aboutsummaryrefslogtreecommitdiff
path: root/src/xembed.cc
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2010-08-20 23:24:19 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2010-08-20 23:24:19 +0200
commitf5c598b518d1f906148534d015f50075d3e8242d (patch)
tree21dd70add5b366c3dd80641b77f6b18e0baa009e /src/xembed.cc
parente98d02a01ffeb18ede86af025e51ae1ec011c75a (diff)
parent5f0fc0e48b8cbee7e1795935da0abff6627fd498 (diff)
merge
Diffstat (limited to 'src/xembed.cc')
-rw-r--r--src/xembed.cc165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/xembed.cc b/src/xembed.cc
new file mode 100644
index 00000000..04a4362a
--- /dev/null
+++ b/src/xembed.cc
@@ -0,0 +1,165 @@
+/*
+ * File: xembed.cc
+ *
+ * Copyright (C) 2009 Jorge Arellano Cid <jcid@dillo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <string.h>
+#include <ctype.h>
+
+#include <fltk/Window.h>
+#include <fltk/run.h>
+#include <fltk/events.h>
+#include <fltk/x.h>
+
+#include "xembed.hh"
+
+#if USE_X11
+
+typedef enum {
+ XEMBED_EMBEDDED_NOTIFY = 0,
+ XEMBED_WINDOW_ACTIVATE = 1,
+ XEMBED_WINDOW_DEACTIVATE = 2,
+ XEMBED_REQUEST_FOCUS = 3,
+ XEMBED_FOCUS_IN = 4,
+ XEMBED_FOCUS_OUT = 5,
+ XEMBED_FOCUS_NEXT = 6,
+ XEMBED_FOCUS_PREV = 7,
+ XEMBED_GRAB_KEY = 8,
+ XEMBED_UNGRAB_KEY = 9,
+ XEMBED_MODALITY_ON = 10,
+ XEMBED_MODALITY_OFF = 11,
+} XEmbedMessageType;
+
+void
+Xembed::setXembedInfo(unsigned long flags)
+{
+ unsigned long buffer[2];
+
+ Atom xembed_info_atom = XInternAtom (fltk::xdisplay, "_XEMBED_INFO", false);
+
+ buffer[0] = 1;
+ buffer[1] = flags;
+
+ XChangeProperty (fltk::xdisplay,
+ xid,
+ xembed_info_atom, xembed_info_atom, 32,
+ PropModeReplace,
+ (unsigned char *)buffer, 2);
+}
+
+void
+Xembed::sendXembedEvent(uint32_t message) {
+ XClientMessageEvent xclient;
+
+ memset (&xclient, 0, sizeof (xclient));
+ xclient.window = xid;
+ xclient.type = ClientMessage;
+ xclient.message_type = XInternAtom (fltk::xdisplay, "_XEMBED", false);
+ xclient.format = 32;
+ xclient.data.l[0] = fltk::event_time;
+ xclient.data.l[1] = message;
+
+ XSendEvent(fltk::xdisplay, xid, False, NoEventMask, (XEvent *)&xclient);
+ XSync(fltk::xdisplay, False);
+}
+
+int
+Xembed::handle(int e) {
+ if (e == fltk::PUSH)
+ sendXembedEvent(XEMBED_REQUEST_FOCUS);
+
+ return Window::handle(e);
+}
+
+static int event_handler(int e, fltk::Window *w) {
+ Atom xembed_atom = XInternAtom (fltk::xdisplay, "_XEMBED", false);
+
+ if (fltk::xevent.type == ClientMessage) {
+ if (fltk::xevent.xclient.message_type == xembed_atom) {
+ long message = fltk::xevent.xclient.data.l[1];
+
+ switch (message) {
+ case XEMBED_WINDOW_ACTIVATE:
+ // Force a ConfigureNotify message so fltk can get the new
+ // coordinates after a move of the embedder window.
+ w->resize(0, 0, w->w(), w->h());
+ break;
+ case XEMBED_WINDOW_DEACTIVATE:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+// TODO: Implement more XEMBED support;
+
+void Xembed::create() {
+ createInternal(xid);
+ setXembedInfo(1);
+ fltk::add_event_handler(event_handler);
+}
+
+void Xembed::createInternal(uint32_t parent) {
+ fltk::Window *window = this;
+ Colormap colormap = fltk::xcolormap;
+
+ XSetWindowAttributes attr;
+ attr.border_pixel = 0;
+ attr.colormap = colormap;
+ attr.bit_gravity = 0; // StaticGravity;
+ int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity;
+
+ int W = window->w();
+ if (W <= 0) W = 1; // X don't like zero...
+ int H = window->h();
+ if (H <= 0) H = 1; // X don't like zero...
+ int X = window->x();
+ int Y = window->y();
+
+ attr.event_mask =
+ ExposureMask | StructureNotifyMask
+ | KeyPressMask | KeyReleaseMask | KeymapStateMask | FocusChangeMask
+ | ButtonPressMask | ButtonReleaseMask
+ | EnterWindowMask | LeaveWindowMask
+ | PointerMotionMask;
+
+ fltk::CreatedWindow::set_xid(window,
+ XCreateWindow(fltk::xdisplay,
+ parent,
+ X, Y, W, H,
+ 0, // borderwidth
+ fltk::xvisual->depth,
+ InputOutput,
+ fltk::xvisual->visual,
+ mask, &attr));
+}
+
+#else // USE_X11
+
+void
+Xembed::setXembedInfo(unsigned long flags) {};
+
+void
+Xembed::sendXembedEvent(uint32_t message) {};
+
+int
+Xembed::handle(int e) {
+ return Window::handle(e);
+}
+
+void
+Xembed::create() {
+ Window::create();
+}
+
+#endif