#include #include "gdkasync.h" #include "gdkx.h" #include "string.h" typedef struct _SetInputFocusState SetInputFocusState; struct _SetInputFocusState { Display *dpy; Window window; _XAsyncHandler async; gulong set_input_focus_req; gulong get_input_focus_req; gboolean have_error; GdkSendXEventCallback callback; gpointer data; }; 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; state->window = window; 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(); }