Bug Summary

File:cdk/x11/cdkdisplay-x11.c
Warning:line 1885, column 36
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cdkdisplay-x11.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/cdk/x11 -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D G_LOG_DOMAIN="Cdk" -D G_LOG_USE_STRUCTURED=1 -D CDK_COMPILATION -I ../.. -I ../../cdk -I ../../cdk -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cdk/x11 -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-171836-43636-1 -x c cdkdisplay-x11.c
1/* CDK - The GIMP Drawing Kit
2 * cdkdisplay-x11.c
3 *
4 * Copyright 2001 Sun Microsystems Inc.
5 * Copyright (C) 2004 Nokia Corporation
6 *
7 * Erwann Chenede <erwann.chenede@sun.com>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "config.h"
24
25#include "cdkasync.h"
26#include "cdkdisplay.h"
27#include "cdkeventsource.h"
28#include "cdkeventtranslator.h"
29#include "cdkframeclockprivate.h"
30#include "cdkinternals.h"
31#include "cdkscreen.h"
32#include "cdkinternals.h"
33#include "cdkdeviceprivate.h"
34#include "cdkkeysprivate.h"
35#include "cdkdevicemanager.h"
36#include "xsettings-client.h"
37#include "cdkdisplay-x11.h"
38#include "cdkprivate-x11.h"
39#include "cdkscreen-x11.h"
40#include "cdkglcontext-x11.h"
41#include "cdk-private.h"
42#include "cdkprofilerprivate.h"
43
44#include <glib.h>
45#include <glib/gprintf.h>
46#include <stdlib.h>
47#include <string.h>
48#include <errno(*__errno_location ()).h>
49#include <unistd.h>
50
51#include <X11/Xatom.h>
52#include <X11/Xlibint.h>
53
54#ifdef HAVE_XKB1
55#include <X11/XKBlib.h>
56#endif
57
58#ifdef HAVE_XFIXES1
59#include <X11/extensions/Xfixes.h>
60#endif
61
62#include <X11/extensions/shape.h>
63
64#ifdef HAVE_XCOMPOSITE1
65#include <X11/extensions/Xcomposite.h>
66#endif
67
68#ifdef HAVE_XDAMAGE1
69#include <X11/extensions/Xdamage.h>
70#endif
71
72#ifdef HAVE_RANDR1
73#include <X11/extensions/Xrandr.h>
74#endif
75
76typedef struct _CdkErrorTrap CdkErrorTrap;
77
78struct _CdkErrorTrap
79{
80 /* Next sequence when trap was pushed, i.e. first sequence to
81 * ignore
82 */
83 gulong start_sequence;
84
85 /* Next sequence when trap was popped, i.e. first sequence
86 * to not ignore. 0 if trap is still active.
87 */
88 gulong end_sequence;
89
90 /* Most recent error code within the sequence */
91 int error_code;
92};
93
94static void cdk_x11_display_dispose (GObject *object);
95static void cdk_x11_display_finalize (GObject *object);
96
97static void cdk_x11_display_event_translator_init (CdkEventTranslatorIface *iface);
98
99static gboolean cdk_x11_display_translate_event (CdkEventTranslator *translator,
100 CdkDisplay *display,
101 CdkEvent *event,
102 XEvent *xevent);
103
104static void cdk_internal_connection_watch (Display *display,
105 XPointer arg,
106 gint fd,
107 gboolean opening,
108 XPointer *watch_data);
109
110typedef struct _CdkEventTypeX11 CdkEventTypeX11;
111
112struct _CdkEventTypeX11
113{
114 gint base;
115 gint n_events;
116};
117
118/* Note that we never *directly* use WM_LOCALE_NAME, WM_PROTOCOLS,
119 * but including them here has the side-effect of getting them
120 * into the internal Xlib cache
121 */
122static const char *const precache_atoms[] = {
123 "UTF8_STRING",
124 "WM_CLIENT_LEADER",
125 "WM_DELETE_WINDOW",
126 "WM_ICON_NAME",
127 "WM_LOCALE_NAME",
128 "WM_NAME",
129 "WM_PROTOCOLS",
130 "WM_TAKE_FOCUS",
131 "WM_WINDOW_ROLE",
132 "_NET_ACTIVE_WINDOW",
133 "_NET_CURRENT_DESKTOP",
134 "_NET_FRAME_EXTENTS",
135 "_NET_STARTUP_ID",
136 "_NET_WM_CM_S0",
137 "_NET_WM_DESKTOP",
138 "_NET_WM_ICON",
139 "_NET_WM_ICON_NAME",
140 "_NET_WM_NAME",
141 "_NET_WM_PID",
142 "_NET_WM_PING",
143 "_NET_WM_STATE",
144 "_NET_WM_STATE_ABOVE",
145 "_NET_WM_STATE_BELOW",
146 "_NET_WM_STATE_FULLSCREEN",
147 "_NET_WM_STATE_HIDDEN",
148 "_NET_WM_STATE_MODAL",
149 "_NET_WM_STATE_MAXIMIZED_VERT",
150 "_NET_WM_STATE_MAXIMIZED_HORZ",
151 "_NET_WM_STATE_SKIP_TASKBAR",
152 "_NET_WM_STATE_SKIP_PAGER",
153 "_NET_WM_STATE_STICKY",
154 "_NET_WM_SYNC_REQUEST",
155 "_NET_WM_SYNC_REQUEST_COUNTER",
156 "_NET_WM_WINDOW_TYPE",
157 "_NET_WM_WINDOW_TYPE_COMBO",
158 "_NET_WM_WINDOW_TYPE_DIALOG",
159 "_NET_WM_WINDOW_TYPE_DND",
160 "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
161 "_NET_WM_WINDOW_TYPE_MENU",
162 "_NET_WM_WINDOW_TYPE_NORMAL",
163 "_NET_WM_WINDOW_TYPE_POPUP_MENU",
164 "_NET_WM_WINDOW_TYPE_TOOLTIP",
165 "_NET_WM_WINDOW_TYPE_UTILITY",
166 "_NET_WM_USER_TIME",
167 "_NET_WM_USER_TIME_WINDOW",
168 "_NET_VIRTUAL_ROOTS",
169 "CDK_SELECTION",
170 "_NET_WM_STATE_FOCUSED",
171 "CDK_VISUALS"
172};
173
174static char *cdk_sm_client_id;
175
176G_DEFINE_TYPE_WITH_CODE (CdkX11Display, cdk_x11_display, CDK_TYPE_DISPLAY,static void cdk_x11_display_init (CdkX11Display *self); static
void cdk_x11_display_class_init (CdkX11DisplayClass *klass);
static GType cdk_x11_display_get_type_once (void); static gpointer
cdk_x11_display_parent_class = ((void*)0); static gint CdkX11Display_private_offset
; static void cdk_x11_display_class_intern_init (gpointer klass
) { cdk_x11_display_parent_class = g_type_class_peek_parent (
klass); if (CdkX11Display_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CdkX11Display_private_offset); cdk_x11_display_class_init
((CdkX11DisplayClass*) klass); } __attribute__ ((__unused__)
) static inline gpointer cdk_x11_display_get_instance_private
(CdkX11Display *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkX11Display_private_offset)))); } GType cdk_x11_display_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= cdk_x11_display_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType cdk_x11_display_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
cdk_display_get_type ()), g_intern_static_string ("CdkX11Display"
), sizeof (CdkX11DisplayClass), (GClassInitFunc)(void (*)(void
)) cdk_x11_display_class_intern_init, sizeof (CdkX11Display),
(GInstanceInitFunc)(void (*)(void)) cdk_x11_display_init, (GTypeFlags
) 0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) cdk_x11_display_event_translator_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (_cdk_x11_event_translator_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
177 G_IMPLEMENT_INTERFACE (CDK_TYPE_EVENT_TRANSLATOR,static void cdk_x11_display_init (CdkX11Display *self); static
void cdk_x11_display_class_init (CdkX11DisplayClass *klass);
static GType cdk_x11_display_get_type_once (void); static gpointer
cdk_x11_display_parent_class = ((void*)0); static gint CdkX11Display_private_offset
; static void cdk_x11_display_class_intern_init (gpointer klass
) { cdk_x11_display_parent_class = g_type_class_peek_parent (
klass); if (CdkX11Display_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CdkX11Display_private_offset); cdk_x11_display_class_init
((CdkX11DisplayClass*) klass); } __attribute__ ((__unused__)
) static inline gpointer cdk_x11_display_get_instance_private
(CdkX11Display *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkX11Display_private_offset)))); } GType cdk_x11_display_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= cdk_x11_display_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType cdk_x11_display_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
cdk_display_get_type ()), g_intern_static_string ("CdkX11Display"
), sizeof (CdkX11DisplayClass), (GClassInitFunc)(void (*)(void
)) cdk_x11_display_class_intern_init, sizeof (CdkX11Display),
(GInstanceInitFunc)(void (*)(void)) cdk_x11_display_init, (GTypeFlags
) 0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) cdk_x11_display_event_translator_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (_cdk_x11_event_translator_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
178 cdk_x11_display_event_translator_init))static void cdk_x11_display_init (CdkX11Display *self); static
void cdk_x11_display_class_init (CdkX11DisplayClass *klass);
static GType cdk_x11_display_get_type_once (void); static gpointer
cdk_x11_display_parent_class = ((void*)0); static gint CdkX11Display_private_offset
; static void cdk_x11_display_class_intern_init (gpointer klass
) { cdk_x11_display_parent_class = g_type_class_peek_parent (
klass); if (CdkX11Display_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CdkX11Display_private_offset); cdk_x11_display_class_init
((CdkX11DisplayClass*) klass); } __attribute__ ((__unused__)
) static inline gpointer cdk_x11_display_get_instance_private
(CdkX11Display *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkX11Display_private_offset)))); } GType cdk_x11_display_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= cdk_x11_display_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType cdk_x11_display_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
cdk_display_get_type ()), g_intern_static_string ("CdkX11Display"
), sizeof (CdkX11DisplayClass), (GClassInitFunc)(void (*)(void
)) cdk_x11_display_class_intern_init, sizeof (CdkX11Display),
(GInstanceInitFunc)(void (*)(void)) cdk_x11_display_init, (GTypeFlags
) 0); { {{ const GInterfaceInfo g_implement_interface_info = {
(GInterfaceInitFunc)(void (*)(void)) cdk_x11_display_event_translator_init
, ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id
, (_cdk_x11_event_translator_get_type ()), &g_implement_interface_info
); };} } return g_define_type_id; }
179
180
181static void
182cdk_x11_display_init (CdkX11Display *display)
183{
184 display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
185}
186
187static void
188cdk_x11_display_event_translator_init (CdkEventTranslatorIface *iface)
189{
190 iface->translate_event = cdk_x11_display_translate_event;
191}
192
193#define ANY_EDGE_TILED(CDK_WINDOW_STATE_LEFT_TILED | CDK_WINDOW_STATE_RIGHT_TILED |
CDK_WINDOW_STATE_TOP_TILED | CDK_WINDOW_STATE_BOTTOM_TILED)
(CDK_WINDOW_STATE_LEFT_TILED | \
194 CDK_WINDOW_STATE_RIGHT_TILED | \
195 CDK_WINDOW_STATE_TOP_TILED | \
196 CDK_WINDOW_STATE_BOTTOM_TILED)
197
198static void
199do_edge_constraint_state_check (CdkWindow *window,
200 CdkWindowState old_state,
201 CdkWindowState *set,
202 CdkWindowState *unset)
203{
204 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
205 CdkWindowState local_set, local_unset;
206 CdkScreen *screen = CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window));
207 guint edge_constraints;
208
209 local_set = *set;
210 local_unset = *unset;
211 edge_constraints = toplevel->edge_constraints;
212
213 /* If the WM doesn't support _CTK_EDGE_CONSTRAINTS, rely on the fallback
214 * implementation. If it supports _CTK_EDGE_CONSTRAINTS, arrange for
215 * CDK_WINDOW_STATE_TILED to be set if any edge is tiled, and cleared
216 * if no edge is tiled.
217 */
218 if (!cdk_x11_screen_supports_net_wm_hint (screen,
219 cdk_atom_intern_static_string ("_CTK_EDGE_CONSTRAINTS")))
220 {
221 /* FIXME: we rely on implementation details of mutter here:
222 * mutter only tiles horizontally, and sets maxvert when it does
223 * and if it tiles, it always affects all edges
224 */
225 if (old_state & CDK_WINDOW_STATE_TILED)
226 {
227 if (!toplevel->have_maxvert)
228 local_unset |= CDK_WINDOW_STATE_TILED;
229 }
230 else
231 {
232 if (toplevel->have_maxvert && !toplevel->have_maxhorz)
233 local_set |= CDK_WINDOW_STATE_TILED;
234 }
235 }
236 else
237 {
238 if (old_state & CDK_WINDOW_STATE_TILED)
239 {
240 if (!(edge_constraints & ANY_EDGE_TILED(CDK_WINDOW_STATE_LEFT_TILED | CDK_WINDOW_STATE_RIGHT_TILED |
CDK_WINDOW_STATE_TOP_TILED | CDK_WINDOW_STATE_BOTTOM_TILED)
))
241 local_unset |= CDK_WINDOW_STATE_TILED;
242 }
243 else
244 {
245 if (edge_constraints & ANY_EDGE_TILED(CDK_WINDOW_STATE_LEFT_TILED | CDK_WINDOW_STATE_RIGHT_TILED |
CDK_WINDOW_STATE_TOP_TILED | CDK_WINDOW_STATE_BOTTOM_TILED)
)
246 local_set |= CDK_WINDOW_STATE_TILED;
247 }
248 }
249
250 /* Top edge */
251 if (old_state & CDK_WINDOW_STATE_TOP_TILED)
252 {
253 if ((edge_constraints & CDK_WINDOW_STATE_TOP_TILED) == 0)
254 local_unset |= CDK_WINDOW_STATE_TOP_TILED;
255 }
256 else
257 {
258 if (edge_constraints & CDK_WINDOW_STATE_TOP_TILED)
259 local_set |= CDK_WINDOW_STATE_TOP_TILED;
260 }
261
262 if (old_state & CDK_WINDOW_STATE_TOP_RESIZABLE)
263 {
264 if ((edge_constraints & CDK_WINDOW_STATE_TOP_RESIZABLE) == 0)
265 local_unset |= CDK_WINDOW_STATE_TOP_RESIZABLE;
266 }
267 else
268 {
269 if (edge_constraints & CDK_WINDOW_STATE_TOP_RESIZABLE)
270 local_set |= CDK_WINDOW_STATE_TOP_RESIZABLE;
271 }
272
273 /* Right edge */
274 if (old_state & CDK_WINDOW_STATE_RIGHT_TILED)
275 {
276 if ((edge_constraints & CDK_WINDOW_STATE_RIGHT_TILED) == 0)
277 local_unset |= CDK_WINDOW_STATE_RIGHT_TILED;
278 }
279 else
280 {
281 if (edge_constraints & CDK_WINDOW_STATE_RIGHT_TILED)
282 local_set |= CDK_WINDOW_STATE_RIGHT_TILED;
283 }
284
285 if (old_state & CDK_WINDOW_STATE_RIGHT_RESIZABLE)
286 {
287 if ((edge_constraints & CDK_WINDOW_STATE_RIGHT_RESIZABLE) == 0)
288 local_unset |= CDK_WINDOW_STATE_RIGHT_RESIZABLE;
289 }
290 else
291 {
292 if (edge_constraints & CDK_WINDOW_STATE_RIGHT_RESIZABLE)
293 local_set |= CDK_WINDOW_STATE_RIGHT_RESIZABLE;
294 }
295
296 /* Bottom edge */
297 if (old_state & CDK_WINDOW_STATE_BOTTOM_TILED)
298 {
299 if ((edge_constraints & CDK_WINDOW_STATE_BOTTOM_TILED) == 0)
300 local_unset |= CDK_WINDOW_STATE_BOTTOM_TILED;
301 }
302 else
303 {
304 if (edge_constraints & CDK_WINDOW_STATE_BOTTOM_TILED)
305 local_set |= CDK_WINDOW_STATE_BOTTOM_TILED;
306 }
307
308 if (old_state & CDK_WINDOW_STATE_BOTTOM_RESIZABLE)
309 {
310 if ((edge_constraints & CDK_WINDOW_STATE_BOTTOM_RESIZABLE) == 0)
311 local_unset |= CDK_WINDOW_STATE_BOTTOM_RESIZABLE;
312 }
313 else
314 {
315 if (edge_constraints & CDK_WINDOW_STATE_BOTTOM_RESIZABLE)
316 local_set |= CDK_WINDOW_STATE_BOTTOM_RESIZABLE;
317 }
318
319 /* Left edge */
320 if (old_state & CDK_WINDOW_STATE_LEFT_TILED)
321 {
322 if ((edge_constraints & CDK_WINDOW_STATE_LEFT_TILED) == 0)
323 local_unset |= CDK_WINDOW_STATE_LEFT_TILED;
324 }
325 else
326 {
327 if (edge_constraints & CDK_WINDOW_STATE_LEFT_TILED)
328 local_set |= CDK_WINDOW_STATE_LEFT_TILED;
329 }
330
331 if (old_state & CDK_WINDOW_STATE_LEFT_RESIZABLE)
332 {
333 if ((edge_constraints & CDK_WINDOW_STATE_LEFT_RESIZABLE) == 0)
334 local_unset |= CDK_WINDOW_STATE_LEFT_RESIZABLE;
335 }
336 else
337 {
338 if (edge_constraints & CDK_WINDOW_STATE_LEFT_RESIZABLE)
339 local_set |= CDK_WINDOW_STATE_LEFT_RESIZABLE;
340 }
341
342 *set = local_set;
343 *unset = local_unset;
344}
345
346static void
347do_net_wm_state_changes (CdkWindow *window)
348{
349 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
350 CdkWindowState old_state, set, unset;
351
352 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
353 cdk_window_get_window_type (window) != CDK_WINDOW_TOPLEVEL)
354 return;
355
356 old_state = cdk_window_get_state (window);
357
358 set = unset = 0;
359
360 /* For found_sticky to remain TRUE, we have to also be on desktop
361 * 0xFFFFFFFF
362 */
363 if (old_state & CDK_WINDOW_STATE_STICKY)
364 {
365 if (!(toplevel->have_sticky && toplevel->on_all_desktops))
366 unset |= CDK_WINDOW_STATE_STICKY;
367 }
368 else
369 {
370 if (toplevel->have_sticky && toplevel->on_all_desktops)
371 set |= CDK_WINDOW_STATE_STICKY;
372 }
373
374 if (old_state & CDK_WINDOW_STATE_FULLSCREEN)
375 {
376 if (!toplevel->have_fullscreen)
377 unset |= CDK_WINDOW_STATE_FULLSCREEN;
378 }
379 else
380 {
381 if (toplevel->have_fullscreen)
382 set |= CDK_WINDOW_STATE_FULLSCREEN;
383 }
384
385 /* Our "maximized" means both vertical and horizontal; if only one,
386 * we don't expose that via CDK
387 */
388 if (old_state & CDK_WINDOW_STATE_MAXIMIZED)
389 {
390 if (!(toplevel->have_maxvert && toplevel->have_maxhorz))
391 unset |= CDK_WINDOW_STATE_MAXIMIZED;
392 }
393 else
394 {
395 if (toplevel->have_maxvert && toplevel->have_maxhorz)
396 set |= CDK_WINDOW_STATE_MAXIMIZED;
397 }
398
399 if (old_state & CDK_WINDOW_STATE_FOCUSED)
400 {
401 if (!toplevel->have_focused)
402 unset |= CDK_WINDOW_STATE_FOCUSED;
403 }
404 else
405 {
406 if (toplevel->have_focused)
407 set |= CDK_WINDOW_STATE_FOCUSED;
408 }
409
410 if (old_state & CDK_WINDOW_STATE_ICONIFIED)
411 {
412 if (!toplevel->have_hidden)
413 unset |= CDK_WINDOW_STATE_ICONIFIED;
414 }
415 else
416 {
417 if (toplevel->have_hidden)
418 set |= CDK_WINDOW_STATE_ICONIFIED;
419 }
420
421 /* Update edge constraints and tiling */
422 do_edge_constraint_state_check (window, old_state, &set, &unset);
423
424 cdk_synthesize_window_state (window, unset, set);
425}
426
427static void
428cdk_check_wm_desktop_changed (CdkWindow *window)
429{
430 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
431 CdkDisplay *display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
432
433 Atom type;
434 gint format;
435 gulong nitems;
436 gulong bytes_after;
437 guchar *data;
438
439 type = None0L;
440 cdk_x11_display_error_trap_push (display);
441 XGetWindowProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
442 CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
,
443 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
444 0, G_MAXLONG9223372036854775807L, False0, XA_CARDINAL((Atom) 6), &type,
445 &format, &nitems,
446 &bytes_after, &data);
447 cdk_x11_display_error_trap_pop_ignored (display);
448
449 if (type != None0L)
450 {
451 gulong *desktop;
452
453 desktop = (gulong *)data;
454 toplevel->on_all_desktops = ((*desktop & 0xFFFFFFFF) == 0xFFFFFFFF);
455 XFree (desktop);
456 }
457 else
458 toplevel->on_all_desktops = FALSE(0);
459
460 do_net_wm_state_changes (window);
461}
462
463static void
464cdk_check_wm_state_changed (CdkWindow *window)
465{
466 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
467 CdkDisplay *display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
468 CdkScreen *screen = CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window));
469
470 Atom type;
471 gint format;
472 gulong nitems;
473 gulong bytes_after;
474 guchar *data;
475 Atom *atoms = NULL((void*)0);
476 gulong i;
477
478 gboolean had_sticky = toplevel->have_sticky;
479
480 toplevel->have_sticky = FALSE(0);
481 toplevel->have_maxvert = FALSE(0);
482 toplevel->have_maxhorz = FALSE(0);
483 toplevel->have_fullscreen = FALSE(0);
484 toplevel->have_focused = FALSE(0);
485 toplevel->have_hidden = FALSE(0);
486
487 type = None0L;
488 cdk_x11_display_error_trap_push (display);
489 XGetWindowProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
,
490 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
491 0, G_MAXLONG9223372036854775807L, False0, XA_ATOM((Atom) 4), &type, &format, &nitems,
492 &bytes_after, &data);
493 cdk_x11_display_error_trap_pop_ignored (display);
494
495 if (type != None0L)
496 {
497 Atom sticky_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
498 Atom maxvert_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
499 Atom maxhorz_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
500 Atom fullscreen_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
501 Atom focused_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FOCUSED");
502 Atom hidden_atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_HIDDEN");
503
504 atoms = (Atom *)data;
505
506 i = 0;
507 while (i < nitems)
508 {
509 if (atoms[i] == sticky_atom)
510 toplevel->have_sticky = TRUE(!(0));
511 else if (atoms[i] == maxvert_atom)
512 toplevel->have_maxvert = TRUE(!(0));
513 else if (atoms[i] == maxhorz_atom)
514 toplevel->have_maxhorz = TRUE(!(0));
515 else if (atoms[i] == fullscreen_atom)
516 toplevel->have_fullscreen = TRUE(!(0));
517 else if (atoms[i] == focused_atom)
518 toplevel->have_focused = TRUE(!(0));
519 else if (atoms[i] == hidden_atom)
520 toplevel->have_hidden = TRUE(!(0));
521
522 ++i;
523 }
524
525 XFree (atoms);
526 }
527
528 if (!cdk_x11_screen_supports_net_wm_hint (screen,
529 cdk_atom_intern_static_string ("_NET_WM_STATE_FOCUSED")))
530 toplevel->have_focused = TRUE(!(0));
531
532 /* When have_sticky is turned on, we have to check the DESKTOP property
533 * as well.
534 */
535 if (toplevel->have_sticky && !had_sticky)
536 cdk_check_wm_desktop_changed (window);
537 else
538 do_net_wm_state_changes (window);
539}
540
541static void
542cdk_check_edge_constraints_changed (CdkWindow *window)
543{
544 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
545 CdkDisplay *display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
546
547 Atom type;
548 gint format;
549 gulong nitems;
550 gulong bytes_after;
551 guchar *data;
552 gulong *constraints;
553
554 type = None0L;
555 cdk_x11_display_error_trap_push (display);
556 XGetWindowProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
557 CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
,
558 cdk_x11_get_xatom_by_name_for_display (display, "_CTK_EDGE_CONSTRAINTS"),
559 0, G_MAXLONG9223372036854775807L, False0, XA_CARDINAL((Atom) 6), &type,
560 &format, &nitems,
561 &bytes_after, &data);
562 cdk_x11_display_error_trap_pop_ignored (display);
563
564 if (type != None0L)
565 {
566 constraints = (gulong *)data;
567
568 /* The CDK enum for these states does not begin at zero so, to avoid
569 * messing around with shifts, just make the passed value and CDK's
570 * enum values match by shifting to the first tiled state.
571 */
572 toplevel->edge_constraints = constraints[0] << 9;
573
574 XFree (constraints);
575 }
576 else
577 {
578 toplevel->edge_constraints = 0;
579 }
580
581 do_net_wm_state_changes (window);
582}
583
584static Window
585get_event_xwindow (XEvent *xevent)
586{
587 Window xwindow;
588
589 switch (xevent->type)
590 {
591 case DestroyNotify17:
592 xwindow = xevent->xdestroywindow.window;
593 break;
594 case UnmapNotify18:
595 xwindow = xevent->xunmap.window;
596 break;
597 case MapNotify19:
598 xwindow = xevent->xmap.window;
599 break;
600 case ConfigureNotify22:
601 xwindow = xevent->xconfigure.window;
602 break;
603 case ReparentNotify21:
604 xwindow = xevent->xreparent.window;
605 break;
606 case GravityNotify24:
607 xwindow = xevent->xgravity.window;
608 break;
609 case CirculateNotify26:
610 xwindow = xevent->xcirculate.window;
611 break;
612 default:
613 xwindow = xevent->xany.window;
614 }
615
616 return xwindow;
617}
618
619static gboolean
620cdk_x11_display_translate_event (CdkEventTranslator *translator G_GNUC_UNUSED__attribute__ ((__unused__)),
621 CdkDisplay *display,
622 CdkEvent *event,
623 XEvent *xevent)
624{
625 Window xwindow;
626 CdkWindow *window;
627 gboolean is_substructure;
628 CdkWindowImplX11 *window_impl = NULL((void*)0);
629 CdkScreen *screen = NULL((void*)0);
630 CdkX11Screen *x11_screen = NULL((void*)0);
631 CdkToplevelX11 *toplevel = NULL((void*)0);
632 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
633 gboolean return_val;
634
635 /* Find the CdkWindow that this event relates to. If that's
636 * not the same as the window that the event was sent to,
637 * we are getting an event from SubstructureNotifyMask.
638 * We ignore such events for internal operation, but we
639 * need to report them to the application because of
640 * CDK_SUBSTRUCTURE_MASK (which should be removed at next
641 * opportunity.) The most likely reason for getting these
642 * events is when we are used in the Metacity or Mutter
643 * window managers.
644 */
645 xwindow = get_event_xwindow (xevent);
646 is_substructure = xwindow != xevent->xany.window;
647
648 window = cdk_x11_window_lookup_for_display (display, xwindow);
649 if (window)
650 {
651 /* We may receive events such as NoExpose/GraphicsExpose
652 * and ShmCompletion for pixmaps
653 */
654 if (!CDK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(window)); GType __t = ((cdk_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
655 return FALSE(0);
656
657 screen = CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window));
658 x11_screen = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
;
659 toplevel = _cdk_x11_window_get_toplevel (window);
660 window_impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
661
662 g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
663 }
664
665 event->any.window = window;
666 event->any.send_event = xevent->xany.send_event ? TRUE(!(0)) : FALSE(0);
667
668 if (window && CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
669 {
670 if (xevent->type != DestroyNotify17)
671 {
672 return_val = FALSE(0);
673 goto done;
674 }
675 }
676
677 if (xevent->type == DestroyNotify17 && !is_substructure)
678 {
679 screen = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->screen;
680 x11_screen = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
;
681
682 if (x11_screen->wmspec_check_window == xevent->xdestroywindow.window)
683 {
684 x11_screen->wmspec_check_window = None0L;
685 x11_screen->last_wmspec_check_time = 0;
686 g_free (x11_screen->window_manager_name);
687 x11_screen->window_manager_name = g_strdup ("unknown")g_strdup_inline ("unknown");
688
689 /* careful, reentrancy */
690 _cdk_x11_screen_window_manager_changed (screen);
691
692 return_val = FALSE(0);
693 goto done;
694 }
695 }
696
697 /* We do a "manual" conversion of the XEvent to a
698 * CdkEvent. The structures are mostly the same so
699 * the conversion is fairly straightforward. We also
700 * optionally print debugging info regarding events
701 * received.
702 */
703
704 return_val = TRUE(!(0));
705
706 switch (xevent->type)
707 {
708 case KeymapNotify11:
709 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("keymap notify"); }; } while (0)
710 g_message ("keymap notify"))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("keymap notify"); }; } while (0)
;
711
712 /* Not currently handled */
713 return_val = FALSE(0);
714 break;
715
716 case Expose12:
717 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
718 g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
719 xevent->xexpose.window, xevent->xexpose.count,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
720 xevent->xexpose.x, xevent->xexpose.y,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
721 xevent->xexpose.width, xevent->xexpose.height,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
722 event->any.send_event ? " (send)" : ""))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s", xevent
->xexpose.window, xevent->xexpose.count, xevent->xexpose
.x, xevent->xexpose.y, xevent->xexpose.width, xevent->
xexpose.height, event->any.send_event ? " (send)" : ""); }
; } while (0)
;
723
724 if (window == NULL((void*)0))
725 {
726 return_val = FALSE(0);
727 break;
728 }
729
730 {
731 CdkRectangle expose_rect;
732 int x2, y2;
733
734 expose_rect.x = xevent->xexpose.x / window_impl->window_scale;
735 expose_rect.y = xevent->xexpose.y / window_impl->window_scale;
736
737 x2 = (xevent->xexpose.x + xevent->xexpose.width + window_impl->window_scale -1) / window_impl->window_scale;
738 expose_rect.width = x2 - expose_rect.x;
739
740 y2 = (xevent->xexpose.y + xevent->xexpose.height + window_impl->window_scale -1) / window_impl->window_scale;
741 expose_rect.height = y2 - expose_rect.y;
742
743 _cdk_x11_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
744 return_val = FALSE(0);
745 }
746
747 break;
748
749 case GraphicsExpose13:
750 {
751 CdkRectangle expose_rect;
752 int x2, y2;
753
754 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("graphics expose:\tdrawable: %ld", xevent->xgraphicsexpose
.drawable); }; } while (0)
755 g_message ("graphics expose:\tdrawable: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("graphics expose:\tdrawable: %ld", xevent->xgraphicsexpose
.drawable); }; } while (0)
756 xevent->xgraphicsexpose.drawable))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("graphics expose:\tdrawable: %ld", xevent->xgraphicsexpose
.drawable); }; } while (0)
;
757
758 if (window == NULL((void*)0))
759 {
760 return_val = FALSE(0);
761 break;
762 }
763
764 expose_rect.x = xevent->xgraphicsexpose.x / window_impl->window_scale;
765 expose_rect.y = xevent->xgraphicsexpose.y / window_impl->window_scale;
766
767 x2 = (xevent->xgraphicsexpose.x + xevent->xgraphicsexpose.width + window_impl->window_scale -1) / window_impl->window_scale;
768 expose_rect.width = x2 - expose_rect.x;
769
770 y2 = (xevent->xgraphicsexpose.y + xevent->xgraphicsexpose.height + window_impl->window_scale -1) / window_impl->window_scale;
771 expose_rect.height = y2 - expose_rect.y;
772
773 _cdk_x11_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
774 return_val = FALSE(0);
775 }
776 break;
777
778 case VisibilityNotify15:
779#ifdef G_ENABLE_DEBUG1
780 if (CDK_DEBUG_CHECK (EVENTS)(_cdk_debug_flags & CDK_DEBUG_EVENTS))
781 switch (xevent->xvisibility.state)
782 {
783 case VisibilityFullyObscured2:
784 g_message ("visibility notify:\twindow: %ld none",
785 xevent->xvisibility.window);
786 break;
787 case VisibilityPartiallyObscured1:
788 g_message ("visibility notify:\twindow: %ld partial",
789 xevent->xvisibility.window);
790 break;
791 case VisibilityUnobscured0:
792 g_message ("visibility notify:\twindow: %ld full",
793 xevent->xvisibility.window);
794 break;
795 }
796#endif /* G_ENABLE_DEBUG */
797
798 if (window == NULL((void*)0))
799 {
800 return_val = FALSE(0);
801 break;
802 }
803
804 event->visibility.type = CDK_VISIBILITY_NOTIFY;
805 event->visibility.window = window;
806
807 switch (xevent->xvisibility.state)
808 {
809 case VisibilityFullyObscured2:
810 event->visibility.state = CDK_VISIBILITY_FULLY_OBSCURED;
811 break;
812
813 case VisibilityPartiallyObscured1:
814 event->visibility.state = CDK_VISIBILITY_PARTIAL;
815 break;
816
817 case VisibilityUnobscured0:
818 event->visibility.state = CDK_VISIBILITY_UNOBSCURED;
819 break;
820 }
821
822 break;
823
824 case CreateNotify16:
825 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
826 g_message ("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
827 xevent->xcreatewindow.window,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
828 xevent->xcreatewindow.x,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
829 xevent->xcreatewindow.y,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
830 xevent->xcreatewindow.width,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
831 xevent->xcreatewindow.height,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
832 xevent->xcreatewindow.border_width,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
833 xevent->xcreatewindow.parent,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
834 xevent->xcreatewindow.override_redirect))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d"
, xevent->xcreatewindow.window, xevent->xcreatewindow.x
, xevent->xcreatewindow.y, xevent->xcreatewindow.width,
xevent->xcreatewindow.height, xevent->xcreatewindow.border_width
, xevent->xcreatewindow.parent, xevent->xcreatewindow.override_redirect
); }; } while (0)
;
835 /* not really handled */
836 break;
837
838 case DestroyNotify17:
839 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("destroy notify:\twindow: %ld", xevent->xdestroywindow.window
); }; } while (0)
840 g_message ("destroy notify:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("destroy notify:\twindow: %ld", xevent->xdestroywindow.window
); }; } while (0)
841 xevent->xdestroywindow.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("destroy notify:\twindow: %ld", xevent->xdestroywindow.window
); }; } while (0)
;
842
843 if (!is_substructure)
844 {
845 event->any.type = CDK_DESTROY;
846 event->any.window = window;
847
848 return_val = window && !CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed);
849
850 if (window && CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
!= x11_screen->xroot_window)
851 cdk_window_destroy_notify (window);
852 }
853 else
854 return_val = FALSE(0);
855
856 break;
857
858 case UnmapNotify18:
859 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("unmap notify:\t\twindow: %ld", xevent->xmap.window); };
} while (0)
860 g_message ("unmap notify:\t\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("unmap notify:\t\twindow: %ld", xevent->xmap.window); };
} while (0)
861 xevent->xmap.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("unmap notify:\t\twindow: %ld", xevent->xmap.window); };
} while (0)
;
862
863 event->any.type = CDK_UNMAP;
864 event->any.window = window;
865
866 if (window && !is_substructure)
867 {
868 /* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to
869 * interpret UnmapNotify events as implying iconic state.
870 * http://bugzilla.gnome.org/show_bug.cgi?id=590726.
871 */
872 if (screen &&
873 !cdk_x11_screen_supports_net_wm_hint (screen,
874 cdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN")))
875 {
876 /* If we are shown (not withdrawn) and get an unmap, it means we were
877 * iconified in the X sense. If we are withdrawn, and get an unmap, it
878 * means we hid the window ourselves, so we will have already flipped
879 * the iconified bit off.
880 */
881 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
882 cdk_synthesize_window_state (window,
883 0,
884 CDK_WINDOW_STATE_ICONIFIED);
885 }
886
887 if (window_impl->toplevel &&
888 window_impl->toplevel->frame_pending)
889 {
890 window_impl->toplevel->frame_pending = FALSE(0);
891 _cdk_frame_clock_thaw (cdk_window_get_frame_clock (event->any.window));
892 }
893
894 if (toplevel)
895 cdk_window_freeze_toplevel_updates (window);
896
897 _cdk_x11_window_grab_check_unmap (window, xevent->xany.serial);
898 }
899
900 break;
901
902 case MapNotify19:
903 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("map notify:\t\twindow: %ld", xevent->xmap.window); }; }
while (0)
904 g_message ("map notify:\t\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("map notify:\t\twindow: %ld", xevent->xmap.window); }; }
while (0)
905 xevent->xmap.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("map notify:\t\twindow: %ld", xevent->xmap.window); }; }
while (0)
;
906
907 event->any.type = CDK_MAP;
908 event->any.window = window;
909
910 if (window && !is_substructure)
911 {
912 /* Unset iconified if it was set */
913 if (window->state & CDK_WINDOW_STATE_ICONIFIED)
914 cdk_synthesize_window_state (window,
915 CDK_WINDOW_STATE_ICONIFIED,
916 0);
917
918 if (toplevel)
919 cdk_window_thaw_toplevel_updates (window);
920 }
921
922 break;
923
924 case ReparentNotify21:
925 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
926 g_message ("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
927 xevent->xreparent.window,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
928 xevent->xreparent.x,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
929 xevent->xreparent.y,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
930 xevent->xreparent.parent,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
931 xevent->xreparent.override_redirect))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d"
, xevent->xreparent.window, xevent->xreparent.x, xevent
->xreparent.y, xevent->xreparent.parent, xevent->xreparent
.override_redirect); }; } while (0)
;
932
933 /* Not currently handled */
934 return_val = FALSE(0);
935 break;
936
937 case ConfigureNotify22:
938 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
939 g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
940 xevent->xconfigure.window,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
941 xevent->xconfigure.x,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
942 xevent->xconfigure.y,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
943 xevent->xconfigure.width,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
944 xevent->xconfigure.height,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
945 xevent->xconfigure.border_width,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
946 xevent->xconfigure.above,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
947 xevent->xconfigure.override_redirect,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
948 !windowdo { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
949 ? " (discarding)"do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
950 : window->window_type == CDK_WINDOW_CHILDdo { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
951 ? " (discarding child)"do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
952 : xevent->xconfigure.event != xevent->xconfigure.windowdo { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
953 ? " (discarding substructure)"do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
954 : ""))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s"
, xevent->xconfigure.window, xevent->xconfigure.x, xevent
->xconfigure.y, xevent->xconfigure.width, xevent->xconfigure
.height, xevent->xconfigure.border_width, xevent->xconfigure
.above, xevent->xconfigure.override_redirect, !window ? " (discarding)"
: window->window_type == CDK_WINDOW_CHILD ? " (discarding child)"
: xevent->xconfigure.event != xevent->xconfigure.window
? " (discarding substructure)" : ""); }; } while (0)
;
955 if (window && CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_ROOT)
956 {
957 window_impl->unscaled_width = xevent->xconfigure.width;
958 window_impl->unscaled_height = xevent->xconfigure.height;
959 window->width = (xevent->xconfigure.width + window_impl->window_scale - 1) / window_impl->window_scale;
960 window->height = (xevent->xconfigure.height + window_impl->window_scale - 1) / window_impl->window_scale;
961
962 _cdk_window_update_size (window);
963 _cdk_x11_window_update_size (window_impl);
964 _cdk_x11_screen_size_changed (screen, xevent);
965 }
966
967#ifdef HAVE_XSYNC1
968 if (!is_substructure && toplevel && display_x11->use_sync && toplevel->pending_counter_value != 0)
969 {
970 toplevel->configure_counter_value = toplevel->pending_counter_value;
971 toplevel->configure_counter_value_is_extended = toplevel->pending_counter_value_is_extended;
972 toplevel->pending_counter_value = 0;
973 }
974#endif
975
976 if (!window ||
977 xevent->xconfigure.event != xevent->xconfigure.window ||
978 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_CHILD ||
979 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_ROOT)
980 return_val = FALSE(0);
981 else
982 {
983 event->configure.type = CDK_CONFIGURE;
984 event->configure.window = window;
985 event->configure.width = (xevent->xconfigure.width + window_impl->window_scale - 1) / window_impl->window_scale;
986 event->configure.height = (xevent->xconfigure.height + window_impl->window_scale - 1) / window_impl->window_scale;
987
988 if (!xevent->xconfigure.send_event &&
989 !xevent->xconfigure.override_redirect &&
990 !CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
991 {
992 gint tx = 0;
993 gint ty = 0;
994 Window child_window = 0;
995
996 cdk_x11_display_error_trap_push (display);
997 if (XTranslateCoordinates (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
998 CDK_WINDOW_XID (window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
,
999 x11_screen->xroot_window,
1000 0, 0,
1001 &tx, &ty,
1002 &child_window))
1003 {
1004 event->configure.x = tx / window_impl->window_scale;
1005 event->configure.y = ty / window_impl->window_scale;
1006 }
1007 cdk_x11_display_error_trap_pop_ignored (display);
1008 }
1009 else
1010 {
1011 event->configure.x = xevent->xconfigure.x / window_impl->window_scale;
1012 event->configure.y = xevent->xconfigure.y / window_impl->window_scale;
1013 }
1014 if (!is_substructure)
1015 {
1016 window->x = event->configure.x;
1017 window->y = event->configure.y;
1018
1019 if (window_impl->unscaled_width != xevent->xconfigure.width ||
1020 window_impl->unscaled_height != xevent->xconfigure.height)
1021 {
1022 window_impl->unscaled_width = xevent->xconfigure.width;
1023 window_impl->unscaled_height = xevent->xconfigure.height;
1024 window->width = event->configure.width;
1025 window->height = event->configure.height;
1026
1027 _cdk_window_update_size (window);
1028 _cdk_x11_window_update_size (window_impl);
1029 }
1030
1031 if (window->resize_count >= 1)
1032 {
1033 window->resize_count -= 1;
1034
1035 if (window->resize_count == 0)
1036 _cdk_x11_moveresize_configure_done (display, window);
1037 }
1038 }
1039 }
1040 break;
1041
1042 case PropertyNotify28:
1043 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1044 g_message ("property notify:\twindow: %ld, atom(%ld): %s%s%s",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1045 xevent->xproperty.window,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1046 xevent->xproperty.atom,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1047 "\"",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1048 cdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom),do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
1049 "\""))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("property notify:\twindow: %ld, atom(%ld): %s%s%s", xevent->
xproperty.window, xevent->xproperty.atom, "\"", cdk_x11_get_xatom_name_for_display
(display, xevent->xproperty.atom), "\""); }; } while (0)
;
1050
1051 if (window == NULL((void*)0))
1052 {
1053 return_val = FALSE(0);
1054 break;
1055 }
1056
1057 /* We compare with the serial of the last time we mapped the
1058 * window to avoid refetching properties that we set ourselves
1059 */
1060 if (toplevel &&
1061 xevent->xproperty.serial >= toplevel->map_serial)
1062 {
1063 if (xevent->xproperty.atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
1064 cdk_check_wm_state_changed (window);
1065
1066 if (xevent->xproperty.atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
1067 cdk_check_wm_desktop_changed (window);
1068
1069 if (xevent->xproperty.atom == cdk_x11_get_xatom_by_name_for_display (display, "_CTK_EDGE_CONSTRAINTS"))
1070 cdk_check_edge_constraints_changed (window);
1071 }
1072
1073 if (window->event_mask & CDK_PROPERTY_CHANGE_MASK)
1074 {
1075 event->property.type = CDK_PROPERTY_NOTIFY;
1076 event->property.window = window;
1077 event->property.atom = cdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom);
1078 event->property.time = xevent->xproperty.time;
1079 event->property.state = xevent->xproperty.state;
1080 }
1081 else
1082 return_val = FALSE(0);
1083
1084 break;
1085
1086 case SelectionClear29:
1087 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection clear:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1088 g_message ("selection clear:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection clear:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1089 xevent->xproperty.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection clear:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
;
1090
1091 if (_cdk_x11_selection_filter_clear_event (&xevent->xselectionclear))
1092 {
1093 event->selection.type = CDK_SELECTION_CLEAR;
1094 event->selection.window = window;
1095 event->selection.selection = cdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
1096 event->selection.time = xevent->xselectionclear.time;
1097 }
1098 else
1099 return_val = FALSE(0);
1100
1101 break;
1102
1103 case SelectionRequest30:
1104 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection request:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1105 g_message ("selection request:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection request:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1106 xevent->xproperty.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection request:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
;
1107
1108 event->selection.type = CDK_SELECTION_REQUEST;
1109 event->selection.window = window;
1110 event->selection.selection = cdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
1111 event->selection.target = cdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
1112 if (xevent->xselectionrequest.property == None0L)
1113 event->selection.property = event->selection.target;
1114 else
1115 event->selection.property = cdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
1116 if (xevent->xselectionrequest.requestor != None0L)
1117 event->selection.requestor = cdk_x11_window_foreign_new_for_display (display,
1118 xevent->xselectionrequest.requestor);
1119 else
1120 event->selection.requestor = NULL((void*)0);
1121 event->selection.time = xevent->xselectionrequest.time;
1122
1123 break;
1124
1125 case SelectionNotify31:
1126 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection notify:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1127 g_message ("selection notify:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection notify:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
1128 xevent->xproperty.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("selection notify:\twindow: %ld", xevent->xproperty.window
); }; } while (0)
;
1129
1130 event->selection.type = CDK_SELECTION_NOTIFY;
1131 event->selection.window = window;
1132 event->selection.selection = cdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
1133 event->selection.target = cdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
1134 if (xevent->xselection.property == None0L)
1135 event->selection.property = event->selection.target;
1136 else
1137 event->selection.property = cdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
1138 event->selection.time = xevent->xselection.time;
1139
1140 break;
1141
1142 case ColormapNotify32:
1143 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("colormap notify:\twindow: %ld", xevent->xcolormap.window
); }; } while (0)
1144 g_message ("colormap notify:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("colormap notify:\twindow: %ld", xevent->xcolormap.window
); }; } while (0)
1145 xevent->xcolormap.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("colormap notify:\twindow: %ld", xevent->xcolormap.window
); }; } while (0)
;
1146
1147 /* Not currently handled */
1148 return_val = FALSE(0);
1149 break;
1150
1151 case ClientMessage33:
1152 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("client message:\twindow: %ld", xevent->xclient.window);
}; } while (0)
1153 g_message ("client message:\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("client message:\twindow: %ld", xevent->xclient.window);
}; } while (0)
1154 xevent->xclient.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("client message:\twindow: %ld", xevent->xclient.window);
}; } while (0)
;
1155
1156 /* Not currently handled */
1157 return_val = FALSE(0);
1158 break;
1159
1160 case MappingNotify34:
1161 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("mapping notify"); }; } while (0)
1162 g_message ("mapping notify"))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("mapping notify"); }; } while (0)
;
1163
1164 /* Let XLib know that there is a new keyboard mapping.
1165 */
1166 XRefreshKeyboardMapping (&xevent->xmapping);
1167 _cdk_x11_keymap_keys_changed (display);
1168 return_val = FALSE(0);
1169 break;
1170
1171 default:
1172#ifdef HAVE_XFIXES1
1173 if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify0)
1174 {
1175 XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
1176
1177 _cdk_x11_screen_process_owner_change (screen, xevent);
1178
1179 event->owner_change.type = CDK_OWNER_CHANGE;
1180 event->owner_change.window = window;
1181 if (selection_notify->owner != None0L)
1182 event->owner_change.owner = cdk_x11_window_foreign_new_for_display (display,
1183 selection_notify->owner);
1184 else
1185 event->owner_change.owner = NULL((void*)0);
1186 event->owner_change.reason = selection_notify->subtype;
1187 event->owner_change.selection =
1188 cdk_x11_xatom_to_atom_for_display (display,
1189 selection_notify->selection);
1190 event->owner_change.time = selection_notify->timestamp;
1191 event->owner_change.selection_time = selection_notify->selection_timestamp;
1192
1193 return_val = TRUE(!(0));
1194 }
1195 else
1196#endif
1197#ifdef HAVE_RANDR1
1198 if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify0 ||
1199 xevent->type - display_x11->xrandr_event_base == RRNotify1)
1200 {
1201 if (screen)
1202 _cdk_x11_screen_size_changed (screen, xevent);
1203 }
1204 else
1205#endif
1206#if defined(HAVE_XCOMPOSITE1) && defined (HAVE_XDAMAGE1) && defined (HAVE_XFIXES1)
1207 if (display_x11->have_xdamage && window && window->composited &&
1208 xevent->type == display_x11->xdamage_event_base + XDamageNotify0 &&
1209 ((XDamageNotifyEvent *) xevent)->damage == window_impl->damage)
1210 {
1211 XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
1212 XserverRegion repair;
1213 CdkRectangle rect;
1214 int x2, y2;
1215
1216 rect.x = window->x + damage_event->area.x / window_impl->window_scale;
1217 rect.y = window->y + damage_event->area.y / window_impl->window_scale;
1218
1219 x2 = (rect.x * window_impl->window_scale + damage_event->area.width + window_impl->window_scale -1) / window_impl->window_scale;
1220 y2 = (rect.y * window_impl->window_scale + damage_event->area.height + window_impl->window_scale -1) / window_impl->window_scale;
1221 rect.width = x2 - rect.x;
1222 rect.height = y2 - rect.y;
1223
1224 repair = XFixesCreateRegion (display_x11->xdisplay,
1225 &damage_event->area, 1);
1226 XDamageSubtract (display_x11->xdisplay,
1227 window_impl->damage,
1228 repair, None0L);
1229 XFixesDestroyRegion (display_x11->xdisplay, repair);
1230
1231 if (window->parent != NULL((void*)0))
1232 _cdk_x11_window_process_expose (window->parent,
1233 damage_event->serial, &rect);
1234
1235 return_val = TRUE(!(0));
1236 }
1237 else
1238#endif
1239#ifdef HAVE_XKB1
1240 if (xevent->type == display_x11->xkb_event_type)
1241 {
1242 XkbEvent *xkb_event = (XkbEvent *) xevent;
1243
1244 switch (xkb_event->any.xkb_type)
1245 {
1246 case XkbNewKeyboardNotify0:
1247 case XkbMapNotify1:
1248 _cdk_x11_keymap_keys_changed (display);
1249
1250 return_val = FALSE(0);
1251 break;
1252
1253 case XkbStateNotify2:
1254 _cdk_x11_keymap_state_changed (display, xevent);
1255 break;
1256 }
1257 }
1258 else
1259#endif
1260 return_val = FALSE(0);
1261 }
1262
1263 done:
1264 if (return_val)
1265 {
1266 if (event->any.window)
1267 g_object_ref (event->any.window)((__typeof__ (event->any.window)) (g_object_ref) (event->
any.window))
;
1268 }
1269 else
1270 {
1271 /* Mark this event as having no resources to be freed */
1272 event->any.window = NULL((void*)0);
1273 event->any.type = CDK_NOTHING;
1274 }
1275
1276 if (window)
1277 g_object_unref (window);
1278
1279 return return_val;
1280}
1281
1282static CdkFrameTimings *
1283find_frame_timings (CdkFrameClock *clock,
1284 guint64 serial)
1285{
1286 gint64 start_frame, end_frame, i;
1287
1288 start_frame = cdk_frame_clock_get_history_start (clock);
1289 end_frame = cdk_frame_clock_get_frame_counter (clock);
1290 for (i = end_frame; i >= start_frame; i--)
1291 {
1292 CdkFrameTimings *timings = cdk_frame_clock_get_timings (clock, i);
1293
1294 if (timings->cookie == serial)
1295 return timings;
1296 }
1297
1298 return NULL((void*)0);
1299}
1300
1301/* _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages represent time
1302 * as a "high resolution server time" - this is the server time interpolated
1303 * to microsecond resolution. The advantage of this time representation
1304 * is that if X server is running on the same computer as a client, and
1305 * the Xserver uses 'clock_gettime(CLOCK_MONOTONIC, ...)' for the server
1306 * time, the client can detect this, and all such clients will share a
1307 * a time representation with high accuracy. If there is not a common
1308 * time source, then the time synchronization will be less accurate.
1309 */
1310gint64
1311server_time_to_monotonic_time (CdkX11Display *display_x11,
1312 gint64 server_time)
1313{
1314 if (display_x11->server_time_query_time == 0 ||
1315 (!display_x11->server_time_is_monotonic_time &&
1316 server_time > display_x11->server_time_query_time + 10*1000*1000)) /* 10 seconds */
1317 {
1318 gint64 current_server_time = cdk_x11_get_server_time (display_x11->leader_cdk_window);
1319 gint64 current_server_time_usec = (gint64)current_server_time * 1000;
1320 gint64 current_monotonic_time = g_get_monotonic_time ();
1321 display_x11->server_time_query_time = current_monotonic_time;
1322
1323 /* If the server time is within a second of the monotonic time,
1324 * we assume that they are identical. This seems like a big margin,
1325 * but we want to be as robust as possible even if the system
1326 * is under load and our processing of the server response is
1327 * delayed.
1328 */
1329 if (current_server_time_usec > current_monotonic_time - 1000*1000 &&
1330 current_server_time_usec < current_monotonic_time + 1000*1000)
1331 display_x11->server_time_is_monotonic_time = TRUE(!(0));
1332
1333 display_x11->server_time_offset = current_server_time_usec - current_monotonic_time;
1334 }
1335
1336 if (display_x11->server_time_is_monotonic_time)
1337 return server_time;
1338 else
1339 return server_time - display_x11->server_time_offset;
1340}
1341
1342CdkFilterReturn
1343_cdk_wm_protocols_filter (CdkXEvent *xev,
1344 CdkEvent *event,
1345 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
1346{
1347 XEvent *xevent = (XEvent *)xev;
1348 CdkWindow *win = event->any.window;
1349 CdkDisplay *display;
1350 Atom atom;
1351
1352 if (!CDK_IS_X11_WINDOW (win)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(win)); GType __t = ((cdk_x11_window_get_type ())); gboolean __r
; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
|| CDK_WINDOW_DESTROYED (win)(((CdkWindow *)(win))->destroyed))
1353 return CDK_FILTER_CONTINUE;
1354
1355 if (xevent->type != ClientMessage33)
1356 return CDK_FILTER_CONTINUE;
1357
1358 display = CDK_WINDOW_DISPLAY (win)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (win)))), ((cdk_x11_screen_get_type
()))))))->display)
;
1359
1360 /* This isn't actually WM_PROTOCOLS because that wouldn't leave enough space
1361 * in the message for everything that gets stuffed in */
1362 if (xevent->xclient.message_type == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_FRAME_DRAWN"))
1363 {
1364 CdkWindowImplX11 *window_impl;
1365 window_impl = CDK_WINDOW_IMPL_X11 (win->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((win->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1366 if (window_impl->toplevel)
1367 {
1368 guint32 d0 = xevent->xclient.data.l[0];
1369 guint32 d1 = xevent->xclient.data.l[1];
1370 guint32 d2 = xevent->xclient.data.l[2];
1371 guint32 d3 = xevent->xclient.data.l[3];
1372
1373 guint64 serial = ((guint64)d1 << 32) | d0;
1374 gint64 frame_drawn_time = server_time_to_monotonic_time (CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
, ((guint64)d3 << 32) | d2);
1375 gint64 refresh_interval, presentation_time;
1376
1377 CdkFrameClock *clock = cdk_window_get_frame_clock (win);
1378 CdkFrameTimings *timings = find_frame_timings (clock, serial);
1379
1380 if (timings)
1381 timings->drawn_time = frame_drawn_time;
1382
1383 if (window_impl->toplevel->frame_pending)
1384 {
1385 window_impl->toplevel->frame_pending = FALSE(0);
1386 _cdk_frame_clock_thaw (clock);
1387 }
1388
1389 cdk_frame_clock_get_refresh_info (clock,
1390 frame_drawn_time,
1391 &refresh_interval,
1392 &presentation_time);
1393 if (presentation_time != 0)
1394 window_impl->toplevel->throttled_presentation_time = presentation_time + refresh_interval;
1395 }
1396
1397 return CDK_FILTER_REMOVE;
1398 }
1399
1400 if (xevent->xclient.message_type == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_FRAME_TIMINGS"))
1401 {
1402 CdkWindowImplX11 *window_impl;
1403 window_impl = CDK_WINDOW_IMPL_X11 (win->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((win->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1404 if (window_impl->toplevel)
1405 {
1406 guint32 d0 = xevent->xclient.data.l[0];
1407 guint32 d1 = xevent->xclient.data.l[1];
1408 guint32 d2 = xevent->xclient.data.l[2];
1409 guint32 d3 = xevent->xclient.data.l[3];
1410
1411 guint64 serial = ((guint64)d1 << 32) | d0;
1412
1413 CdkFrameClock *clock = cdk_window_get_frame_clock (win);
1414 CdkFrameTimings *timings = find_frame_timings (clock, serial);
1415
1416 if (timings)
1417 {
1418 gint32 presentation_time_offset = (gint32)d2;
1419 gint32 refresh_interval = d3;
1420
1421 if (timings->drawn_time && presentation_time_offset)
1422 timings->presentation_time = timings->drawn_time + presentation_time_offset;
1423
1424 if (refresh_interval)
1425 timings->refresh_interval = refresh_interval;
1426
1427 timings->complete = TRUE(!(0));
1428#ifdef G_ENABLE_DEBUG1
1429 if (CDK_DEBUG_CHECK (FRAMES)(_cdk_debug_flags & CDK_DEBUG_FRAMES))
1430 _cdk_frame_clock_debug_print_timings (clock, timings);
1431
1432 if (cdk_profiler_is_running ())
1433 _cdk_frame_clock_add_timings_to_profiler (clock, timings);
1434#endif /* G_ENABLE_DEBUG */
1435 }
1436 }
1437 }
1438
1439 if (xevent->xclient.message_type != cdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS"))
1440 return CDK_FILTER_CONTINUE;
1441
1442 atom = (Atom) xevent->xclient.data.l[0];
1443
1444 if (atom == cdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
1445 {
1446 /* The delete window request specifies a window
1447 * to delete. We don't actually destroy the
1448 * window because "it is only a request". (The
1449 * window might contain vital data that the
1450 * program does not want destroyed). Instead
1451 * the event is passed along to the program,
1452 * which should then destroy the window.
1453 */
1454 CDK_NOTE (EVENTS,do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("delete window:\t\twindow: %ld", xevent->xclient.window)
; }; } while (0)
1455 g_message ("delete window:\t\twindow: %ld",do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("delete window:\t\twindow: %ld", xevent->xclient.window)
; }; } while (0)
1456 xevent->xclient.window))do { if ((_cdk_debug_flags & CDK_DEBUG_EVENTS)) { g_message
("delete window:\t\twindow: %ld", xevent->xclient.window)
; }; } while (0)
;
1457
1458 event->any.type = CDK_DELETE;
1459
1460 cdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]);
1461
1462 return CDK_FILTER_TRANSLATE;
1463 }
1464 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
1465 {
1466 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (win);
1467
1468 /* There is no way of knowing reliably whether we are viewable;
1469 * so trap errors asynchronously around the XSetInputFocus call
1470 */
1471 if (toplevel && win->accept_focus)
1472 {
1473 cdk_x11_display_error_trap_push (display);
1474 XSetInputFocus (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
1475 toplevel->focus_window,
1476 RevertToParent2,
1477 xevent->xclient.data.l[1]);
1478 cdk_x11_display_error_trap_pop_ignored (display);
1479 }
1480
1481 return CDK_FILTER_REMOVE;
1482 }
1483 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
1484 !_cdk_x11_display_is_root_window (display,
1485 xevent->xclient.window))
1486 {
1487 XClientMessageEvent xclient = xevent->xclient;
1488
1489 xclient.window = CDK_WINDOW_XROOTWIN (win)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (win)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
;
1490 XSendEvent (CDK_WINDOW_XDISPLAY (win)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (win)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1491 xclient.window,
1492 False0,
1493 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19), (XEvent *)&xclient);
1494
1495 return CDK_FILTER_REMOVE;
1496 }
1497 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
1498 CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->use_sync)
1499 {
1500 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (win);
1501 if (toplevel)
1502 {
1503#ifdef HAVE_XSYNC1
1504 toplevel->pending_counter_value = xevent->xclient.data.l[2] + ((gint64)xevent->xclient.data.l[3] << 32);
1505 toplevel->pending_counter_value_is_extended = xevent->xclient.data.l[4] != 0;
1506#endif
1507 }
1508 return CDK_FILTER_REMOVE;
1509 }
1510
1511 return CDK_FILTER_CONTINUE;
1512}
1513
1514static void
1515cdk_event_init (CdkDisplay *display)
1516{
1517 CdkX11Display *display_x11;
1518 CdkDeviceManager *device_manager;
1519
1520 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1521 display_x11->event_source = cdk_x11_event_source_new (display);
1522
1523 cdk_x11_event_source_add_translator ((CdkEventSource *) display_x11->event_source,
1524 CDK_EVENT_TRANSLATOR (display)((((CdkEventTranslator*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((_cdk_x11_event_translator_get_type
()))))))
);
1525
1526 G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
;
1527 device_manager = cdk_display_get_device_manager (display);
1528 cdk_x11_event_source_add_translator ((CdkEventSource *) display_x11->event_source,
1529 CDK_EVENT_TRANSLATOR (device_manager)((((CdkEventTranslator*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((device_manager)), ((_cdk_x11_event_translator_get_type
()))))))
);
1530 G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ;
1531}
1532
1533static void
1534set_sm_client_id (CdkDisplay *display,
1535 const gchar *sm_client_id)
1536{
1537 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1538
1539 if (cdk_display_is_closed (display))
1540 return;
1541
1542 if (sm_client_id && strcmp (sm_client_id, ""))
1543 XChangeProperty (display_x11->xdisplay, display_x11->leader_window,
1544 cdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"),
1545 XA_STRING((Atom) 31), 8, PropModeReplace0, (guchar *)sm_client_id,
1546 strlen (sm_client_id));
1547 else
1548 XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
1549 cdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
1550}
1551
1552CdkDisplay *
1553_cdk_x11_display_open (const gchar *display_name)
1554{
1555 Display *xdisplay;
1556 CdkDisplay *display;
1557 CdkX11Display *display_x11;
1558 CdkWindowAttr attr;
1559 gint argc;
1560 gchar *argv[1];
1561
1562 XClassHint *class_hint;
1563 gint ignore;
1564 gint maj, min;
1565
1566 xdisplay = XOpenDisplay (display_name);
1567 if (!xdisplay)
1568 return NULL((void*)0);
1569
1570 display = g_object_new (CDK_TYPE_X11_DISPLAY(cdk_x11_display_get_type()), NULL((void*)0));
1571 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1572
1573 display_x11->xdisplay = xdisplay;
1574
1575 /* Set up handlers for Xlib internal connections */
1576 XAddConnectionWatch (xdisplay, cdk_internal_connection_watch, NULL((void*)0));
1577
1578 _cdk_x11_precache_atoms (display, precache_atoms, G_N_ELEMENTS (precache_atoms)(sizeof (precache_atoms) / sizeof ((precache_atoms)[0])));
1579
1580 /* RandR must be initialized before we initialize the screens */
1581 display_x11->have_randr12 = FALSE(0);
1582 display_x11->have_randr13 = FALSE(0);
1583 display_x11->have_randr15 = FALSE(0);
1584#ifdef HAVE_RANDR1
1585 if (XRRQueryExtension (display_x11->xdisplay,
1586 &display_x11->xrandr_event_base, &ignore))
1587 {
1588 int major, minor;
1589
1590 XRRQueryVersion (display_x11->xdisplay, &major, &minor);
1591
1592 if ((major == 1 && minor >= 2) || major > 1) {
1593 display_x11->have_randr12 = TRUE(!(0));
1594 if (minor >= 3 || major > 1)
1595 display_x11->have_randr13 = TRUE(!(0));
1596#ifdef HAVE_RANDR151
1597 if (minor >= 5 || major > 1)
1598 display_x11->have_randr15 = TRUE(!(0));
1599#endif
1600 }
1601
1602 cdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents2);
1603 }
1604#endif
1605
1606 /* initialize the display's screens */
1607 display_x11->screen = _cdk_x11_screen_new (display, DefaultScreen (display_x11->xdisplay)(((_XPrivDisplay)(display_x11->xdisplay))->default_screen
)
);
1608
1609 /* We need to initialize events after we have the screen
1610 * structures in places
1611 */
1612 _cdk_x11_xsettings_init (CDK_X11_SCREEN (display_x11->screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11->screen)), ((cdk_x11_screen_get_type ()))
))))
);
1613
1614 display->device_manager = _cdk_x11_device_manager_new (display);
1615
1616 cdk_event_init (display);
1617
1618 attr.window_type = CDK_WINDOW_TOPLEVEL;
1619 attr.wclass = CDK_INPUT_ONLY;
1620 attr.x = 10;
1621 attr.y = 10;
1622 attr.width = 10;
1623 attr.height = 10;
1624 attr.event_mask = 0;
1625
1626 display_x11->leader_cdk_window = cdk_window_new (CDK_X11_SCREEN (display_x11->screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11->screen)), ((cdk_x11_screen_get_type ()))
))))
->root_window,
1627 &attr, CDK_WA_X | CDK_WA_Y);
1628 (_cdk_x11_window_get_toplevel (display_x11->leader_cdk_window))->is_leader = TRUE(!(0));
1629
1630 display_x11->leader_window = CDK_WINDOW_XID (display_x11->leader_cdk_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display_x11->leader_cdk_window)), ((cdk_window_get_type
()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))
->xid)
;
1631
1632 display_x11->leader_window_title_set = FALSE(0);
1633
1634#ifdef HAVE_XFIXES1
1635 if (XFixesQueryExtension (display_x11->xdisplay,
1636 &display_x11->xfixes_event_base,
1637 &ignore))
1638 {
1639 display_x11->have_xfixes = TRUE(!(0));
1640
1641 cdk_x11_register_standard_event_type (display,
1642 display_x11->xfixes_event_base,
1643 XFixesNumberEvents(2));
1644 }
1645 else
1646#endif
1647 display_x11->have_xfixes = FALSE(0);
1648
1649#ifdef HAVE_XCOMPOSITE1
1650 if (XCompositeQueryExtension (display_x11->xdisplay,
1651 &ignore, &ignore))
1652 {
1653 int major, minor;
1654
1655 XCompositeQueryVersion (display_x11->xdisplay, &major, &minor);
1656
1657 /* Prior to Composite version 0.4, composited windows clipped their
1658 * parents, so you had to use IncludeInferiors to draw to the parent
1659 * This isn't useful for our purposes, so require 0.4
1660 */
1661 display_x11->have_xcomposite = major > 0 || (major == 0 && minor >= 4);
1662 }
1663 else
1664#endif
1665 display_x11->have_xcomposite = FALSE(0);
1666
1667#ifdef HAVE_XDAMAGE1
1668 if (XDamageQueryExtension (display_x11->xdisplay,
1669 &display_x11->xdamage_event_base,
1670 &ignore))
1671 {
1672 display_x11->have_xdamage = TRUE(!(0));
1673
1674 cdk_x11_register_standard_event_type (display,
1675 display_x11->xdamage_event_base,
1676 XDamageNumberEvents(0 + 1));
1677 }
1678 else
1679#endif
1680 display_x11->have_xdamage = FALSE(0);
1681
1682 display_x11->have_shapes = FALSE(0);
1683 display_x11->have_input_shapes = FALSE(0);
1684
1685 if (XShapeQueryExtension (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, &display_x11->shape_event_base, &ignore))
1686 {
1687 display_x11->have_shapes = TRUE(!(0));
1688#ifdef ShapeInput2
1689 if (XShapeQueryVersion (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, &maj, &min))
1690 display_x11->have_input_shapes = (maj == 1 && min >= 1);
1691#endif
1692 }
1693
1694 display_x11->trusted_client = TRUE(!(0));
1695 {
1696 Window root, child;
1697 int rootx, rooty, winx, winy;
1698 unsigned int xmask;
1699
1700 cdk_x11_display_error_trap_push (display);
1701 XQueryPointer (display_x11->xdisplay,
1702 CDK_X11_SCREEN (display_x11->screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11->screen)), ((cdk_x11_screen_get_type ()))
))))
->xroot_window,
1703 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
1704 if (G_UNLIKELY (cdk_x11_display_error_trap_pop (display) == BadWindow)(cdk_x11_display_error_trap_pop (display) == 3))
1705 {
1706 g_warning ("Connection to display %s appears to be untrusted. Pointer and keyboard grabs and inter-client communication may not work as expected.", cdk_display_get_name (display));
1707 display_x11->trusted_client = FALSE(0);
1708 }
1709 }
1710
1711 if (g_getenv ("CDK_SYNCHRONIZE"))
1712 XSynchronize (display_x11->xdisplay, True1);
1713
1714 class_hint = XAllocClassHint();
1715 class_hint->res_name = (char *) g_get_prgname ();
1716 class_hint->res_class = (char *)cdk_get_program_class ();
1717
1718 /* XmbSetWMProperties sets the RESOURCE_NAME environment variable
1719 * from argv[0], so we just synthesize an argument array here.
1720 */
1721 argc = 1;
1722 argv[0] = (char *) g_get_prgname ();
1723
1724 XmbSetWMProperties (display_x11->xdisplay,
1725 display_x11->leader_window,
1726 NULL((void*)0), NULL((void*)0), argv, argc, NULL((void*)0), NULL((void*)0),
1727 class_hint);
1728 XFree (class_hint);
1729
1730 if (cdk_sm_client_id)
1731 set_sm_client_id (display, cdk_sm_client_id);
1732
1733 if (!cdk_running_in_sandbox ())
1734 {
1735 /* if sandboxed, we're likely in a pid namespace and would only confuse the wm with this */
1736 long pid = getpid ();
1737 XChangeProperty (display_x11->xdisplay,
1738 display_x11->leader_window,
1739 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
1740 XA_CARDINAL((Atom) 6), 32, PropModeReplace0, (guchar *) & pid, 1);
1741 }
1742
1743 /* We don't yet know a valid time. */
1744 display_x11->user_time = 0;
1745
1746#ifdef HAVE_XKB1
1747 {
1748 gint xkb_major = XkbMajorVersion1;
1749 gint xkb_minor = XkbMinorVersion0;
1750 if (XkbLibraryVersion (&xkb_major, &xkb_minor))
1751 {
1752 xkb_major = XkbMajorVersion1;
1753 xkb_minor = XkbMinorVersion0;
1754
1755 if (XkbQueryExtension (display_x11->xdisplay,
1756 NULL((void*)0), &display_x11->xkb_event_type, NULL((void*)0),
1757 &xkb_major, &xkb_minor))
1758 {
1759 Boolint detectable_autorepeat_supported;
1760
1761 display_x11->use_xkb = TRUE(!(0));
1762
1763 XkbSelectEvents (display_x11->xdisplay,
1764 XkbUseCoreKbd0x0100,
1765 XkbNewKeyboardNotifyMask(1L << 0) | XkbMapNotifyMask(1L << 1) | XkbStateNotifyMask(1L << 2),
1766 XkbNewKeyboardNotifyMask(1L << 0) | XkbMapNotifyMask(1L << 1) | XkbStateNotifyMask(1L << 2));
1767
1768 /* keep this in sync with _cdk_x11_keymap_state_changed() */
1769 XkbSelectEventDetails (display_x11->xdisplay,
1770 XkbUseCoreKbd0x0100, XkbStateNotify2,
1771 XkbAllStateComponentsMask(0x3fff),
1772 XkbModifierStateMask(1L << 0)|XkbGroupStateMask(1L << 4));
1773
1774 XkbSetDetectableAutoRepeat (display_x11->xdisplay,
1775 True1,
1776 &detectable_autorepeat_supported);
1777
1778 CDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("Detectable autorepeat %s.", detectable_autorepeat_supported
? "supported" : "not supported"); }; } while (0)
1779 detectable_autorepeat_supported ?do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("Detectable autorepeat %s.", detectable_autorepeat_supported
? "supported" : "not supported"); }; } while (0)
1780 "supported" : "not supported"))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("Detectable autorepeat %s.", detectable_autorepeat_supported
? "supported" : "not supported"); }; } while (0)
;
1781
1782 display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
1783 }
1784 }
1785 }
1786#endif
1787
1788 display_x11->use_sync = FALSE(0);
1789#ifdef HAVE_XSYNC1
1790 {
1791 int major, minor;
1792 int error_base, event_base;
1793
1794 if (XSyncQueryExtension (display_x11->xdisplay,
1795 &event_base, &error_base) &&
1796 XSyncInitialize (display_x11->xdisplay,
1797 &major, &minor))
1798 display_x11->use_sync = TRUE(!(0));
1799 }
1800#endif
1801
1802 _cdk_x11_screen_setup (display_x11->screen);
1803
1804 g_signal_emit_by_name (display, "opened");
1805
1806 return display;
1807}
1808
1809/*
1810 * XLib internal connection handling
1811 */
1812typedef struct _CdkInternalConnection CdkInternalConnection;
1813
1814struct _CdkInternalConnection
1815{
1816 gint fd;
1817 GSource *source;
1818 Display *display;
1819};
1820
1821static gboolean
1822process_internal_connection (GIOChannel *gioc G_GNUC_UNUSED__attribute__ ((__unused__)),
1823 GIOCondition cond G_GNUC_UNUSED__attribute__ ((__unused__)),
1824 gpointer data)
1825{
1826 CdkInternalConnection *connection = (CdkInternalConnection *)data;
1827
1828 cdk_threads_enter ();
1829
1830 XProcessInternalConnection ((Display*)connection->display, connection->fd);
1831
1832 cdk_threads_leave ();
1833
1834 return TRUE(!(0));
1835}
1836
1837static gulong
1838cdk_x11_display_get_next_serial (CdkDisplay *display)
1839{
1840 return NextRequest (CDK_DISPLAY_XDISPLAY (display))(((_XPrivDisplay)((((((CdkX11Display*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display)), ((cdk_x11_display_get_type())
)))))->xdisplay)))->request + 1)
;
1841}
1842
1843
1844static CdkInternalConnection *
1845cdk_add_connection_handler (Display *display,
1846 guint fd)
1847{
1848 GIOChannel *io_channel;
1849 CdkInternalConnection *connection;
1850
1851 connection = g_new (CdkInternalConnection, 1)((CdkInternalConnection *) g_malloc_n ((1), sizeof (CdkInternalConnection
)))
;
1852
1853 connection->fd = fd;
1854 connection->display = display;
1855
1856 io_channel = g_io_channel_unix_new (fd);
1857
1858 connection->source = g_io_create_watch (io_channel, G_IO_IN);
1859 g_source_set_callback (connection->source,
1860 (GSourceFunc)process_internal_connection, connection, NULL((void*)0));
1861 g_source_attach (connection->source, NULL((void*)0));
1862
1863 g_io_channel_unref (io_channel);
1864
1865 return connection;
1866}
1867
1868static void
1869cdk_remove_connection_handler (CdkInternalConnection *connection)
1870{
1871 g_source_destroy (connection->source);
1872 g_free (connection);
1873}
1874
1875static void
1876cdk_internal_connection_watch (Display *display,
1877 XPointer arg G_GNUC_UNUSED__attribute__ ((__unused__)),
1878 gint fd,
1879 gboolean opening,
1880 XPointer *watch_data)
1881{
1882 if (opening)
1883 *watch_data = (XPointer)cdk_add_connection_handler (display, fd);
1884 else
1885 cdk_remove_connection_handler ((CdkInternalConnection *)*watch_data);
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
1886}
1887
1888static const gchar *
1889cdk_x11_display_get_name (CdkDisplay *display)
1890{
1891 return (gchar *) DisplayString (CDK_X11_DISPLAY (display)->xdisplay)(((_XPrivDisplay)(((((CdkX11Display*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display)), ((cdk_x11_display_get_type())
)))))->xdisplay))->display_name)
;
1892}
1893
1894static CdkScreen *
1895cdk_x11_display_get_default_screen (CdkDisplay *display)
1896{
1897 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->screen;
1898}
1899
1900gboolean
1901_cdk_x11_display_is_root_window (CdkDisplay *display,
1902 Window xroot_window)
1903{
1904 CdkX11Display *display_x11;
1905
1906 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1907
1908 return CDK_SCREEN_XROOTWIN (display_x11->screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11->screen)), ((cdk_x11_screen_get_type ()))
))))->xroot_window)
== xroot_window;
1909}
1910
1911struct XPointerUngrabInfo {
1912 CdkDisplay *display;
1913 guint32 time;
1914};
1915
1916static void
1917device_grab_update_callback (CdkDisplay *display,
1918 gpointer data,
1919 gulong serial)
1920{
1921 CdkPointerWindowInfo *pointer_info;
1922 CdkDevice *device = data;
1923
1924 pointer_info = _cdk_display_get_pointer_info (display, device);
1925 _cdk_display_device_grab_update (display, device,
1926 pointer_info->last_slave ? pointer_info->last_slave : device,
1927 serial);
1928}
1929
1930#define XSERVER_TIME_IS_LATER(time1, time2)( (( time1 > time2 ) && ( time1 - time2 < ((guint32
)-1)/2 )) || (( time1 < time2 ) && ( time2 - time1
> ((guint32)-1)/2 )) )
\
1931 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
1932 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
1933 )
1934
1935void
1936_cdk_x11_display_update_grab_info (CdkDisplay *display,
1937 CdkDevice *device,
1938 gint status)
1939{
1940 if (status == GrabSuccess0)
1941 _cdk_x11_roundtrip_async (display, device_grab_update_callback, device);
1942}
1943
1944void
1945_cdk_x11_display_update_grab_info_ungrab (CdkDisplay *display,
1946 CdkDevice *device,
1947 guint32 time,
1948 gulong serial)
1949{
1950 CdkDeviceGrabInfo *grab;
1951
1952 XFlush (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
);
1953
1954 grab = _cdk_display_get_last_device_grab (display, device);
1955 if (grab &&
1956 (time == CDK_CURRENT_TIME0L ||
1957 grab->time == CDK_CURRENT_TIME0L ||
1958 !XSERVER_TIME_IS_LATER (grab->time, time)( (( grab->time > time ) && ( grab->time - time
< ((guint32)-1)/2 )) || (( grab->time < time ) &&
( time - grab->time > ((guint32)-1)/2 )) )
))
1959 {
1960 grab->serial_end = serial;
1961 _cdk_x11_roundtrip_async (display, device_grab_update_callback, device);
1962 }
1963}
1964
1965static void
1966cdk_x11_display_beep (CdkDisplay *display)
1967{
1968 if (!CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->trusted_client)
1969 return;
1970
1971#ifdef HAVE_XKB1
1972 XkbBell (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, None0L, 0, None0L);
1973#else
1974 XBell (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, 0);
1975#endif
1976}
1977
1978static void
1979cdk_x11_display_sync (CdkDisplay *display)
1980{
1981 XSync (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, False0);
1982}
1983
1984static void
1985cdk_x11_display_flush (CdkDisplay *display)
1986{
1987 if (!display->closed)
1988 XFlush (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
);
1989}
1990
1991static gboolean
1992cdk_x11_display_has_pending (CdkDisplay *display)
1993{
1994 return XPending (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
);
1995}
1996
1997static CdkWindow *
1998cdk_x11_display_get_default_group (CdkDisplay *display)
1999{
2000 g_return_val_if_fail (CDK_IS_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_DISPLAY (display)"); return (((void*)0)); } } while
(0)
;
2001
2002 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->leader_cdk_window;
2003}
2004
2005/**
2006 * cdk_x11_display_grab:
2007 * @display: (type CdkX11Display): a #CdkDisplay
2008 *
2009 * Call XGrabServer() on @display.
2010 * To ungrab the display again, use cdk_x11_display_ungrab().
2011 *
2012 * cdk_x11_display_grab()/cdk_x11_display_ungrab() calls can be nested.
2013 *
2014 * Since: 2.2
2015 **/
2016void
2017cdk_x11_display_grab (CdkDisplay *display)
2018{
2019 CdkX11Display *display_x11;
2020
2021 g_return_if_fail (CDK_IS_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_DISPLAY (display)"); return; } } while (0)
;
2022
2023 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2024
2025 if (display_x11->grab_count == 0)
2026 XGrabServer (display_x11->xdisplay);
2027 display_x11->grab_count++;
2028}
2029
2030/**
2031 * cdk_x11_display_ungrab:
2032 * @display: (type CdkX11Display): a #CdkDisplay
2033 *
2034 * Ungrab @display after it has been grabbed with
2035 * cdk_x11_display_grab().
2036 *
2037 * Since: 2.2
2038 **/
2039void
2040cdk_x11_display_ungrab (CdkDisplay *display)
2041{
2042 CdkX11Display *display_x11;
2043
2044 g_return_if_fail (CDK_IS_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_DISPLAY (display)"); return; } } while (0)
;
2045
2046 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;;
2047 g_return_if_fail (display_x11->grab_count > 0)do { if ((display_x11->grab_count > 0)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "display_x11->grab_count > 0"
); return; } } while (0)
;
2048
2049 display_x11->grab_count--;
2050 if (display_x11->grab_count == 0)
2051 {
2052 XUngrabServer (display_x11->xdisplay);
2053 XFlush (display_x11->xdisplay);
2054 }
2055}
2056
2057static void
2058cdk_x11_display_dispose (GObject *object)
2059{
2060 CdkX11Display *display_x11 = CDK_X11_DISPLAY (object)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((cdk_x11_display_get_type()))))))
;
2061
2062 _cdk_screen_close (display_x11->screen);
2063
2064 if (display_x11->event_source)
2065 {
2066 g_source_destroy (display_x11->event_source);
2067 g_source_unref (display_x11->event_source);
2068 display_x11->event_source = NULL((void*)0);
2069 }
2070
2071 G_OBJECT_CLASS (cdk_x11_display_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((cdk_x11_display_parent_class)), (((GType) ((20) <<
(2))))))))
->dispose (object);
2072}
2073
2074static void
2075cdk_x11_display_finalize (GObject *object)
2076{
2077 CdkX11Display *display_x11 = CDK_X11_DISPLAY (object)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((cdk_x11_display_get_type()))))))
;
2078
2079 /* Keymap */
2080 if (display_x11->keymap)
2081 g_object_unref (display_x11->keymap);
2082
2083 _cdk_x11_cursor_display_finalize (CDK_DISPLAY (display_x11)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11)), ((cdk_display_get_type ()))))))
);
2084
2085 /* Empty the event queue */
2086 _cdk_x11_display_free_translate_queue (CDK_DISPLAY (display_x11)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_x11)), ((cdk_display_get_type ()))))))
);
2087
2088 /* Atom Hashtable */
2089 g_hash_table_destroy (display_x11->atom_from_virtual);
2090 g_hash_table_destroy (display_x11->atom_to_virtual);
2091
2092 /* Leader Window */
2093 XDestroyWindow (display_x11->xdisplay, display_x11->leader_window);
2094
2095 /* List of event window extraction functions */
2096 g_slist_free_full (display_x11->event_types, g_free);
2097
2098 /* input CdkWindow list */
2099 g_list_free_full (display_x11->input_windows, g_free);
2100
2101 /* Free all CdkScreens */
2102 g_object_unref (display_x11->screen);
2103 g_list_free_full (display_x11->screens, g_object_unref);
2104
2105 g_ptr_array_free (display_x11->monitors, TRUE(!(0)));
2106
2107 g_free (display_x11->startup_notification_id);
2108
2109 /* X ID hashtable */
2110 g_hash_table_destroy (display_x11->xid_ht);
2111
2112 XCloseDisplay (display_x11->xdisplay);
2113
2114 /* error traps */
2115 while (display_x11->error_traps != NULL((void*)0))
2116 {
2117 CdkErrorTrap *trap = display_x11->error_traps->data;
2118
2119 display_x11->error_traps =
2120 g_slist_delete_link (display_x11->error_traps,
2121 display_x11->error_traps);
2122
2123 if (trap->end_sequence == 0)
2124 g_warning ("Display finalized with an unpopped error trap");
2125
2126 g_slice_free (CdkErrorTrap, trap)do { if (1) g_slice_free1 (sizeof (CdkErrorTrap), (trap)); else
(void) ((CdkErrorTrap*) 0 == (trap)); } while (0)
;
2127 }
2128
2129 G_OBJECT_CLASS (cdk_x11_display_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((cdk_x11_display_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
2130}
2131
2132/**
2133 * cdk_x11_lookup_xdisplay:
2134 * @xdisplay: a pointer to an X Display
2135 *
2136 * Find the #CdkDisplay corresponding to @xdisplay, if any exists.
2137 *
2138 * Returns: (transfer none) (type CdkX11Display): the #CdkDisplay, if found, otherwise %NULL.
2139 *
2140 * Since: 2.2
2141 **/
2142CdkDisplay *
2143cdk_x11_lookup_xdisplay (Display *xdisplay)
2144{
2145 GSList *list, *l;
2146 CdkDisplay *display;
2147
2148 display = NULL((void*)0);
2149
2150 list = cdk_display_manager_list_displays (cdk_display_manager_get ());
2151
2152 for (l = list; l; l = l->next)
2153 {
2154 if (CDK_IS_X11_DISPLAY (l->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(l->data)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
&&
2155 CDK_DISPLAY_XDISPLAY (l->data)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((l->data)), ((cdk_x11_display_get_type()))))))->xdisplay
)
== xdisplay)
2156 {
2157 display = l->data;
2158 break;
2159 }
2160 }
2161
2162 g_slist_free (list);
2163
2164 return display;
2165}
2166
2167/**
2168 * _cdk_x11_display_screen_for_xrootwin:
2169 * @display: a #CdkDisplay
2170 * @xrootwin: window ID for one of of the screen’s of the display.
2171 *
2172 * Given the root window ID of one of the screen’s of a #CdkDisplay,
2173 * finds the screen.
2174 *
2175 * Returns: (transfer none): the #CdkScreen corresponding to
2176 * @xrootwin, or %NULL.
2177 **/
2178CdkScreen *
2179_cdk_x11_display_screen_for_xrootwin (CdkDisplay *display,
2180 Window xrootwin)
2181{
2182 CdkScreen *screen;
2183 XWindowAttributes attrs;
2184 gboolean result;
2185 CdkX11Display *display_x11;
2186 GList *l;
2187
2188 screen = cdk_display_get_default_screen (display);
2189
2190 if (CDK_SCREEN_XROOTWIN (screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))->xroot_window
)
== xrootwin)
2191 return screen;
2192
2193 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2194
2195 for (l = display_x11->screens; l; l = l->next)
2196 {
2197 screen = l->data;
2198 if (CDK_SCREEN_XROOTWIN (screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))->xroot_window
)
== xrootwin)
2199 return screen;
2200 }
2201
2202 cdk_x11_display_error_trap_push (display);
2203 result = XGetWindowAttributes (display_x11->xdisplay, xrootwin, &attrs);
2204 if (cdk_x11_display_error_trap_pop (display) || !result)
2205 return NULL((void*)0);
2206
2207 screen = _cdk_x11_screen_new (display, XScreenNumberOfScreen (attrs.screen));
2208
2209 display_x11->screens = g_list_prepend (display_x11->screens, screen);
2210
2211 return screen;
2212}
2213
2214/**
2215 * cdk_x11_display_get_xdisplay:
2216 * @display: (type CdkX11Display): a #CdkDisplay
2217 *
2218 * Returns the X display of a #CdkDisplay.
2219 *
2220 * Returns: (transfer none): an X display
2221 *
2222 * Since: 2.2
2223 */
2224Display *
2225cdk_x11_display_get_xdisplay (CdkDisplay *display)
2226{
2227 g_return_val_if_fail (CDK_IS_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_DISPLAY (display)"); return (((void*)0)); } } while
(0)
;
2228 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->xdisplay;
2229}
2230
2231static void
2232cdk_x11_display_make_default (CdkDisplay *display)
2233{
2234 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2235 const gchar *startup_id;
2236
2237 g_free (display_x11->startup_notification_id);
2238 display_x11->startup_notification_id = NULL((void*)0);
2239
2240 startup_id = cdk_get_desktop_startup_id ();
2241 if (startup_id)
2242 cdk_x11_display_set_startup_notification_id (display, startup_id);
2243}
2244
2245static void
2246broadcast_xmessage (CdkDisplay *display,
2247 const char *message_type,
2248 const char *message_type_begin,
2249 const char *message)
2250{
2251 Display *xdisplay = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
2252 CdkScreen *screen = cdk_display_get_default_screen (display);
2253 CdkWindow *root_window = cdk_screen_get_root_window (screen);
2254 Window xroot_window = CDK_WINDOW_XID (root_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((root_window)), ((cdk_window_get_type ())
)))))->impl)), ((cdk_window_impl_x11_get_type ()))))))->
xid)
;
2255
2256 Atom type_atom;
2257 Atom type_atom_begin;
2258 Window xwindow;
2259
2260 if (!G_LIKELY (CDK_X11_DISPLAY (display)->trusted_client)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->trusted_client
)
)
2261 return;
2262
2263 {
2264 XSetWindowAttributes attrs;
2265
2266 attrs.override_redirect = True1;
2267 attrs.event_mask = PropertyChangeMask(1L<<22) | StructureNotifyMask(1L<<17);
2268
2269 xwindow =
2270 XCreateWindow (xdisplay,
2271 xroot_window,
2272 -100, -100, 1, 1,
2273 0,
2274 CopyFromParent0L,
2275 CopyFromParent0L,
2276 (Visual *)CopyFromParent0L,
2277 CWOverrideRedirect(1L<<9) | CWEventMask(1L<<11),
2278 &attrs);
2279 }
2280
2281 type_atom = cdk_x11_get_xatom_by_name_for_display (display,
2282 message_type);
2283 type_atom_begin = cdk_x11_get_xatom_by_name_for_display (display,
2284 message_type_begin);
2285
2286 {
2287 XClientMessageEvent xclient;
2288 const char *src;
2289 const char *src_end;
2290 char *dest;
2291
2292 memset(&xclient, 0, sizeof (xclient));
2293
2294 xclient.type = ClientMessage33;
2295 xclient.message_type = type_atom_begin;
2296 xclient.display =xdisplay;
2297 xclient.window = xwindow;
2298 xclient.format = 8;
2299
2300 src = message;
2301 src_end = message + strlen (message) + 1; /* +1 to include nul byte */
2302
2303 while (src != src_end)
2304 {
2305 char *dest_end;
2306
2307 dest = &xclient.data.b[0];
2308 dest_end = dest + 20;
2309
2310 while (dest != dest_end &&
2311 src != src_end)
2312 {
2313 *dest = *src;
2314 ++dest;
2315 ++src;
2316 }
2317
2318 while (dest != dest_end)
2319 {
2320 *dest = 0;
2321 ++dest;
2322 }
2323
2324 XSendEvent (xdisplay,
2325 xroot_window,
2326 False0,
2327 PropertyChangeMask(1L<<22),
2328 (XEvent *)&xclient);
2329
2330 xclient.message_type = type_atom;
2331 }
2332 }
2333
2334 XDestroyWindow (xdisplay, xwindow);
2335 XFlush (xdisplay);
2336}
2337
2338/**
2339 * cdk_x11_display_broadcast_startup_message:
2340 * @display: (type CdkX11Display): a #CdkDisplay
2341 * @message_type: startup notification message type ("new", "change",
2342 * or "remove")
2343 * @...: a list of key/value pairs (as strings), terminated by a
2344 * %NULL key. (A %NULL value for a key will cause that key to be
2345 * skipped in the output.)
2346 *
2347 * Sends a startup notification message of type @message_type to
2348 * @display.
2349 *
2350 * This is a convenience function for use by code that implements the
2351 * freedesktop startup notification specification. Applications should
2352 * not normally need to call it directly. See the
2353 * [Startup Notification Protocol specification](http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt)
2354 * for definitions of the message types and keys that can be used.
2355 *
2356 * Since: 2.12
2357 **/
2358void
2359cdk_x11_display_broadcast_startup_message (CdkDisplay *display,
2360 const char *message_type,
2361 ...)
2362{
2363 GString *message;
2364 va_list ap;
2365 const char *key, *value, *p;
2366
2367 message = g_string_new (message_type);
2368 g_string_append_c (message, ':')g_string_append_c_inline (message, ':');
2369
2370 va_start (ap, message_type)__builtin_va_start(ap, message_type);
2371 while ((key = va_arg (ap, const char *)__builtin_va_arg(ap, const char *)))
2372 {
2373 value = va_arg (ap, const char *)__builtin_va_arg(ap, const char *);
2374 if (!value)
2375 continue;
2376
2377 g_string_append_printf (message, " %s=\"", key);
2378 for (p = value; *p; p++)
2379 {
2380 switch (*p)
2381 {
2382 case ' ':
2383 case '"':
2384 case '\\':
2385 g_string_append_c (message, '\\')g_string_append_c_inline (message, '\\');
2386 break;
2387 }
2388
2389 g_string_append_c (message, *p)g_string_append_c_inline (message, *p);
2390 }
2391 g_string_append_c (message, '\"')g_string_append_c_inline (message, '\"');
2392 }
2393 va_end (ap)__builtin_va_end(ap);
2394
2395 broadcast_xmessage (display,
2396 "_NET_STARTUP_INFO",
2397 "_NET_STARTUP_INFO_BEGIN",
2398 message->str);
2399
2400 g_string_free (message, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(message), ((!(0)))) : g_string_free_and_steal (message)) : (
g_string_free) ((message), ((!(0)))))
;
2401}
2402
2403static void
2404cdk_x11_display_notify_startup_complete (CdkDisplay *display,
2405 const gchar *startup_id)
2406{
2407 gchar *free_this = NULL((void*)0);
2408
2409 if (startup_id == NULL((void*)0))
2410 {
2411 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2412
2413 startup_id = free_this = display_x11->startup_notification_id;
2414 display_x11->startup_notification_id = NULL((void*)0);
2415
2416 if (startup_id == NULL((void*)0))
2417 return;
2418 }
2419
2420 cdk_x11_display_broadcast_startup_message (display, "remove",
2421 "ID", startup_id,
2422 NULL((void*)0));
2423
2424 g_free (free_this);
2425}
2426
2427static gboolean
2428cdk_x11_display_supports_selection_notification (CdkDisplay *display)
2429{
2430 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2431
2432 return display_x11->have_xfixes;
2433}
2434
2435static gboolean
2436cdk_x11_display_request_selection_notification (CdkDisplay *display,
2437 CdkAtom selection)
2438
2439{
2440#ifdef HAVE_XFIXES1
2441 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2442 Atom atom;
2443
2444 if (display_x11->have_xfixes)
2445 {
2446 atom = cdk_x11_atom_to_xatom_for_display (display,
2447 selection);
2448 XFixesSelectSelectionInput (display_x11->xdisplay,
2449 display_x11->leader_window,
2450 atom,
2451 XFixesSetSelectionOwnerNotifyMask(1L << 0) |
2452 XFixesSelectionWindowDestroyNotifyMask(1L << 1) |
2453 XFixesSelectionClientCloseNotifyMask(1L << 2));
2454 return TRUE(!(0));
2455 }
2456 else
2457#endif
2458 return FALSE(0);
2459}
2460
2461static gboolean
2462cdk_x11_display_supports_clipboard_persistence (CdkDisplay *display)
2463{
2464 Atom clipboard_manager;
2465
2466 /* It might make sense to cache this */
2467 clipboard_manager = cdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
2468 return XGetSelectionOwner (CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->xdisplay, clipboard_manager) != None0L;
2469}
2470
2471static void
2472cdk_x11_display_store_clipboard (CdkDisplay *display,
2473 CdkWindow *clipboard_window,
2474 guint32 time_,
2475 const CdkAtom *targets,
2476 gint n_targets)
2477{
2478 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2479 Atom clipboard_manager, save_targets;
2480
2481 g_return_if_fail (CDK_WINDOW_IS_X11 (clipboard_window))do { if ((((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) (((clipboard_window)->impl)); GType __t = ((cdk_window_impl_x11_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))))) { } else { g_return_if_fail_warning ("Cdk", ((
const char*) (__func__)), "CDK_WINDOW_IS_X11 (clipboard_window)"
); return; } } while (0)
;
2482
2483 clipboard_manager = cdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER");
2484 save_targets = cdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS");
2485
2486 cdk_x11_display_error_trap_push (display);
2487
2488 if (XGetSelectionOwner (display_x11->xdisplay, clipboard_manager) != None0L)
2489 {
2490 Atom property_name = None0L;
2491
2492 if (n_targets > 0)
2493 {
2494 Atom *xatoms;
2495 int i;
2496
2497 property_name = cdk_x11_get_xatom_by_name_for_display (display, "CDK_SELECTION");
2498
2499 xatoms = g_new (Atom, n_targets)((Atom *) g_malloc_n ((n_targets), sizeof (Atom)));
2500 for (i = 0; i < n_targets; i++)
2501 xatoms[i] = cdk_x11_atom_to_xatom_for_display (display, targets[i]);
2502
2503 XChangeProperty (display_x11->xdisplay, CDK_WINDOW_XID (clipboard_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((clipboard_window)), ((cdk_window_get_type
()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))
->xid)
,
2504 property_name, XA_ATOM((Atom) 4),
2505 32, PropModeReplace0, (guchar *)xatoms, n_targets);
2506 g_free (xatoms);
2507
2508 }
2509
2510 XConvertSelection (display_x11->xdisplay,
2511 clipboard_manager, save_targets, property_name,
2512 CDK_WINDOW_XID (clipboard_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((clipboard_window)), ((cdk_window_get_type
()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))
->xid)
, time_);
2513
2514 }
2515 cdk_x11_display_error_trap_pop_ignored (display);
2516
2517}
2518
2519/**
2520 * cdk_x11_display_get_user_time:
2521 * @display: (type CdkX11Display): a #CdkDisplay
2522 *
2523 * Returns the timestamp of the last user interaction on
2524 * @display. The timestamp is taken from events caused
2525 * by user interaction such as key presses or pointer
2526 * movements. See cdk_x11_window_set_user_time().
2527 *
2528 * Returns: the timestamp of the last user interaction
2529 *
2530 * Since: 2.8
2531 */
2532guint32
2533cdk_x11_display_get_user_time (CdkDisplay *display)
2534{
2535 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->user_time;
2536}
2537
2538static gboolean
2539cdk_x11_display_supports_shapes (CdkDisplay *display)
2540{
2541 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->have_shapes;
2542}
2543
2544static gboolean
2545cdk_x11_display_supports_input_shapes (CdkDisplay *display)
2546{
2547 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->have_input_shapes;
2548}
2549
2550
2551/**
2552 * cdk_x11_display_get_startup_notification_id:
2553 * @display: (type CdkX11Display): a #CdkDisplay
2554 *
2555 * Gets the startup notification ID for a display.
2556 *
2557 * Returns: the startup notification ID for @display
2558 *
2559 * Since: 2.12
2560 */
2561const gchar *
2562cdk_x11_display_get_startup_notification_id (CdkDisplay *display)
2563{
2564 return CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->startup_notification_id;
2565}
2566
2567/**
2568 * cdk_x11_display_set_startup_notification_id:
2569 * @display: (type CdkX11Display): a #CdkDisplay
2570 * @startup_id: the startup notification ID (must be valid utf8)
2571 *
2572 * Sets the startup notification ID for a display.
2573 *
2574 * This is usually taken from the value of the DESKTOP_STARTUP_ID
2575 * environment variable, but in some cases (such as the application not
2576 * being launched using exec()) it can come from other sources.
2577 *
2578 * If the ID contains the string "_TIME" then the portion following that
2579 * string is taken to be the X11 timestamp of the event that triggered
2580 * the application to be launched and the CDK current event time is set
2581 * accordingly.
2582 *
2583 * The startup ID is also what is used to signal that the startup is
2584 * complete (for example, when opening a window or when calling
2585 * cdk_notify_startup_complete()).
2586 *
2587 * Since: 3.0
2588 **/
2589void
2590cdk_x11_display_set_startup_notification_id (CdkDisplay *display,
2591 const gchar *startup_id)
2592{
2593 CdkX11Display *display_x11;
2594
2595 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2596
2597 g_free (display_x11->startup_notification_id);
2598 display_x11->startup_notification_id = g_strdup (startup_id)g_strdup_inline (startup_id);
2599
2600 if (startup_id != NULL((void*)0))
2601 {
2602 gchar *time_str;
2603
2604 /* Find the launch time from the startup_id, if it's there. Newer spec
2605 * states that the startup_id is of the form <unique>_TIME<timestamp>
2606 */
2607 time_str = g_strrstr (startup_id, "_TIME");
2608 if (time_str != NULL((void*)0))
2609 {
2610 gulong retval;
2611 gchar *end;
2612 errno(*__errno_location ()) = 0;
2613
2614 /* Skip past the "_TIME" part */
2615 time_str += 5;
2616
2617 retval = strtoul (time_str, &end, 0);
2618 if (end != time_str && errno(*__errno_location ()) == 0)
2619 display_x11->user_time = retval;
2620 }
2621 else
2622 display_x11->user_time = 0;
2623
2624 /* Set the startup id on the leader window so it
2625 * applies to all windows we create on this display
2626 */
2627 XChangeProperty (display_x11->xdisplay,
2628 display_x11->leader_window,
2629 cdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
2630 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2631 PropModeReplace0,
2632 (guchar *)startup_id, strlen (startup_id));
2633 }
2634 else
2635 {
2636 XDeleteProperty (display_x11->xdisplay, display_x11->leader_window,
2637 cdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
2638 display_x11->user_time = 0;
2639 }
2640}
2641
2642static gboolean
2643cdk_x11_display_supports_composite (CdkDisplay *display)
2644{
2645 CdkX11Display *x11_display = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2646
2647 return x11_display->have_xcomposite &&
2648 x11_display->have_xdamage &&
2649 x11_display->have_xfixes;
2650}
2651
2652/**
2653 * cdk_x11_register_standard_event_type:
2654 * @display: (type CdkX11Display): a #CdkDisplay
2655 * @event_base: first event type code to register
2656 * @n_events: number of event type codes to register
2657 *
2658 * Registers interest in receiving extension events with type codes
2659 * between @event_base and `event_base + n_events - 1`.
2660 * The registered events must have the window field in the same place
2661 * as core X events (this is not the case for e.g. XKB extension events).
2662 *
2663 * If an event type is registered, events of this type will go through
2664 * global and window-specific filters (see cdk_window_add_filter()).
2665 * Unregistered events will only go through global filters.
2666 * CDK may register the events of some X extensions on its own.
2667 *
2668 * This function should only be needed in unusual circumstances, e.g.
2669 * when filtering XInput extension events on the root window.
2670 *
2671 * Since: 2.4
2672 **/
2673void
2674cdk_x11_register_standard_event_type (CdkDisplay *display,
2675 gint event_base,
2676 gint n_events)
2677{
2678 CdkEventTypeX11 *event_type;
2679 CdkX11Display *display_x11;
2680
2681 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2682 event_type = g_new (CdkEventTypeX11, 1)((CdkEventTypeX11 *) g_malloc_n ((1), sizeof (CdkEventTypeX11
)))
;
2683
2684 event_type->base = event_base;
2685 event_type->n_events = n_events;
2686
2687 display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type);
2688}
2689
2690/* look up the extension name for a given major opcode. grubs around in
2691 * xlib to do it since a) it’s already cached there b) XQueryExtension
2692 * emits protocol so we can’t use it in an error handler.
2693 */
2694static const char *
2695_cdk_x11_decode_request_code(Display *dpy, int code)
2696{
2697 _XExtension *ext;
2698
2699 if (code < 128)
2700 return "core protocol";
2701
2702 for (ext = dpy->ext_procs; ext; ext = ext->next)
2703 {
2704 if (ext->codes.major_opcode == code)
2705 return ext->name;
2706 }
2707
2708 return "unknown";
2709}
2710
2711/* compare X sequence numbers handling wraparound */
2712#define SEQUENCE_COMPARE(a,op,b)(((long) (a) - (long) (b)) op 0) (((long) (a) - (long) (b)) op 0)
2713
2714/* delivers an error event from the error handler in cdkmain-x11.c */
2715void
2716_cdk_x11_display_error_event (CdkDisplay *display,
2717 XErrorEvent *error)
2718{
2719 CdkX11Display *display_x11;
2720 GSList *tmp_list;
2721 gboolean ignore;
2722
2723 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2724
2725 ignore = FALSE(0);
2726 for (tmp_list = display_x11->error_traps;
2727 tmp_list != NULL((void*)0);
2728 tmp_list = tmp_list->next)
2729 {
2730 CdkErrorTrap *trap;
2731
2732 trap = tmp_list->data;
2733
2734 if (SEQUENCE_COMPARE (trap->start_sequence, <=, error->serial)(((long) (trap->start_sequence) - (long) (error->serial
)) <= 0)
&&
2735 (trap->end_sequence == 0 ||
2736 SEQUENCE_COMPARE (trap->end_sequence, >, error->serial)(((long) (trap->end_sequence) - (long) (error->serial))
> 0)
))
2737 {
2738 ignore = TRUE(!(0));
2739 trap->error_code = error->error_code;
2740 break; /* only innermost trap gets the error code */
2741 }
2742 }
2743
2744 if (!ignore)
2745 {
2746 gchar buf[64];
2747 gchar *msg;
2748
2749 XGetErrorText (display_x11->xdisplay, error->error_code, buf, 63);
2750
2751 msg =
2752 g_strdup_printf ("The program '%s' received an X Window System error.\n"
2753 "This probably reflects a bug in the program.\n"
2754 "The error was '%s'.\n"
2755 " (Details: serial %ld error_code %d request_code %d (%s) minor_code %d)\n"
2756 " (Note to programmers: normally, X errors are reported asynchronously;\n"
2757 " that is, you will receive the error a while after causing it.\n"
2758 " To debug your program, run it with the CDK_SYNCHRONIZE environment\n"
2759 " variable to change this behavior. You can then get a meaningful\n"
2760 " backtrace from your debugger if you break on the cdk_x_error() function.)",
2761 g_get_prgname (),
2762 buf,
2763 error->serial,
2764 error->error_code,
2765 error->request_code,
2766 _cdk_x11_decode_request_code(display_x11->xdisplay,
2767 error->request_code),
2768 error->minor_code);
2769
2770#ifdef G_ENABLE_DEBUG1
2771 g_error ("%s", msg);
2772#else /* !G_ENABLE_DEBUG */
2773 g_warning ("%s", msg);
2774
2775 _exit (1);
2776#endif /* G_ENABLE_DEBUG */
2777 }
2778}
2779
2780static void
2781delete_outdated_error_traps (CdkX11Display *display_x11)
2782{
2783 GSList *tmp_list;
2784 gulong processed_sequence;
2785
2786 processed_sequence = XLastKnownRequestProcessed (display_x11->xdisplay);
2787
2788 tmp_list = display_x11->error_traps;
2789 while (tmp_list != NULL((void*)0))
2790 {
2791 CdkErrorTrap *trap = tmp_list->data;
2792
2793 if (trap->end_sequence != 0 &&
2794 SEQUENCE_COMPARE (trap->end_sequence, <=, processed_sequence)(((long) (trap->end_sequence) - (long) (processed_sequence
)) <= 0)
)
2795 {
2796 GSList *free_me = tmp_list;
2797
2798 tmp_list = tmp_list->next;
2799 display_x11->error_traps =
2800 g_slist_delete_link (display_x11->error_traps, free_me);
2801 g_slice_free (CdkErrorTrap, trap)do { if (1) g_slice_free1 (sizeof (CdkErrorTrap), (trap)); else
(void) ((CdkErrorTrap*) 0 == (trap)); } while (0)
;
2802 }
2803 else
2804 {
2805 tmp_list = tmp_list->next;
2806 }
2807 }
2808}
2809
2810/**
2811 * cdk_x11_display_error_trap_push:
2812 * @display: (type CdkX11Display): a #CdkDisplay
2813 *
2814 * Begins a range of X requests on @display for which X error events
2815 * will be ignored. Unignored errors (when no trap is pushed) will abort
2816 * the application. Use cdk_x11_display_error_trap_pop() or
2817 * cdk_x11_display_error_trap_pop_ignored()to lift a trap pushed
2818 * with this function.
2819 *
2820 * See also cdk_error_trap_push() to push a trap on all displays.
2821 *
2822 * Since: 3.0
2823 */
2824void
2825cdk_x11_display_error_trap_push (CdkDisplay *display)
2826{
2827 CdkX11Display *display_x11;
2828 CdkErrorTrap *trap;
2829
2830 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2831
2832 delete_outdated_error_traps (display_x11);
2833
2834 /* set up the Xlib callback to tell us about errors */
2835 _cdk_x11_error_handler_push ();
2836
2837 trap = g_slice_new0 (CdkErrorTrap)((CdkErrorTrap*) g_slice_alloc0 (sizeof (CdkErrorTrap)));
2838
2839 trap->start_sequence = XNextRequest (display_x11->xdisplay);
2840 trap->error_code = Success0;
2841
2842 display_x11->error_traps =
2843 g_slist_prepend (display_x11->error_traps, trap);
2844}
2845
2846static gint
2847cdk_x11_display_error_trap_pop_internal (CdkDisplay *display,
2848 gboolean need_code)
2849{
2850 CdkX11Display *display_x11;
2851 CdkErrorTrap *trap;
2852 GSList *tmp_list;
2853 int result;
2854
2855 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
2856
2857 g_return_val_if_fail (display_x11->error_traps != NULL, Success)do { if ((display_x11->error_traps != ((void*)0))) { } else
{ g_return_if_fail_warning ("Cdk", ((const char*) (__func__)
), "display_x11->error_traps != NULL"); return (0); } } while
(0)
;
2858
2859 /* Find the first trap that hasn't been popped already */
2860 trap = NULL((void*)0); /* quiet gcc */
2861 for (tmp_list = display_x11->error_traps;
2862 tmp_list != NULL((void*)0);
2863 tmp_list = tmp_list->next)
2864 {
2865 trap = tmp_list->data;
2866
2867 if (trap->end_sequence == 0)
2868 break;
2869 }
2870
2871 g_return_val_if_fail (trap != NULL, Success)do { if ((trap != ((void*)0))) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "trap != NULL"); return (
0); } } while (0)
;
2872 g_assert (trap->end_sequence == 0)do { if (trap->end_sequence == 0) ; else g_assertion_message_expr
("Cdk", "cdkdisplay-x11.c", 2872, ((const char*) (__func__))
, "trap->end_sequence == 0"); } while (0)
;
2873
2874 /* May need to sync to fill in trap->error_code if we care about
2875 * getting an error code.
2876 */
2877 if (need_code)
2878 {
2879 gulong processed_sequence;
2880 gulong next_sequence;
2881
2882 next_sequence = XNextRequest (display_x11->xdisplay);
2883 processed_sequence = XLastKnownRequestProcessed (display_x11->xdisplay);
2884
2885 /* If our last request was already processed, there is no point
2886 * in syncing. i.e. if last request was a round trip (or even if
2887 * we got an event with the serial of a non-round-trip)
2888 */
2889 if ((next_sequence - 1) != processed_sequence)
2890 {
2891 XSync (display_x11->xdisplay, False0);
2892 }
2893
2894 result = trap->error_code;
2895 }
2896 else
2897 {
2898 result = Success0;
2899 }
2900
2901 /* record end of trap, giving us a range of
2902 * error sequences we'll ignore.
2903 */
2904 trap->end_sequence = XNextRequest (display_x11->xdisplay);
2905
2906 /* remove the Xlib callback */
2907 _cdk_x11_error_handler_pop ();
2908
2909 /* we may already be outdated */
2910 delete_outdated_error_traps (display_x11);
2911
2912 return result;
2913}
2914
2915/**
2916 * cdk_x11_display_set_window_scale:
2917 * @display: (type CdkX11Display): the display
2918 * @scale: The new scale value
2919 *
2920 * Forces a specific window scale for all windows on this display,
2921 * instead of using the default or user configured scale. This
2922 * is can be used to disable scaling support by setting @scale to
2923 * 1, or to programmatically set the window scale.
2924 *
2925 * Once the scale is set by this call it will not change in response
2926 * to later user configuration changes.
2927 *
2928 * Since: 3.10
2929 */
2930void
2931cdk_x11_display_set_window_scale (CdkDisplay *display,
2932 gint scale)
2933{
2934 CdkX11Screen *x11_screen;
2935 gboolean need_reread_settings = FALSE(0);
2936
2937 g_return_if_fail (CDK_IS_X11_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_X11_DISPLAY (display)"); return; } } while (0)
;
2938
2939 scale = MAX (scale, 1)(((scale) > (1)) ? (scale) : (1));
2940
2941 x11_screen = CDK_X11_SCREEN (CDK_X11_DISPLAY (display)->screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((((((CdkX11Display*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_x11_display_get_type())))
)))->screen)), ((cdk_x11_screen_get_type ()))))))
;
2942
2943 if (!x11_screen->fixed_window_scale)
2944 {
2945 x11_screen->fixed_window_scale = TRUE(!(0));
2946
2947 /* We treat screens with a window scale set differently when
2948 * reading xsettings, so we need to reread
2949 */
2950 need_reread_settings = TRUE(!(0));
2951 }
2952
2953 _cdk_x11_screen_set_window_scale (x11_screen, scale);
2954
2955 if (need_reread_settings)
2956 _cdk_x11_settings_force_reread (x11_screen);
2957}
2958
2959
2960/**
2961 * cdk_x11_display_error_trap_pop:
2962 * @display: (type CdkX11Display): the display
2963 *
2964 * Pops the error trap pushed by cdk_x11_display_error_trap_push().
2965 * Will XSync() if necessary and will always block until
2966 * the error is known to have occurred or not occurred,
2967 * so the error code can be returned.
2968 *
2969 * If you don’t need to use the return value,
2970 * cdk_x11_display_error_trap_pop_ignored() would be more efficient.
2971 *
2972 * See cdk_error_trap_pop() for the all-displays-at-once
2973 * equivalent.
2974 *
2975 * Since: 3.0
2976 *
2977 * Returns: X error code or 0 on success
2978 */
2979gint
2980cdk_x11_display_error_trap_pop (CdkDisplay *display)
2981{
2982 g_return_val_if_fail (CDK_IS_X11_DISPLAY (display), Success)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_X11_DISPLAY (display)"); return (0); } } while (0
)
;
2983
2984 return cdk_x11_display_error_trap_pop_internal (display, TRUE(!(0)));
2985}
2986
2987/**
2988 * cdk_x11_display_error_trap_pop_ignored:
2989 * @display: (type CdkX11Display): the display
2990 *
2991 * Pops the error trap pushed by cdk_x11_display_error_trap_push().
2992 * Does not block to see if an error occurred; merely records the
2993 * range of requests to ignore errors for, and ignores those errors
2994 * if they arrive asynchronously.
2995 *
2996 * See cdk_error_trap_pop_ignored() for the all-displays-at-once
2997 * equivalent.
2998 *
2999 * Since: 3.0
3000 */
3001void
3002cdk_x11_display_error_trap_pop_ignored (CdkDisplay *display)
3003{
3004 g_return_if_fail (CDK_IS_X11_DISPLAY (display))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_X11_DISPLAY (display)"); return; } } while (0)
;
3005
3006 cdk_x11_display_error_trap_pop_internal (display, FALSE(0));
3007}
3008
3009/**
3010 * cdk_x11_set_sm_client_id:
3011 * @sm_client_id: (nullable): the client id assigned by the session manager
3012 * when the connection was opened, or %NULL to remove the property.
3013 *
3014 * Sets the `SM_CLIENT_ID` property on the application’s leader window so that
3015 * the window manager can save the application’s state using the X11R6 ICCCM
3016 * session management protocol.
3017 *
3018 * See the X Session Management Library documentation for more information on
3019 * session management and the Inter-Client Communication Conventions Manual
3020 *
3021 * Since: 2.24
3022 */
3023void
3024cdk_x11_set_sm_client_id (const gchar *sm_client_id)
3025{
3026 GSList *displays, *l;
3027
3028 g_free (cdk_sm_client_id);
3029 cdk_sm_client_id = g_strdup (sm_client_id)g_strdup_inline (sm_client_id);
3030
3031 displays = cdk_display_manager_list_displays (cdk_display_manager_get ());
3032 for (l = displays; l; l = l->next)
3033 {
3034 if (CDK_IS_X11_DISPLAY (l->data)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(l->data)); GType __t = ((cdk_x11_display_get_type())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
)
3035 set_sm_client_id (l->data, sm_client_id);
3036 }
3037
3038 g_slist_free (displays);
3039}
3040
3041static gint
3042pop_error_trap (CdkDisplay *display,
3043 gboolean ignored)
3044{
3045 if (ignored)
3046 {
3047 cdk_x11_display_error_trap_pop_ignored (display);
3048 return Success0;
3049 }
3050 else
3051 {
3052 return cdk_x11_display_error_trap_pop (display);
3053 }
3054}
3055
3056static CdkKeymap *
3057cdk_x11_display_get_keymap (CdkDisplay *display)
3058{
3059 CdkX11Display *display_x11;
3060 g_return_val_if_fail (CDK_IS_DISPLAY (display), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((display)); GType __t = ((cdk_display_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_DISPLAY (display)"); return (((void*)0)); } } while
(0)
;
3061 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
3062
3063 if (!display_x11->keymap)
3064 display_x11->keymap = g_object_new (CDK_TYPE_X11_KEYMAP(cdk_x11_keymap_get_type()), NULL((void*)0));
3065
3066 display_x11->keymap->display = display;
3067
3068 return display_x11->keymap;
3069}
3070
3071static CdkSeat *
3072cdk_x11_display_get_default_seat (CdkDisplay *display)
3073{
3074 GList *seats, *l;
3075 int device_id;
3076 gboolean result = FALSE(0);
3077
3078 seats = cdk_display_list_seats (display);
3079
3080 /* Shortcut only one seat being available.
3081 * This path always triggers for core events, so we can freely use XInput below. */
3082 if (g_list_length (seats) == 1)
3083 {
3084 CdkSeat *seat = seats->data;
3085
3086 g_list_free (seats);
3087 return seat;
3088 }
3089
3090 cdk_x11_display_error_trap_push (display);
3091 result = XIGetClientPointer (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3092 None0L, &device_id);
3093 cdk_x11_display_error_trap_pop_ignored (display);
3094
3095 for (l = seats; l; l = l->next)
3096 {
3097 CdkDevice *pointer;
3098
3099 pointer = cdk_seat_get_pointer (l->data);
3100
3101 if (cdk_x11_device_get_id (pointer) == device_id || !result)
3102 {
3103 CdkSeat *seat = l->data;
3104 g_list_free (seats);
3105
3106 return seat;
3107 }
3108 }
3109
3110 g_list_free (seats);
3111
3112 return NULL((void*)0);
3113}
3114
3115static int
3116cdk_x11_display_get_n_monitors (CdkDisplay *display)
3117{
3118 CdkX11Display *x11_display = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
3119
3120 return x11_display->monitors->len;
3121}
3122
3123
3124static CdkMonitor *
3125cdk_x11_display_get_monitor (CdkDisplay *display,
3126 int monitor_num)
3127{
3128 CdkX11Display *x11_display = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
3129
3130 if (0 <= monitor_num && monitor_num < x11_display->monitors->len)
3131 return (CdkMonitor *)x11_display->monitors->pdata[monitor_num];
3132
3133 return NULL((void*)0);
3134}
3135
3136static CdkMonitor *
3137cdk_x11_display_get_primary_monitor (CdkDisplay *display)
3138{
3139 CdkX11Display *x11_display = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
3140
3141 if (0 <= x11_display->primary_monitor && x11_display->primary_monitor < x11_display->monitors->len)
3142 return x11_display->monitors->pdata[x11_display->primary_monitor];
3143
3144 return NULL((void*)0);
3145}
3146
3147static void
3148cdk_x11_display_class_init (CdkX11DisplayClass * class)
3149{
3150 GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), (((GType) ((20) << (2))))))))
;
3151 CdkDisplayClass *display_class = CDK_DISPLAY_CLASS (class)((((CdkDisplayClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((class)), ((cdk_display_get_type ()))))))
;
3152
3153 object_class->dispose = cdk_x11_display_dispose;
3154 object_class->finalize = cdk_x11_display_finalize;
3155
3156 display_class->window_type = CDK_TYPE_X11_WINDOW(cdk_x11_window_get_type ());
3157
3158 display_class->get_name = cdk_x11_display_get_name;
3159 display_class->get_default_screen = cdk_x11_display_get_default_screen;
3160 display_class->beep = cdk_x11_display_beep;
3161 display_class->sync = cdk_x11_display_sync;
3162 display_class->flush = cdk_x11_display_flush;
3163 display_class->make_default = cdk_x11_display_make_default;
3164 display_class->has_pending = cdk_x11_display_has_pending;
3165 display_class->queue_events = _cdk_x11_display_queue_events;
3166 display_class->get_default_group = cdk_x11_display_get_default_group;
3167 display_class->supports_selection_notification = cdk_x11_display_supports_selection_notification;
3168 display_class->request_selection_notification = cdk_x11_display_request_selection_notification;
3169 display_class->supports_clipboard_persistence = cdk_x11_display_supports_clipboard_persistence;
3170 display_class->store_clipboard = cdk_x11_display_store_clipboard;
3171 display_class->supports_shapes = cdk_x11_display_supports_shapes;
3172 display_class->supports_input_shapes = cdk_x11_display_supports_input_shapes;
3173 display_class->supports_composite = cdk_x11_display_supports_composite;
3174 display_class->get_app_launch_context = _cdk_x11_display_get_app_launch_context;
3175 display_class->get_cursor_for_type = _cdk_x11_display_get_cursor_for_type;
3176 display_class->get_cursor_for_name = _cdk_x11_display_get_cursor_for_name;
3177 display_class->get_cursor_for_surface = _cdk_x11_display_get_cursor_for_surface;
3178 display_class->get_default_cursor_size = _cdk_x11_display_get_default_cursor_size;
3179 display_class->get_maximal_cursor_size = _cdk_x11_display_get_maximal_cursor_size;
3180 display_class->supports_cursor_alpha = _cdk_x11_display_supports_cursor_alpha;
3181 display_class->supports_cursor_color = _cdk_x11_display_supports_cursor_color;
3182
3183 display_class->before_process_all_updates = _cdk_x11_display_before_process_all_updates;
3184 display_class->after_process_all_updates = _cdk_x11_display_after_process_all_updates;
3185 display_class->get_next_serial = cdk_x11_display_get_next_serial;
3186 display_class->notify_startup_complete = cdk_x11_display_notify_startup_complete;
3187 display_class->create_window_impl = _cdk_x11_display_create_window_impl;
3188 display_class->get_keymap = cdk_x11_display_get_keymap;
3189 display_class->push_error_trap = cdk_x11_display_error_trap_push;
3190 display_class->pop_error_trap = pop_error_trap;
3191 display_class->get_selection_owner = _cdk_x11_display_get_selection_owner;
3192 display_class->set_selection_owner = _cdk_x11_display_set_selection_owner;
3193 display_class->send_selection_notify = _cdk_x11_display_send_selection_notify;
3194 display_class->get_selection_property = _cdk_x11_display_get_selection_property;
3195 display_class->convert_selection = _cdk_x11_display_convert_selection;
3196 display_class->text_property_to_utf8_list = _cdk_x11_display_text_property_to_utf8_list;
3197 display_class->utf8_to_string_target = _cdk_x11_display_utf8_to_string_target;
3198
3199 display_class->make_gl_context_current = cdk_x11_display_make_gl_context_current;
3200
3201 display_class->get_default_seat = cdk_x11_display_get_default_seat;
3202
3203 display_class->get_n_monitors = cdk_x11_display_get_n_monitors;
3204 display_class->get_monitor = cdk_x11_display_get_monitor;
3205 display_class->get_primary_monitor = cdk_x11_display_get_primary_monitor;
3206
3207 _cdk_x11_windowing_init ();
3208}