mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
Localize stripped down gtk2
This is intended mainly for GNU/Linux distros who will remove GTK2 support in the near future.
This commit is contained in:
parent
2a928dae19
commit
ad51c7c2ba
1528 changed files with 915658 additions and 57 deletions
845
libs/tk/ydk/x11/gdkasync.c
Normal file
845
libs/tk/ydk/x11/gdkasync.c
Normal file
|
|
@ -0,0 +1,845 @@
|
|||
/* GTK - The GIMP Toolkit
|
||||
* gdkasync.c: Utility functions using the Xlib asynchronous interfaces
|
||||
* Copyright (C) 2003, Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* 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.
|
||||
*/
|
||||
/* Portions of code in this file are based on code from Xlib
|
||||
*/
|
||||
/*
|
||||
Copyright 1986, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
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 "config.h"
|
||||
#ifdef NEED_XIPROTO_H_FOR_XREPLY
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#endif
|
||||
#include <X11/Xlibint.h>
|
||||
#include "gdkasync.h"
|
||||
#include "gdkx.h"
|
||||
#include "gdkalias.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,
|
||||
CHILD_INFO_GET_WA,
|
||||
CHILD_INFO_GET_GEOMETRY
|
||||
} ChildInfoReq;
|
||||
|
||||
struct _ChildInfoChildState
|
||||
{
|
||||
gulong seq[3];
|
||||
};
|
||||
|
||||
struct _ChildInfoState
|
||||
{
|
||||
gboolean get_wm_state;
|
||||
Window *children;
|
||||
guint nchildren;
|
||||
GdkChildInfoX11 *child_info;
|
||||
ChildInfoChildState *child_states;
|
||||
|
||||
guint current_child;
|
||||
guint n_children_found;
|
||||
gint current_request;
|
||||
gboolean have_error;
|
||||
gboolean child_has_error;
|
||||
};
|
||||
|
||||
struct _ListChildrenState
|
||||
{
|
||||
Display *dpy;
|
||||
gulong get_property_req;
|
||||
gboolean have_error;
|
||||
gboolean has_wm_state;
|
||||
};
|
||||
|
||||
struct _SendEventState
|
||||
{
|
||||
Display *dpy;
|
||||
Window window;
|
||||
_XAsyncHandler async;
|
||||
gulong send_event_req;
|
||||
gulong get_input_focus_req;
|
||||
gboolean have_error;
|
||||
GdkSendXEventCallback callback;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
struct _SetInputFocusState
|
||||
{
|
||||
Display *dpy;
|
||||
_XAsyncHandler async;
|
||||
gulong set_input_focus_req;
|
||||
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,
|
||||
char *buf,
|
||||
int len,
|
||||
XPointer data)
|
||||
{
|
||||
SendEventState *state = (SendEventState *)data;
|
||||
|
||||
if (dpy->last_request_read == state->send_event_req)
|
||||
{
|
||||
if (rep->generic.type == X_Error &&
|
||||
rep->error.errorCode == BadWindow)
|
||||
{
|
||||
state->have_error = TRUE;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
else 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 (callback_idle, state);
|
||||
|
||||
DeqAsyncHandler(state->dpy, &state->async);
|
||||
|
||||
return (rep->generic.type != X_Error);
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
client_message_to_wire (XClientMessageEvent *ev,
|
||||
xEvent *event)
|
||||
{
|
||||
int i;
|
||||
event->u.clientMessage.window = ev->window;
|
||||
event->u.u.type = ev->type;
|
||||
event->u.u.detail = ev->format;
|
||||
switch (ev->format)
|
||||
{
|
||||
case 8:
|
||||
event->u.clientMessage.u.b.type = ev->message_type;
|
||||
for (i = 0; i < 20; i++)
|
||||
event->u.clientMessage.u.b.bytes[i] = ev->data.b[i];
|
||||
break;
|
||||
case 16:
|
||||
event->u.clientMessage.u.s.type = ev->message_type;
|
||||
event->u.clientMessage.u.s.shorts0 = ev->data.s[0];
|
||||
event->u.clientMessage.u.s.shorts1 = ev->data.s[1];
|
||||
event->u.clientMessage.u.s.shorts2 = ev->data.s[2];
|
||||
event->u.clientMessage.u.s.shorts3 = ev->data.s[3];
|
||||
event->u.clientMessage.u.s.shorts4 = ev->data.s[4];
|
||||
event->u.clientMessage.u.s.shorts5 = ev->data.s[5];
|
||||
event->u.clientMessage.u.s.shorts6 = ev->data.s[6];
|
||||
event->u.clientMessage.u.s.shorts7 = ev->data.s[7];
|
||||
event->u.clientMessage.u.s.shorts8 = ev->data.s[8];
|
||||
event->u.clientMessage.u.s.shorts9 = ev->data.s[9];
|
||||
break;
|
||||
case 32:
|
||||
event->u.clientMessage.u.l.type = ev->message_type;
|
||||
event->u.clientMessage.u.l.longs0 = ev->data.l[0];
|
||||
event->u.clientMessage.u.l.longs1 = ev->data.l[1];
|
||||
event->u.clientMessage.u.l.longs2 = ev->data.l[2];
|
||||
event->u.clientMessage.u.l.longs3 = ev->data.l[3];
|
||||
event->u.clientMessage.u.l.longs4 = ev->data.l[4];
|
||||
break;
|
||||
default:
|
||||
/* client passing bogus data, let server complain */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_x11_send_client_message_async (GdkDisplay *display,
|
||||
Window window,
|
||||
gboolean propagate,
|
||||
glong event_mask,
|
||||
XClientMessageEvent *event_send,
|
||||
GdkSendXEventCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
Display *dpy;
|
||||
SendEventState *state;
|
||||
|
||||
dpy = GDK_DISPLAY_XDISPLAY (display);
|
||||
|
||||
state = g_new (SendEventState, 1);
|
||||
|
||||
state->dpy = dpy;
|
||||
state->window = window;
|
||||
state->callback = callback;
|
||||
state->data = data;
|
||||
state->have_error = FALSE;
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
state->async.next = dpy->async_handlers;
|
||||
state->async.handler = send_event_handler;
|
||||
state->async.data = (XPointer) state;
|
||||
dpy->async_handlers = &state->async;
|
||||
|
||||
{
|
||||
register xSendEventReq *req;
|
||||
xEvent ev;
|
||||
|
||||
client_message_to_wire (event_send, &ev);
|
||||
|
||||
GetReq(SendEvent, req);
|
||||
req->destination = window;
|
||||
req->propagate = propagate;
|
||||
req->eventMask = event_mask;
|
||||
/* gross, matches Xproto.h */
|
||||
#ifdef WORD64
|
||||
memcpy ((char *) req->eventdata, (char *) &ev, SIZEOF(xEvent));
|
||||
#else
|
||||
memcpy ((char *) &req->event, (char *) &ev, SIZEOF(xEvent));
|
||||
#endif
|
||||
|
||||
state->send_event_req = dpy->request;
|
||||
}
|
||||
|
||||
/*
|
||||
* XSync (dpy, 0)
|
||||
*/
|
||||
{
|
||||
xReq *req;
|
||||
|
||||
GetEmptyReq(GetInputFocus, req);
|
||||
state->get_input_focus_req = dpy->request;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
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,
|
||||
char *buf,
|
||||
int len,
|
||||
XPointer data)
|
||||
{
|
||||
ListChildrenState *state = (ListChildrenState *)data;
|
||||
|
||||
if (dpy->last_request_read != state->get_property_req)
|
||||
return False;
|
||||
|
||||
if (rep->generic.type == X_Error)
|
||||
{
|
||||
state->have_error = TRUE;
|
||||
return False;
|
||||
}
|
||||
else
|
||||
{
|
||||
xGetPropertyReply replbuf;
|
||||
xGetPropertyReply *repl;
|
||||
|
||||
repl = (xGetPropertyReply *)
|
||||
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||
(sizeof(xGetPropertyReply) - sizeof(xReply)) >> 2,
|
||||
True);
|
||||
|
||||
state->has_wm_state = repl->propertyType != None;
|
||||
/* Since we called GetProperty with longLength of 0, we don't
|
||||
* have to worry about consuming the property data that would
|
||||
* normally follow after the reply
|
||||
*/
|
||||
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
list_children_and_wm_state (Display *dpy,
|
||||
Window w,
|
||||
Atom wm_state_atom,
|
||||
gboolean *has_wm_state,
|
||||
Window **children,
|
||||
unsigned int *nchildren)
|
||||
{
|
||||
ListChildrenState state;
|
||||
_XAsyncHandler async;
|
||||
long nbytes;
|
||||
xQueryTreeReply rep;
|
||||
register xResourceReq *req;
|
||||
xGetPropertyReq *prop_req;
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
*children = NULL;
|
||||
*nchildren = 0;
|
||||
*has_wm_state = FALSE;
|
||||
|
||||
state.have_error = FALSE;
|
||||
state.has_wm_state = FALSE;
|
||||
|
||||
if (wm_state_atom)
|
||||
{
|
||||
async.next = dpy->async_handlers;
|
||||
async.handler = list_children_handler;
|
||||
async.data = (XPointer) &state;
|
||||
dpy->async_handlers = &async;
|
||||
|
||||
GetReq (GetProperty, prop_req);
|
||||
prop_req->window = w;
|
||||
prop_req->property = wm_state_atom;
|
||||
prop_req->type = AnyPropertyType;
|
||||
prop_req->delete = False;
|
||||
prop_req->longOffset = 0;
|
||||
prop_req->longLength = 0;
|
||||
|
||||
state.get_property_req = dpy->request;
|
||||
}
|
||||
|
||||
GetResReq(QueryTree, w, req);
|
||||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
|
||||
{
|
||||
state.have_error = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rep.nChildren != 0)
|
||||
{
|
||||
nbytes = rep.nChildren << 2;
|
||||
if (state.have_error)
|
||||
{
|
||||
_XEatData(dpy, (unsigned long) nbytes);
|
||||
goto out;
|
||||
}
|
||||
*children = g_new (Window, rep.nChildren);
|
||||
_XRead32 (dpy, (long *) *children, nbytes);
|
||||
}
|
||||
|
||||
*nchildren = rep.nChildren;
|
||||
*has_wm_state = state.has_wm_state;
|
||||
|
||||
out:
|
||||
if (wm_state_atom)
|
||||
DeqAsyncHandler(dpy, &async);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return !state.have_error;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_get_wa_reply (Display *dpy,
|
||||
ChildInfoState *state,
|
||||
xGetWindowAttributesReply *repl)
|
||||
{
|
||||
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||
child->is_mapped = repl->mapState != IsUnmapped;
|
||||
child->window_class = repl->class;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_get_geometry_reply (Display *dpy,
|
||||
ChildInfoState *state,
|
||||
xGetGeometryReply *repl)
|
||||
{
|
||||
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||
|
||||
child->x = cvtINT16toInt (repl->x);
|
||||
child->y = cvtINT16toInt (repl->y);
|
||||
child->width = repl->width;
|
||||
child->height = repl->height;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_get_property_reply (Display *dpy,
|
||||
ChildInfoState *state,
|
||||
xGetPropertyReply *repl)
|
||||
{
|
||||
GdkChildInfoX11 *child = &state->child_info[state->n_children_found];
|
||||
child->has_wm_state = repl->propertyType != None;
|
||||
|
||||
/* Since we called GetProperty with longLength of 0, we don't
|
||||
* have to worry about consuming the property data that would
|
||||
* normally follow after the reply
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
next_child (ChildInfoState *state)
|
||||
{
|
||||
if (state->current_request == CHILD_INFO_GET_GEOMETRY)
|
||||
{
|
||||
if (!state->have_error && !state->child_has_error)
|
||||
{
|
||||
state->child_info[state->n_children_found].window = state->children[state->current_child];
|
||||
state->n_children_found++;
|
||||
}
|
||||
state->current_child++;
|
||||
if (state->get_wm_state)
|
||||
state->current_request = CHILD_INFO_GET_PROPERTY;
|
||||
else
|
||||
state->current_request = CHILD_INFO_GET_WA;
|
||||
state->child_has_error = FALSE;
|
||||
state->have_error = FALSE;
|
||||
}
|
||||
else
|
||||
state->current_request++;
|
||||
}
|
||||
|
||||
static Bool
|
||||
get_child_info_handler (Display *dpy,
|
||||
xReply *rep,
|
||||
char *buf,
|
||||
int len,
|
||||
XPointer data)
|
||||
{
|
||||
Bool result = True;
|
||||
|
||||
ChildInfoState *state = (ChildInfoState *)data;
|
||||
|
||||
if (dpy->last_request_read != state->child_states[state->current_child].seq[state->current_request])
|
||||
return False;
|
||||
|
||||
if (rep->generic.type == X_Error)
|
||||
{
|
||||
state->child_has_error = TRUE;
|
||||
if (rep->error.errorCode != BadDrawable ||
|
||||
rep->error.errorCode != BadWindow)
|
||||
{
|
||||
state->have_error = TRUE;
|
||||
result = False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state->current_request)
|
||||
{
|
||||
case CHILD_INFO_GET_PROPERTY:
|
||||
{
|
||||
xGetPropertyReply replbuf;
|
||||
xGetPropertyReply *repl;
|
||||
|
||||
repl = (xGetPropertyReply *)
|
||||
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||
(sizeof(xGetPropertyReply) - sizeof(xReply)) >> 2,
|
||||
True);
|
||||
|
||||
handle_get_property_reply (dpy, state, repl);
|
||||
}
|
||||
break;
|
||||
case CHILD_INFO_GET_WA:
|
||||
{
|
||||
xGetWindowAttributesReply replbuf;
|
||||
xGetWindowAttributesReply *repl;
|
||||
|
||||
repl = (xGetWindowAttributesReply *)
|
||||
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||
(sizeof(xGetWindowAttributesReply) - sizeof(xReply)) >> 2,
|
||||
True);
|
||||
|
||||
handle_get_wa_reply (dpy, state, repl);
|
||||
}
|
||||
break;
|
||||
case CHILD_INFO_GET_GEOMETRY:
|
||||
{
|
||||
xGetGeometryReply replbuf;
|
||||
xGetGeometryReply *repl;
|
||||
|
||||
repl = (xGetGeometryReply *)
|
||||
_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
|
||||
(sizeof(xGetGeometryReply) - sizeof(xReply)) >> 2,
|
||||
True);
|
||||
|
||||
handle_get_geometry_reply (dpy, state, repl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
next_child (state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_x11_get_window_child_info (GdkDisplay *display,
|
||||
Window window,
|
||||
gboolean get_wm_state,
|
||||
gboolean *win_has_wm_state,
|
||||
GdkChildInfoX11 **children,
|
||||
guint *nchildren)
|
||||
{
|
||||
Display *dpy;
|
||||
_XAsyncHandler async;
|
||||
ChildInfoState state;
|
||||
Atom wm_state_atom;
|
||||
gboolean has_wm_state;
|
||||
Bool result;
|
||||
guint i;
|
||||
|
||||
*children = NULL;
|
||||
*nchildren = 0;
|
||||
|
||||
dpy = GDK_DISPLAY_XDISPLAY (display);
|
||||
if (get_wm_state)
|
||||
wm_state_atom = gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE");
|
||||
else
|
||||
wm_state_atom = None;
|
||||
|
||||
state.children = NULL;
|
||||
state.nchildren = 0;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
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 ();
|
||||
if (!result)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (win_has_wm_state)
|
||||
*win_has_wm_state = FALSE;
|
||||
}
|
||||
|
||||
state.get_wm_state = get_wm_state;
|
||||
state.child_info = g_new (GdkChildInfoX11, state.nchildren);
|
||||
state.child_states = g_new (ChildInfoChildState, state.nchildren);
|
||||
state.current_child = 0;
|
||||
state.n_children_found = 0;
|
||||
if (get_wm_state)
|
||||
state.current_request = CHILD_INFO_GET_PROPERTY;
|
||||
else
|
||||
state.current_request = CHILD_INFO_GET_WA;
|
||||
state.have_error = FALSE;
|
||||
state.child_has_error = FALSE;
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
async.next = dpy->async_handlers;
|
||||
async.handler = get_child_info_handler;
|
||||
async.data = (XPointer) &state;
|
||||
dpy->async_handlers = &async;
|
||||
|
||||
for (i = 0; i < state.nchildren; i++)
|
||||
{
|
||||
xResourceReq *resource_req;
|
||||
xGetPropertyReq *prop_req;
|
||||
Window window = state.children[i];
|
||||
|
||||
if (get_wm_state)
|
||||
{
|
||||
GetReq (GetProperty, prop_req);
|
||||
prop_req->window = window;
|
||||
prop_req->property = wm_state_atom;
|
||||
prop_req->type = AnyPropertyType;
|
||||
prop_req->delete = False;
|
||||
prop_req->longOffset = 0;
|
||||
prop_req->longLength = 0;
|
||||
|
||||
state.child_states[i].seq[CHILD_INFO_GET_PROPERTY] = dpy->request;
|
||||
}
|
||||
|
||||
GetResReq(GetWindowAttributes, window, resource_req);
|
||||
state.child_states[i].seq[CHILD_INFO_GET_WA] = dpy->request;
|
||||
|
||||
GetResReq(GetGeometry, window, resource_req);
|
||||
state.child_states[i].seq[CHILD_INFO_GET_GEOMETRY] = dpy->request;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
/* Wait for the last reply
|
||||
*/
|
||||
xGetGeometryReply rep;
|
||||
|
||||
/* On error, our async handler will get called
|
||||
*/
|
||||
if (_XReply (dpy, (xReply *)&rep, 0, xTrue))
|
||||
handle_get_geometry_reply (dpy, &state, &rep);
|
||||
|
||||
next_child (&state);
|
||||
}
|
||||
|
||||
if (!state.have_error)
|
||||
{
|
||||
*children = state.child_info;
|
||||
*nchildren = state.n_children_found;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (state.child_info);
|
||||
}
|
||||
|
||||
g_free (state.children);
|
||||
g_free (state.child_states);
|
||||
|
||||
DeqAsyncHandler(dpy, &async);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
#define __GDK_ASYNC_C__
|
||||
#include "gdkaliasdef.c"
|
||||
Loading…
Add table
Add a link
Reference in a new issue