X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fx11%2Fgdkasync.c;h=04f78a95646f587a69cda7a7be594574bd33159c;hb=9d0febc9a64a5bfb0fcfc3a88de4757f6c1ff090;hp=61f25fbdf13429acc0160ee5ca353f51a3566bfb;hpb=3b9a31df075d4a53aaf1d592adc81a0dfc8996f7;p=~andy%2Fgtk diff --git a/gdk/x11/gdkasync.c b/gdk/x11/gdkasync.c index 61f25fbdf..04f78a956 100644 --- a/gdk/x11/gdkasync.c +++ b/gdk/x11/gdkasync.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* Portions of code in this file are based on code from Xlib */ @@ -43,20 +41,24 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ -#include +#include "config.h" + +#include "gdkasync.h" +#include "gdkprivate-x11.h" + #ifdef NEED_XIPROTO_H_FOR_XREPLY #include #endif + #include -#include "gdkalias.h" -#include "gdkasync.h" -#include "gdkx.h" + typedef struct _ChildInfoChildState ChildInfoChildState; 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 +114,28 @@ struct _SetInputFocusState gulong get_input_focus_req; }; +struct _RoundtripState +{ + Display *dpy; + _XAsyncHandler async; + gulong get_input_focus_req; + GdkDisplay *display; + GdkRoundTripCallback callback; + gpointer data; +}; + +static gboolean +callback_idle (gpointer data) +{ + SendEventState *state = (SendEventState *)data; + + state->callback (state->window, !state->have_error, state->data); + + g_free (state); + + return FALSE; +} + static Bool send_event_handler (Display *dpy, xReply *rep, @@ -133,7 +157,7 @@ send_event_handler (Display *dpy, else if (dpy->last_request_read == state->get_input_focus_req) { xGetInputFocusReply replbuf; - xGetInputFocusReply *repl; + xGetInputFocusReply *repl G_GNUC_UNUSED; if (rep->generic.type != X_Error) { @@ -147,7 +171,7 @@ send_event_handler (Display *dpy, } if (state->callback) - state->callback (state->window, !state->have_error, state->data); + gdk_threads_add_idle (callback_idle, state); DeqAsyncHandler(state->dpy, &state->async); @@ -262,99 +286,6 @@ _gdk_x11_send_client_message_async (GdkDisplay *display, SyncHandle(); } -static Bool -set_input_focus_handler (Display *dpy, - xReply *rep, - char *buf, - int len, - XPointer data) -{ - SetInputFocusState *state = (SetInputFocusState *)data; - - if (dpy->last_request_read == state->set_input_focus_req) - { - if (rep->generic.type == X_Error && - rep->error.errorCode == BadMatch) - { - /* Consume BadMatch errors, since we have no control - * over them. - */ - return True; - } - } - - 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); - } - - DeqAsyncHandler(state->dpy, &state->async); - - g_free (state); - - return (rep->generic.type != X_Error); - } - - return False; -} - -void -_gdk_x11_set_input_focus_safe (GdkDisplay *display, - Window window, - int revert_to, - Time time) -{ - Display *dpy; - SetInputFocusState *state; - - dpy = GDK_DISPLAY_XDISPLAY (display); - - state = g_new (SetInputFocusState, 1); - - state->dpy = dpy; - - LockDisplay(dpy); - - state->async.next = dpy->async_handlers; - state->async.handler = set_input_focus_handler; - state->async.data = (XPointer) state; - dpy->async_handlers = &state->async; - - { - xSetInputFocusReq *req; - - GetReq(SetInputFocus, req); - req->focus = window; - req->revertTo = revert_to; - req->time = time; - state->set_input_focus_req = dpy->request; - } - - /* - * XSync (dpy, 0) - */ - { - xReq *req; - - GetEmptyReq(GetInputFocus, req); - state->get_input_focus_req = dpy->request; - } - - UnlockDisplay(dpy); - SyncHandle(); -} - static Bool list_children_handler (Display *dpy, xReply *rep, @@ -624,19 +555,26 @@ _gdk_x11_get_window_child_info (GdkDisplay *display, else wm_state_atom = None; - gdk_error_trap_push (); + state.children = NULL; + state.nchildren = 0; + + gdk_x11_display_error_trap_push (display); result = list_children_and_wm_state (dpy, window, win_has_wm_state ? wm_state_atom : None, &has_wm_state, &state.children, &state.nchildren); - gdk_error_trap_pop (); + gdk_x11_display_error_trap_pop_ignored (display); if (!result) - return FALSE; + { + g_free (state.children); + return FALSE; + } if (has_wm_state) { if (win_has_wm_state) *win_has_wm_state = TRUE; + g_free (state.children); return TRUE; } else @@ -724,3 +662,89 @@ _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->display, state->data, state->get_input_focus_req); + + g_free (state); + + return FALSE; +} + +static Bool +roundtrip_handler (Display *dpy, + xReply *rep, + char *buf, + int len, + XPointer data) +{ + RoundtripState *state = (RoundtripState *)data; + + if (dpy->last_request_read == state->get_input_focus_req) + { + xGetInputFocusReply replbuf; + xGetInputFocusReply *repl G_GNUC_UNUSED; + + 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->display = display; + 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(); +}