[gtk+] x11: Add GdkX11Display:translate-event signal
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] x11: Add GdkX11Display:translate-event signal
- Date: Wed, 13 Dec 2017 00:14:10 +0000 (UTC)
commit 0d1ea056580c41112c17b1dbdd6e3f500fdcf186
Author: Benjamin Otte <otte redhat com>
Date: Wed Dec 13 00:43:30 2017 +0100
x11: Add GdkX11Display:translate-event signal
This is supposed to replace gdk_window_add_filter() in the long run.
gdk/gdkmarshalers.list | 1 +
gdk/x11/gdkdisplay-x11.c | 75 +++++++++++++++++++++++++++++++++++++++++++++-
gdk/x11/gdkdisplay-x11.h | 6 +++-
gdk/x11/gdkeventsource.c | 62 ++++++++++++++++++--------------------
gdk/x11/gdkeventsource.h | 4 ++
5 files changed, 113 insertions(+), 35 deletions(-)
---
diff --git a/gdk/gdkmarshalers.list b/gdk/gdkmarshalers.list
index adc37b9..d70b190 100644
--- a/gdk/gdkmarshalers.list
+++ b/gdk/gdkmarshalers.list
@@ -4,5 +4,6 @@ VOID:POINTER,POINTER,POINTER
OBJECT:VOID
OBJECT:DOUBLE,DOUBLE
BOXED:INT,INT
+BOXED:POINTER
VOID:DOUBLE,DOUBLE,POINTER,POINTER
VOID:POINTER,POINTER,BOOLEAN,BOOLEAN
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index a474443..b8eaff1 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -33,9 +33,9 @@
#include "gdkeventtranslator.h"
#include "gdkframeclockprivate.h"
#include "gdkinternals.h"
-#include "gdkinternals.h"
#include "gdkdeviceprivate.h"
#include "gdkkeysprivate.h"
+#include "gdkmarshalers.h"
#include "xsettings-client.h"
#include "gdkclipboard-x11.h"
#include "gdkprivate-x11.h"
@@ -76,6 +76,11 @@
#include <X11/extensions/Xrandr.h>
#endif
+enum {
+ TRANSLATE_EVENT,
+ LAST_SIGNAL
+};
+
typedef struct _GdkErrorTrap GdkErrorTrap;
struct _GdkErrorTrap
@@ -176,6 +181,8 @@ static const char *const precache_atoms[] = {
static char *gdk_sm_client_id;
+static guint signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE_WITH_CODE (GdkX11Display, gdk_x11_display, GDK_TYPE_DISPLAY,
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
gdk_x11_display_event_translator_init))
@@ -3156,6 +3163,24 @@ gdk_x11_display_get_last_seen_time (GdkDisplay *display)
return gdk_x11_get_server_time (GDK_X11_DISPLAY (display)->leader_gdk_window);
}
+static gboolean
+gdk_x11_display_translate_event_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer dummy)
+{
+ GdkEvent *event;
+
+ event = g_value_get_boxed (handler_return);
+ if (event == NULL)
+ return TRUE;
+
+ if (event->type != GDK_NOTHING)
+ g_value_set_boxed (return_accu, event);
+
+ return FALSE;
+}
+
static void
gdk_x11_display_class_init (GdkX11DisplayClass * class)
{
@@ -3216,5 +3241,53 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
display_class->get_last_seen_time = gdk_x11_display_get_last_seen_time;
display_class->set_cursor_theme = gdk_x11_display_set_cursor_theme;
+ class->translate_event = gdk_event_source_translate_event;
+
+ /**
+ * GdkX11Display::translate-event:
+ * @display: the object on which the signal is emitted
+ * @xevent: a pointer to the XEvent to process
+ *
+ * The ::translate-event signal is a low level signal that is emitted
+ * whenever an XEvent needs to be translated to a #GdkEvent.
+ *
+ * Handlers to this signal can return one of 3 possible values:
+ *
+ * 1. %NULL
+ *
+ * This will result in the next handler being invoked.
+ *
+ * 2. a #GdkEvent
+ *
+ * This will result in no further handlers being invoked and the returned
+ * event being enqueued for further processing by GDK.
+ *
+ * 3. gdk_event_new(GDK_NOTHING)
+ *
+ * If a handler returns an event of type GDK_NOTHING, the event will be
+ * discarded and no further handlers will be invoked. Use this if your
+ * function completely handled the @xevent.
+ *
+ * Note that the default handler for this function is GDK's own event
+ * translation mechanism, so by translating an event that GDK expects to
+ * translate, you may break GDK and/or GTK+ in interesting ways, so you
+ * have to know what you're doing.
+ *
+ * If you are interested in X GenericEvents, bear in mind that
+ * XGetEventData() has been already called on the event, and
+ * XFreeEventData() will be called afterwards.
+ *
+ * Returns: The translated #GdkEvent or %NULL to invoke further handlers to
+ * translate the event.
+ */
+ signals[TRANSLATE_EVENT] =
+ g_signal_new (g_intern_static_string ("translate-event"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdkX11DisplayClass, translate_event),
+ gdk_x11_display_translate_event_accumulator, NULL,
+ _gdk_marshal_BOXED__POINTER,
+ GDK_TYPE_EVENT, 1, G_TYPE_POINTER);
+
_gdk_x11_windowing_init ();
}
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 6da7cf6..555b855 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -26,8 +26,9 @@
#include "gdkkeys.h"
#include "gdkwindow.h"
#include "gdkinternals.h"
-#include "gdkx11screen.h"
#include "gdkx11devicemanager.h"
+#include "gdkx11display.h"
+#include "gdkx11screen.h"
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -166,6 +167,9 @@ struct _GdkX11Display
struct _GdkX11DisplayClass
{
GdkDisplayClass parent_class;
+
+ GdkEvent * (* translate_event) (GdkX11Display *display,
+ const XEvent *event);
};
GdkX11Screen *_gdk_x11_display_screen_for_xrootwin (GdkDisplay *display,
diff --git a/gdk/x11/gdkeventsource.c b/gdk/x11/gdkeventsource.c
index 5de5b7b..ccf4c59 100644
--- a/gdk/x11/gdkeventsource.c
+++ b/gdk/x11/gdkeventsource.c
@@ -263,29 +263,23 @@ handle_touch_synthetic_crossing (GdkEvent *event)
}
}
-static GdkEvent *
-gdk_event_source_translate_event (GdkEventSource *event_source,
- XEvent *xevent)
+GdkEvent *
+gdk_event_source_translate_event (GdkX11Display *x11_display,
+ const XEvent *xevent)
{
+ GdkEventSource *event_source = (GdkEventSource *) x11_display->event_source;
GdkEvent *event = gdk_event_new (GDK_NOTHING);
GdkFilterReturn result = GDK_FILTER_CONTINUE;
+ GdkDisplay *display = GDK_DISPLAY (x11_display);
GdkEventTranslator *event_translator;
GdkWindow *filter_window;
Display *dpy;
GdkX11Screen *x11_screen;
gpointer cache;
- x11_screen = GDK_X11_DISPLAY (event_source->display)->screen;
-
- dpy = GDK_DISPLAY_XDISPLAY (event_source->display);
+ x11_screen = GDK_X11_DISPLAY (display)->screen;
-#ifdef HAVE_XGENERICEVENTS
- /* Get cookie data here so it's available
- * to every event translator and event filter.
- */
- if (xevent->type == GenericEvent)
- XGetEventData (dpy, &xevent->xcookie);
-#endif
+ dpy = GDK_DISPLAY_XDISPLAY (display);
filter_window = gdk_event_source_get_filter_window (event_source, xevent,
&event_translator);
@@ -300,7 +294,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
xevent->xany.window == x11_screen->xsettings_manager_window)
result = gdk_xsettings_manager_window_filter (xevent, event, x11_screen);
- cache = gdk_window_cache_get (event_source->display);
+ cache = gdk_window_cache_get (display);
if (cache)
{
if (result == GDK_FILTER_CONTINUE)
@@ -328,11 +322,6 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
if (result != GDK_FILTER_CONTINUE)
{
-#ifdef HAVE_XGENERICEVENTS
- if (xevent->type == GenericEvent)
- XFreeEventData (dpy, &xevent->xcookie);
-#endif
-
if (result == GDK_FILTER_REMOVE)
{
gdk_event_free (event);
@@ -349,7 +338,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
{
/* Event translator was gotten before in get_filter_window() */
event = _gdk_x11_event_translator_translate (event_translator,
- event_source->display,
+ display,
xevent);
}
else
@@ -362,7 +351,7 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
list = list->next;
event = _gdk_x11_event_translator_translate (translator,
- event_source->display,
+ display,
xevent);
}
}
@@ -386,11 +375,6 @@ gdk_event_source_translate_event (GdkEventSource *event_source,
handle_touch_synthetic_crossing (event);
}
-#ifdef HAVE_XGENERICEVENTS
- if (xevent->type == GenericEvent)
- XFreeEventData (dpy, &xevent->xcookie);
-#endif
-
return event;
}
@@ -449,11 +433,6 @@ _gdk_x11_display_queue_events (GdkDisplay *display)
GdkEvent *event;
XEvent xevent;
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
- GdkEventSource *event_source;
- GdkX11Display *display_x11;
-
- display_x11 = GDK_X11_DISPLAY (display);
- event_source = (GdkEventSource *) display_x11->event_source;
while (!_gdk_event_queue_find_first (display) && XPending (xdisplay))
{
@@ -469,9 +448,26 @@ _gdk_x11_display_queue_events (GdkDisplay *display)
continue;
}
- event = gdk_event_source_translate_event (event_source, &xevent);
+#ifdef HAVE_XGENERICEVENTS
+ /* Get cookie data here so it's available
+ * to every event translator and event filter.
+ */
+ if (xevent.type == GenericEvent)
+ XGetEventData (xdisplay, &xevent.xcookie);
+#endif
+
+ g_signal_emit_by_name (display, "translate-event", &xevent, &event);
- if (event)
+#ifdef HAVE_XGENERICEVENTS
+ if (xevent.type == GenericEvent)
+ XFreeEventData (xdisplay, &xevent.xcookie);
+#endif
+
+ if (event && event->type == GDK_NOTHING)
+ {
+ gdk_event_free (event);
+ }
+ else if (event)
{
GList *node;
diff --git a/gdk/x11/gdkeventsource.h b/gdk/x11/gdkeventsource.h
index 8338fdd..5398f4f 100644
--- a/gdk/x11/gdkeventsource.h
+++ b/gdk/x11/gdkeventsource.h
@@ -19,6 +19,7 @@
#define __GDK_X11_EVENT_SOURCE_H__
#include "gdkeventtranslator.h"
+#include "gdkx11display.h"
G_BEGIN_DECLS
@@ -37,6 +38,9 @@ void gdk_x11_event_source_select_events (GdkEventSource *source,
GdkEventMask event_mask,
unsigned int extra_x_mask);
+GdkEvent *gdk_event_source_translate_event (GdkX11Display *display,
+ const XEvent *xevent);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]