mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 17:40:40 -05:00
Merge from stable: add XEMBED support
Add the XEMBED protocol support in the GLX backend, for embedding the stage window into another X window. This allows cross-toolkit inclusion and makes clutter-gtk possible.
This commit is contained in:
parent
fdb1a82569
commit
8b7504dea2
@ -37,11 +37,11 @@ G_BEGIN_DECLS
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* Map to xlibs masks */
|
/* Map to xlibs masks */
|
||||||
CLUTTER_BUTTON1_MASK = (1<<8),
|
CLUTTER_BUTTON1_MASK = (1 << 8),
|
||||||
CLUTTER_BUTTON2_MASK = (1<<9),
|
CLUTTER_BUTTON2_MASK = (1 << 9),
|
||||||
CLUTTER_BUTTON3_MASK = (1<<10),
|
CLUTTER_BUTTON3_MASK = (1 << 10),
|
||||||
CLUTTER_BUTTON4_MASK = (1<<11),
|
CLUTTER_BUTTON4_MASK = (1 << 11),
|
||||||
CLUTTER_BUTTON5_MASK = (1<<12)
|
CLUTTER_BUTTON5_MASK = (1 << 12)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -57,7 +57,8 @@ typedef enum
|
|||||||
CLUTTER_BUTTON_RELEASE,
|
CLUTTER_BUTTON_RELEASE,
|
||||||
CLUTTER_SCROLL,
|
CLUTTER_SCROLL,
|
||||||
CLUTTER_STAGE_STATE,
|
CLUTTER_STAGE_STATE,
|
||||||
CLUTTER_DESTROY_NOTIFY
|
CLUTTER_DESTROY_NOTIFY,
|
||||||
|
CLUTTER_CLIENT_MESSAGE
|
||||||
} ClutterEventType;
|
} ClutterEventType;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -41,6 +41,28 @@
|
|||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
|
/* XEMBED protocol support for toolkit embedding */
|
||||||
|
#define XEMBED_MAPPED (1 << 0)
|
||||||
|
#define MAX_SUPPORTED_XEMBED_VERSION 1
|
||||||
|
|
||||||
|
#define XEMBED_EMBEDDED_NOTIFY 0
|
||||||
|
#define XEMBED_WINDOW_ACTIVATE 1
|
||||||
|
#define XEMBED_WINDOW_DEACTIVATE 2
|
||||||
|
#define XEMBED_REQUEST_FOCUS 3
|
||||||
|
#define XEMBED_FOCUS_IN 4
|
||||||
|
#define XEMBED_FOCUS_OUT 5
|
||||||
|
#define XEMBED_FOCUS_NEXT 6
|
||||||
|
#define XEMBED_FOCUS_PREV 7
|
||||||
|
/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
|
||||||
|
#define XEMBED_MODALITY_ON 10
|
||||||
|
#define XEMBED_MODALITY_OFF 11
|
||||||
|
#define XEMBED_REGISTER_ACCELERATOR 12
|
||||||
|
#define XEMBED_UNREGISTER_ACCELERATOR 13
|
||||||
|
#define XEMBED_ACTIVATE_ACCELERATOR 14
|
||||||
|
|
||||||
|
static Atom Atom_XEMBED = 0;
|
||||||
|
static Window ParentEmbedderWin = None;
|
||||||
|
|
||||||
typedef struct _ClutterEventSource ClutterEventSource;
|
typedef struct _ClutterEventSource ClutterEventSource;
|
||||||
|
|
||||||
struct _ClutterEventSource
|
struct _ClutterEventSource
|
||||||
@ -84,6 +106,59 @@ clutter_check_xpending (ClutterBackend *backend)
|
|||||||
return XPending (CLUTTER_BACKEND_GLX (backend)->xdpy);
|
return XPending (CLUTTER_BACKEND_GLX (backend)->xdpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
xembed_send_message (Display *xdisplay,
|
||||||
|
Window window,
|
||||||
|
long message,
|
||||||
|
long detail,
|
||||||
|
long data1,
|
||||||
|
long data2)
|
||||||
|
{
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
memset (&ev, 0, sizeof (ev));
|
||||||
|
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = window;
|
||||||
|
ev.xclient.message_type = Atom_XEMBED;
|
||||||
|
ev.xclient.format = 32;
|
||||||
|
ev.xclient.data.l[0] = CurrentTime;
|
||||||
|
ev.xclient.data.l[1] = message;
|
||||||
|
ev.xclient.data.l[2] = detail;
|
||||||
|
ev.xclient.data.l[3] = data1;
|
||||||
|
ev.xclient.data.l[4] = data2;
|
||||||
|
|
||||||
|
clutter_glx_trap_x_errors ();
|
||||||
|
|
||||||
|
XSendEvent (xdisplay, window, False, NoEventMask, &ev);
|
||||||
|
XSync (xdisplay, False);
|
||||||
|
|
||||||
|
if (clutter_glx_untrap_x_errors ())
|
||||||
|
return False;
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xembed_set_info (Display *xdisplay,
|
||||||
|
Window window,
|
||||||
|
gint flags)
|
||||||
|
{
|
||||||
|
gint32 list[2];
|
||||||
|
Atom atom_XEMBED_INFO;
|
||||||
|
|
||||||
|
atom_XEMBED_INFO = XInternAtom (xdisplay, "_XEMBED_INFO", False);
|
||||||
|
|
||||||
|
list[0] = MAX_SUPPORTED_XEMBED_VERSION;
|
||||||
|
list[1] = XEMBED_MAPPED;
|
||||||
|
|
||||||
|
clutter_glx_trap_x_errors ();
|
||||||
|
XChangeProperty (xdisplay, window,
|
||||||
|
atom_XEMBED_INFO,
|
||||||
|
atom_XEMBED_INFO, 32,
|
||||||
|
PropModeReplace, (unsigned char *) list, 2);
|
||||||
|
clutter_glx_untrap_x_errors ();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_events_init (ClutterBackend *backend)
|
_clutter_events_init (ClutterBackend *backend)
|
||||||
@ -96,6 +171,8 @@ _clutter_events_init (ClutterBackend *backend)
|
|||||||
connection_number = ConnectionNumber (backend_glx->xdpy);
|
connection_number = ConnectionNumber (backend_glx->xdpy);
|
||||||
CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);
|
CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);
|
||||||
|
|
||||||
|
Atom_XEMBED = XInternAtom (backend_glx->xdpy, "_XEMBED", False);
|
||||||
|
|
||||||
source = backend_glx->event_source = clutter_event_source_new (backend);
|
source = backend_glx->event_source = clutter_event_source_new (backend);
|
||||||
event_source = (ClutterEventSource *) source;
|
event_source = (ClutterEventSource *) source;
|
||||||
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
|
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
|
||||||
@ -108,6 +185,10 @@ _clutter_events_init (ClutterBackend *backend)
|
|||||||
g_source_add_poll (source, &event_source->event_poll_fd);
|
g_source_add_poll (source, &event_source->event_poll_fd);
|
||||||
g_source_set_can_recurse (source, TRUE);
|
g_source_set_can_recurse (source, TRUE);
|
||||||
g_source_attach (source, NULL);
|
g_source_attach (source, NULL);
|
||||||
|
|
||||||
|
xembed_set_info (backend_glx->xdpy,
|
||||||
|
clutter_glx_get_stage_window (CLUTTER_STAGE (backend_glx->stage)),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -128,6 +209,7 @@ _clutter_events_uninit (ClutterBackend *backend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_user_time (Display *display,
|
set_user_time (Display *display,
|
||||||
Window *xwindow,
|
Window *xwindow,
|
||||||
@ -200,6 +282,48 @@ translate_key_event (ClutterBackend *backend,
|
|||||||
0); /* FIXME: index with modifiers */
|
0); /* FIXME: index with modifiers */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_xembed_event (ClutterBackendGlx *backend_glx,
|
||||||
|
XEvent *xevent)
|
||||||
|
{
|
||||||
|
ClutterActor *stage;
|
||||||
|
|
||||||
|
stage = _clutter_backend_get_stage (CLUTTER_BACKEND (backend_glx));
|
||||||
|
|
||||||
|
switch (xevent->xclient.data.l[1])
|
||||||
|
{
|
||||||
|
case XEMBED_EMBEDDED_NOTIFY:
|
||||||
|
CLUTTER_NOTE (EVENT, "got XEMBED_EMBEDDED_NOTIFY from %lx",
|
||||||
|
xevent->xclient.data.l[3]);
|
||||||
|
|
||||||
|
ParentEmbedderWin = xevent->xclient.data.l[3];
|
||||||
|
|
||||||
|
clutter_actor_realize (stage);
|
||||||
|
clutter_actor_show (stage);
|
||||||
|
|
||||||
|
xembed_set_info (backend_glx->xdpy,
|
||||||
|
clutter_glx_get_stage_window (CLUTTER_STAGE (stage)),
|
||||||
|
XEMBED_MAPPED);
|
||||||
|
break;
|
||||||
|
case XEMBED_WINDOW_ACTIVATE:
|
||||||
|
CLUTTER_NOTE (EVENT, "got XEMBED_WINDOW_ACTIVATE");
|
||||||
|
break;
|
||||||
|
case XEMBED_WINDOW_DEACTIVATE:
|
||||||
|
CLUTTER_NOTE (EVENT, "got XEMBED_WINDOW_DEACTIVATE");
|
||||||
|
break;
|
||||||
|
case XEMBED_FOCUS_IN:
|
||||||
|
CLUTTER_NOTE (EVENT, "got XEMBED_FOCUS_IN");
|
||||||
|
if (ParentEmbedderWin)
|
||||||
|
xembed_send_message (backend_glx->xdpy, ParentEmbedderWin,
|
||||||
|
XEMBED_FOCUS_NEXT,
|
||||||
|
0, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CLUTTER_NOTE (EVENT, "got unknown XEMBED message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
clutter_event_translate (ClutterBackend *backend,
|
clutter_event_translate (ClutterBackend *backend,
|
||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
@ -316,6 +440,12 @@ clutter_event_translate (ClutterBackend *backend,
|
|||||||
xevent->xdestroywindow.window);
|
xevent->xdestroywindow.window);
|
||||||
event->type = event->any.type = CLUTTER_DESTROY_NOTIFY;
|
event->type = event->any.type = CLUTTER_DESTROY_NOTIFY;
|
||||||
break;
|
break;
|
||||||
|
case ClientMessage:
|
||||||
|
CLUTTER_NOTE (EVENT, "client message");
|
||||||
|
if (xevent->xclient.message_type == Atom_XEMBED)
|
||||||
|
handle_xembed_event (backend_glx, xevent);
|
||||||
|
event->type = event->any.type = CLUTTER_CLIENT_MESSAGE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* ignore every other event */
|
/* ignore every other event */
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -85,6 +85,7 @@ Windowing events handled by Clutter.
|
|||||||
@CLUTTER_SCROLL:
|
@CLUTTER_SCROLL:
|
||||||
@CLUTTER_STAGE_STATE:
|
@CLUTTER_STAGE_STATE:
|
||||||
@CLUTTER_DESTROY_NOTIFY:
|
@CLUTTER_DESTROY_NOTIFY:
|
||||||
|
@CLUTTER_CLIENT_MESSAGE:
|
||||||
|
|
||||||
<!-- ##### UNION ClutterEvent ##### -->
|
<!-- ##### UNION ClutterEvent ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
Loading…
Reference in New Issue
Block a user