From d2c1c0a8db6fd01bda11e6592a41ea2dfe1b4396 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 26 Jan 2009 19:55:08 +0100 Subject: [PATCH] Add _gdk_x11_roundtrip_async --- gdk/x11/gdkasync.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ gdk/x11/gdkasync.h | 6 +++ 2 files changed, 101 insertions(+) diff --git a/gdk/x11/gdkasync.c b/gdk/x11/gdkasync.c index 3f90d59441..585c9ef2b9 100644 --- a/gdk/x11/gdkasync.c +++ b/gdk/x11/gdkasync.c @@ -57,6 +57,7 @@ typedef struct _ChildInfoState ChildInfoState; typedef struct _ListChildrenState ListChildrenState; typedef struct _SendEventState SendEventState; typedef struct _SetInputFocusState SetInputFocusState; +typedef struct _RoundtripState RoundtripState; typedef enum { CHILD_INFO_GET_PROPERTY, @@ -112,6 +113,15 @@ struct _SetInputFocusState gulong get_input_focus_req; }; +struct _RoundtripState +{ + Display *dpy; + _XAsyncHandler async; + gulong get_input_focus_req; + GdkRoundTripCallback callback; + gpointer data; +}; + static gboolean callback_idle (gpointer data) { @@ -743,5 +753,90 @@ _gdk_x11_get_window_child_info (GdkDisplay *display, return !state.have_error; } +static gboolean +roundtrip_callback_idle (gpointer data) +{ + RoundtripState *state = (RoundtripState *)data; + + state->callback (state->data); + + g_free (state); + + return FALSE; +} + +static Bool +roundtrip_handler (Display *dpy, + xReply *rep, + char *buf, + int len, + XPointer data) +{ + RoundtripState *state = (SendEventState *)data; + + if (dpy->last_request_read == state->get_input_focus_req) + { + xGetInputFocusReply replbuf; + xGetInputFocusReply *repl; + + if (rep->generic.type != X_Error) + { + /* Actually does nothing, since there are no additional bytes + * to read, but maintain good form. + */ + repl = (xGetInputFocusReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2, + True); + } + + if (state->callback) + gdk_threads_add_idle (roundtrip_callback_idle, state); + + DeqAsyncHandler(state->dpy, &state->async); + + return (rep->generic.type != X_Error); + } + + return False; +} + +void +_gdk_x11_roundtrip_async (GdkDisplay *display, + GdkRoundTripCallback callback, + gpointer data) +{ + Display *dpy; + RoundtripState *state; + + dpy = GDK_DISPLAY_XDISPLAY (display); + + state = g_new (RoundtripState, 1); + + state->dpy = dpy; + state->callback = callback; + state->data = data; + + LockDisplay(dpy); + + state->async.next = dpy->async_handlers; + state->async.handler = roundtrip_handler; + state->async.data = (XPointer) state; + dpy->async_handlers = &state->async; + + /* + * XSync (dpy, 0) + */ + { + xReq *req; + + GetEmptyReq(GetInputFocus, req); + state->get_input_focus_req = dpy->request; + } + + UnlockDisplay(dpy); + SyncHandle(); +} + #define __GDK_ASYNC_C__ #include "gdkaliasdef.c" diff --git a/gdk/x11/gdkasync.h b/gdk/x11/gdkasync.h index 91897f380f..407e3c8473 100644 --- a/gdk/x11/gdkasync.h +++ b/gdk/x11/gdkasync.h @@ -31,6 +31,8 @@ typedef struct _GdkChildInfoX11 GdkChildInfoX11; typedef void (*GdkSendXEventCallback) (Window window, gboolean success, gpointer data); +typedef void (*GdkRoundTripCallback) (gpointer data); + struct _GdkChildInfoX11 { @@ -63,6 +65,10 @@ gboolean _gdk_x11_get_window_child_info (GdkDisplay *display, GdkChildInfoX11 **children, guint *nchildren); +void _gdk_x11_roundtrip_async (GdkDisplay *display, + GdkRoundTripCallback callback, + gpointer data); + G_END_DECLS #endif /* __GDK_ASYNC_H__ */