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:
parent
2f0181ac44
commit
777f145128
@ -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 *) ¬ify_event);
|
(XEvent *) ¬ify_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 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user