/* * File: xembed.cc * * Copyright (C) 2009 Jorge Arellano Cid * * 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 #include #include #include #include #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 == FL_PUSH) sendXembedEvent(XEMBED_REQUEST_FOCUS); return Fl_Window::handle(e); } static int event_handler(int e, Fl_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) { Fl_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 Fl_Window::handle(e); } void Xembed::create() { #if 0 PORT1.3 Fl_Window::create(); #endif } #endif