st-clipboard: Use GDK for the event filters instead of Clutter

Instead of using Clutter to add an event filter for X events it now
uses the GDK API. The Clutter API won't work if Clutter is not using
an X11-based backend such as if Mutter is directly running with the
KMS backend. This is a step towards making Mutter be its own display
server and a step towards being a Wayland compositor. In this case GDK
will still be using the X backend because it will connect to the
headless X server.

https://bugzilla.gnome.org/show_bug.cgi?id=693438
This commit is contained in:
Neil Roberts 2012-07-18 16:55:24 +01:00
parent 2f0181ac44
commit 777f145128

View File

@ -30,7 +30,8 @@
#include "st-clipboard.h" #include "st-clipboard.h"
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <clutter/x11/clutter-x11.h> #include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <string.h> #include <string.h>
G_DEFINE_TYPE (StClipboard, st_clipboard, G_TYPE_OBJECT) G_DEFINE_TYPE (StClipboard, st_clipboard, G_TYPE_OBJECT)
@ -107,20 +108,23 @@ st_clipboard_finalize (GObject *object)
G_OBJECT_CLASS (st_clipboard_parent_class)->finalize (object); G_OBJECT_CLASS (st_clipboard_parent_class)->finalize (object);
} }
static ClutterX11FilterReturn static GdkFilterReturn
st_clipboard_provider (XEvent *xev, st_clipboard_provider (GdkXEvent *xevent_p,
ClutterEvent *cev, GdkEvent *gev,
StClipboard *clipboard) void *user_data)
{ {
StClipboard *clipboard = user_data;
XEvent *xev = (XEvent *) xevent_p;
XSelectionEvent notify_event; XSelectionEvent notify_event;
XSelectionRequestEvent *req_event; XSelectionRequestEvent *req_event;
GdkDisplay *display = gdk_display_get_default ();
if (xev->type != SelectionRequest) if (xev->type != SelectionRequest)
return CLUTTER_X11_FILTER_CONTINUE; return GDK_FILTER_CONTINUE;
req_event = &xev->xselectionrequest; req_event = &xev->xselectionrequest;
clutter_x11_trap_x_errors (); gdk_x11_display_error_trap_push (display);
if (req_event->target == __atom_targets) if (req_event->target == __atom_targets)
{ {
@ -161,11 +165,14 @@ st_clipboard_provider (XEvent *xev,
XSendEvent (req_event->display, req_event->requestor, False, 0, XSendEvent (req_event->display, req_event->requestor, False, 0,
(XEvent *) &notify_event); (XEvent *) &notify_event);
/* Make it happen non async */ /* Make it happen non async */
XSync (clutter_x11_get_default_display(), FALSE); XSync (GDK_DISPLAY_XDISPLAY (display), FALSE);
clutter_x11_untrap_x_errors (); /* FIXME: Warn here on fail ? */ if (gdk_x11_display_error_trap_pop (display))
{
/* FIXME: Warn here on fail ? */
}
return CLUTTER_X11_FILTER_REMOVE; return GDK_FILTER_REMOVE;
} }
@ -185,17 +192,19 @@ st_clipboard_class_init (StClipboardClass *klass)
static void static void
st_clipboard_init (StClipboard *self) st_clipboard_init (StClipboard *self)
{ {
GdkDisplay *gdk_display;
Display *dpy; Display *dpy;
StClipboardPrivate *priv; StClipboardPrivate *priv;
priv = self->priv = CLIPBOARD_PRIVATE (self); priv = self->priv = CLIPBOARD_PRIVATE (self);
priv->clipboard_window = gdk_display = gdk_display_get_default ();
XCreateSimpleWindow (clutter_x11_get_default_display (), dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
clutter_x11_get_root_window (),
-1, -1, 1, 1, 0, 0, 0);
dpy = clutter_x11_get_default_display (); priv->clipboard_window =
XCreateSimpleWindow (dpy,
gdk_x11_get_default_root_xwindow (),
-1, -1, 1, 1, 0, 0, 0);
/* Only create once */ /* Only create once */
if (__atom_primary == None) if (__atom_primary == None)
@ -216,22 +225,26 @@ st_clipboard_init (StClipboard *self)
priv->supported_targets[0] = __utf8_string; priv->supported_targets[0] = __utf8_string;
priv->supported_targets[1] = __atom_targets; priv->supported_targets[1] = __atom_targets;
clutter_x11_add_filter ((ClutterX11FilterFunc) st_clipboard_provider, gdk_window_add_filter (NULL, /* all windows */
self); st_clipboard_provider,
self);
} }
static ClutterX11FilterReturn static GdkFilterReturn
st_clipboard_x11_event_filter (XEvent *xev, st_clipboard_x11_event_filter (GdkXEvent *xevent_p,
ClutterEvent *cev, GdkEvent *gev,
EventFilterData *filter_data) void *user_data)
{ {
XEvent *xev = (XEvent *) xevent_p;
EventFilterData *filter_data = user_data;
Atom actual_type; Atom actual_type;
int actual_format, result; int actual_format, result;
unsigned long nitems, bytes_after; unsigned long nitems, bytes_after;
unsigned char *data = NULL; unsigned char *data = NULL;
GdkDisplay *display = gdk_display_get_default ();
if(xev->type != SelectionNotify) if(xev->type != SelectionNotify)
return CLUTTER_X11_FILTER_CONTINUE; return GDK_FILTER_CONTINUE;
if (xev->xselection.property == None) if (xev->xselection.property == None)
{ {
@ -240,13 +253,14 @@ st_clipboard_x11_event_filter (XEvent *xev,
NULL, NULL,
filter_data->user_data); filter_data->user_data);
clutter_x11_remove_filter ((ClutterX11FilterFunc) st_clipboard_x11_event_filter, gdk_window_remove_filter (NULL,
filter_data); st_clipboard_x11_event_filter,
filter_data);
g_free (filter_data); g_free (filter_data);
return CLUTTER_X11_FILTER_REMOVE; return GDK_FILTER_REMOVE;
} }
clutter_x11_trap_x_errors (); gdk_x11_display_error_trap_push (display);
result = XGetWindowProperty (xev->xselection.display, result = XGetWindowProperty (xev->xselection.display,
xev->xselection.requestor, xev->xselection.requestor,
@ -260,7 +274,7 @@ st_clipboard_x11_event_filter (XEvent *xev,
&bytes_after, &bytes_after,
&data); &data);
if (clutter_x11_untrap_x_errors () || result != Success) if (gdk_x11_display_error_trap_pop (display) || result != Success)
{ {
/* FIXME: handle failure better */ /* FIXME: handle failure better */
g_warning ("Clipboard: prop retrival failed"); g_warning ("Clipboard: prop retrival failed");
@ -269,16 +283,16 @@ st_clipboard_x11_event_filter (XEvent *xev,
filter_data->callback (filter_data->clipboard, (char*) data, filter_data->callback (filter_data->clipboard, (char*) data,
filter_data->user_data); filter_data->user_data);
clutter_x11_remove_filter gdk_window_remove_filter (NULL,
((ClutterX11FilterFunc) st_clipboard_x11_event_filter, st_clipboard_x11_event_filter,
filter_data); filter_data);
g_free (filter_data); g_free (filter_data);
if (data) if (data)
XFree (data); XFree (data);
return CLUTTER_X11_FILTER_REMOVE; return GDK_FILTER_REMOVE;
} }
/** /**
@ -326,7 +340,7 @@ st_clipboard_get_text (StClipboard *clipboard,
gpointer user_data) gpointer user_data)
{ {
EventFilterData *data; EventFilterData *data;
GdkDisplay *gdk_display;
Display *dpy; Display *dpy;
g_return_if_fail (ST_IS_CLIPBOARD (clipboard)); g_return_if_fail (ST_IS_CLIPBOARD (clipboard));
@ -337,12 +351,14 @@ st_clipboard_get_text (StClipboard *clipboard,
data->callback = callback; data->callback = callback;
data->user_data = user_data; data->user_data = user_data;
clutter_x11_add_filter ((ClutterX11FilterFunc) st_clipboard_x11_event_filter, gdk_window_add_filter (NULL, /* all windows */
data); st_clipboard_x11_event_filter,
data);
dpy = clutter_x11_get_default_display (); gdk_display = gdk_display_get_default ();
dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
clutter_x11_trap_x_errors (); /* safety on */ gdk_x11_display_error_trap_push (gdk_display);
XConvertSelection (dpy, XConvertSelection (dpy,
atom_for_clipboard_type (type), atom_for_clipboard_type (type),
@ -350,7 +366,10 @@ st_clipboard_get_text (StClipboard *clipboard,
clipboard->priv->clipboard_window, clipboard->priv->clipboard_window,
CurrentTime); CurrentTime);
clutter_x11_untrap_x_errors (); if (gdk_x11_display_error_trap_pop (gdk_display))
{
/* FIXME */
}
} }
/** /**
@ -367,6 +386,7 @@ st_clipboard_set_text (StClipboard *clipboard,
const gchar *text) const gchar *text)
{ {
StClipboardPrivate *priv; StClipboardPrivate *priv;
GdkDisplay *gdk_display;
Display *dpy; Display *dpy;
g_return_if_fail (ST_IS_CLIPBOARD (clipboard)); g_return_if_fail (ST_IS_CLIPBOARD (clipboard));
@ -379,13 +399,17 @@ st_clipboard_set_text (StClipboard *clipboard,
priv->clipboard_text = g_strdup (text); priv->clipboard_text = g_strdup (text);
/* tell X we own the clipboard selection */ /* tell X we own the clipboard selection */
dpy = clutter_x11_get_default_display (); gdk_display = gdk_display_get_default ();
dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
clutter_x11_trap_x_errors (); gdk_x11_display_error_trap_push (gdk_display);
XSetSelectionOwner (dpy, atom_for_clipboard_type (type), priv->clipboard_window, CurrentTime); XSetSelectionOwner (dpy, atom_for_clipboard_type (type), priv->clipboard_window, CurrentTime);
XSync (dpy, FALSE); XSync (dpy, FALSE);
clutter_x11_untrap_x_errors (); if (gdk_x11_display_error_trap_pop (gdk_display))
{
/* FIXME */
}
} }