Bug Summary

File:cdk/x11/cdkwindow-x11.c
Warning:line 2638, column 31
Access to field 'base_width' results in a dereference of a null pointer (loaded from variable 'geometry')

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 cdkwindow-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-172619-43637-1 -x c cdkwindow-x11.c
1/* CDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3 * Josh MacDonald, Ryan Lortie
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS
21 * file for a list of people on the CTK+ Team. See the ChangeLog
22 * files for a list of changes. These files are distributed with
23 * CTK+ at ftp://ftp.ctk.org/pub/ctk/.
24 */
25
26#include "config.h"
27
28#include "cdkwindow-x11.h"
29
30#include "cdkwindow.h"
31#include "cdkwindowimpl.h"
32#include "cdkvisualprivate.h"
33#include "cdkinternals.h"
34#include "cdkdeviceprivate.h"
35#include "cdkframeclockprivate.h"
36#include "cdkasync.h"
37#include "cdkeventsource.h"
38#include "cdkdisplay-x11.h"
39#include "cdkglcontext-x11.h"
40#include "cdkprivate-x11.h"
41#include "cdk-private.h"
42
43#include <stdlib.h>
44#include <stdio.h>
45#include <string.h>
46#include <netinet/in.h>
47#include <unistd.h>
48
49#include <cairo-xlib.h>
50
51#include "MwmUtil.h"
52
53#include <X11/Xlib.h>
54#include <X11/Xutil.h>
55#include <X11/Xatom.h>
56
57#include <X11/extensions/shape.h>
58
59#ifdef HAVE_XKB1
60#include <X11/XKBlib.h>
61#endif
62
63#ifdef HAVE_XCOMPOSITE1
64#include <X11/extensions/Xcomposite.h>
65#endif
66
67#ifdef HAVE_XFIXES1
68#include <X11/extensions/Xfixes.h>
69#endif
70
71#ifdef HAVE_XDAMAGE1
72#include <X11/extensions/Xdamage.h>
73#endif
74
75const int _cdk_x11_event_mask_table[21] =
76{
77 ExposureMask(1L<<15),
78 PointerMotionMask(1L<<6),
79 PointerMotionHintMask(1L<<7),
80 ButtonMotionMask(1L<<13),
81 Button1MotionMask(1L<<8),
82 Button2MotionMask(1L<<9),
83 Button3MotionMask(1L<<10),
84 ButtonPressMask(1L<<2),
85 ButtonReleaseMask(1L<<3),
86 KeyPressMask(1L<<0),
87 KeyReleaseMask(1L<<1),
88 EnterWindowMask(1L<<4),
89 LeaveWindowMask(1L<<5),
90 FocusChangeMask(1L<<21),
91 StructureNotifyMask(1L<<17),
92 PropertyChangeMask(1L<<22),
93 VisibilityChangeMask(1L<<16),
94 0, /* PROXIMITY_IN */
95 0, /* PROXIMTY_OUT */
96 SubstructureNotifyMask(1L<<19),
97 ButtonPressMask(1L<<2) /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
98};
99
100const gint _cdk_x11_event_mask_table_size = G_N_ELEMENTS (_cdk_x11_event_mask_table)(sizeof (_cdk_x11_event_mask_table) / sizeof ((_cdk_x11_event_mask_table
)[0]))
;
101
102/* Forward declarations */
103static void cdk_x11_window_apply_fullscreen_mode (CdkWindow *window);
104static gboolean cdk_window_icon_name_set (CdkWindow *window);
105static void set_wm_name (CdkDisplay *display,
106 Window xwindow,
107 const gchar *name);
108static void move_to_current_desktop (CdkWindow *window);
109static void cdk_window_x11_set_background (CdkWindow *window,
110 cairo_pattern_t *pattern);
111
112static void cdk_window_impl_x11_finalize (GObject *object);
113
114#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
\
115 (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL || \
116 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP || \
117 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN)
118
119#define WINDOW_IS_TOPLEVEL(window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
\
120 (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL || \
121 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP)
122
123/* Return whether time1 is considered later than time2 as far as xserver
124 * time is concerned. Accounts for wraparound.
125 */
126#define XSERVER_TIME_IS_LATER(time1, time2)( (( time1 > time2 ) && ( time1 - time2 < ((guint32
)-1)/2 )) || (( time1 < time2 ) && ( time2 - time1
> ((guint32)-1)/2 )) )
\
127 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
128 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
129 )
130
131struct _CdkX11Window {
132 CdkWindow parent;
133};
134
135struct _CdkX11WindowClass {
136 CdkWindowClass parent_class;
137};
138
139G_DEFINE_TYPE (CdkX11Window, cdk_x11_window, CDK_TYPE_WINDOW)static void cdk_x11_window_init (CdkX11Window *self); static void
cdk_x11_window_class_init (CdkX11WindowClass *klass); static
GType cdk_x11_window_get_type_once (void); static gpointer cdk_x11_window_parent_class
= ((void*)0); static gint CdkX11Window_private_offset; static
void cdk_x11_window_class_intern_init (gpointer klass) { cdk_x11_window_parent_class
= g_type_class_peek_parent (klass); if (CdkX11Window_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkX11Window_private_offset
); cdk_x11_window_class_init ((CdkX11WindowClass*) klass); } __attribute__
((__unused__)) static inline gpointer cdk_x11_window_get_instance_private
(CdkX11Window *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CdkX11Window_private_offset)))); } GType cdk_x11_window_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_window_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_window_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
cdk_window_get_type ()), g_intern_static_string ("CdkX11Window"
), sizeof (CdkX11WindowClass), (GClassInitFunc)(void (*)(void
)) cdk_x11_window_class_intern_init, sizeof (CdkX11Window), (
GInstanceInitFunc)(void (*)(void)) cdk_x11_window_init, (GTypeFlags
) 0); { {{};} } return g_define_type_id; }
140
141static void
142cdk_x11_window_class_init (CdkX11WindowClass *x11_window_class G_GNUC_UNUSED__attribute__ ((__unused__)))
143{
144}
145
146static void
147cdk_x11_window_init (CdkX11Window *x11_window G_GNUC_UNUSED__attribute__ ((__unused__)))
148{
149}
150
151
152G_DEFINE_TYPE (CdkWindowImplX11, cdk_window_impl_x11, CDK_TYPE_WINDOW_IMPL)static void cdk_window_impl_x11_init (CdkWindowImplX11 *self)
; static void cdk_window_impl_x11_class_init (CdkWindowImplX11Class
*klass); static GType cdk_window_impl_x11_get_type_once (void
); static gpointer cdk_window_impl_x11_parent_class = ((void*
)0); static gint CdkWindowImplX11_private_offset; static void
cdk_window_impl_x11_class_intern_init (gpointer klass) { cdk_window_impl_x11_parent_class
= g_type_class_peek_parent (klass); if (CdkWindowImplX11_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkWindowImplX11_private_offset
); cdk_window_impl_x11_class_init ((CdkWindowImplX11Class*) klass
); } __attribute__ ((__unused__)) static inline gpointer cdk_window_impl_x11_get_instance_private
(CdkWindowImplX11 *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkWindowImplX11_private_offset)))); } GType cdk_window_impl_x11_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_window_impl_x11_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_window_impl_x11_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((cdk_window_impl_get_type ()), g_intern_static_string ("CdkWindowImplX11"
), sizeof (CdkWindowImplX11Class), (GClassInitFunc)(void (*)(
void)) cdk_window_impl_x11_class_intern_init, sizeof (CdkWindowImplX11
), (GInstanceInitFunc)(void (*)(void)) cdk_window_impl_x11_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
153
154static void
155cdk_window_impl_x11_init (CdkWindowImplX11 *impl)
156{
157 impl->device_cursor = g_hash_table_new_full (NULL((void*)0), NULL((void*)0),
158 NULL((void*)0), g_object_unref);
159 impl->window_scale = 1;
160 impl->frame_sync_enabled = TRUE(!(0));
161}
162
163CdkToplevelX11 *
164_cdk_x11_window_get_toplevel (CdkWindow *window)
165{
166 CdkWindowImplX11 *impl;
167
168 g_return_val_if_fail (CDK_IS_WINDOW (window), NULL)do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
169
170 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
171 return NULL((void*)0);
172
173 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
174
175 if (!impl->toplevel)
176 {
177 impl->toplevel = g_new0 (CdkToplevelX11, 1)((CdkToplevelX11 *) g_malloc0_n ((1), sizeof (CdkToplevelX11)
))
;
178 impl->toplevel->have_focused = TRUE(!(0));
179 }
180
181 return impl->toplevel;
182}
183
184/**
185 * _cdk_x11_window_update_size:
186 * @impl: a #CdkWindowImplX11.
187 *
188 * Updates the state of the window (in particular the drawable's
189 * cairo surface) when its size has changed.
190 **/
191void
192_cdk_x11_window_update_size (CdkWindowImplX11 *impl)
193{
194 if (impl->cairo_surface)
195 {
196 cairo_xlib_surface_set_size (impl->cairo_surface,
197 impl->unscaled_width, impl->unscaled_height);
198 }
199}
200
201void
202cdk_x11_window_get_unscaled_size (CdkWindow *window,
203 int *unscaled_width,
204 int *unscaled_height)
205{
206 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
207
208 if (unscaled_width)
209 *unscaled_width = impl->unscaled_width;
210
211 if (unscaled_height)
212 *unscaled_height = impl->unscaled_height;
213}
214
215static void
216set_sync_counter(Display *display,
217 XSyncCounter counter,
218 gint64 value)
219{
220 XSyncValue sync_value;
221
222 XSyncIntsToValue (&sync_value,
223 value & G_GINT64_CONSTANT(0xFFFFFFFF)(0xFFFFFFFFL),
224 value >> 32);
225 XSyncSetCounter (display, counter, sync_value);
226}
227
228static void
229window_pre_damage (CdkWindow *window)
230{
231 CdkWindow *toplevel_window = cdk_window_get_toplevel (window);
232 CdkWindowImplX11 *impl;
233
234 if (!toplevel_window || !WINDOW_IS_TOPLEVEL (toplevel_window)(((((CdkWindow *)(toplevel_window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(toplevel_window)))->window_type) == CDK_WINDOW_TEMP
)
)
235 return;
236
237 impl = CDK_WINDOW_IMPL_X11 (toplevel_window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((toplevel_window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
238
239 if (impl->toplevel->in_frame &&
240 impl->toplevel->current_counter_value % 2 == 0)
241 {
242 impl->toplevel->current_counter_value += 1;
243 set_sync_counter (CDK_WINDOW_XDISPLAY (impl->wrapper)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (impl->wrapper)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
244 impl->toplevel->extended_update_counter,
245 impl->toplevel->current_counter_value);
246 }
247}
248
249static void
250on_surface_changed (void *data)
251{
252 CdkWindow *window = data;
253 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
254
255 if (impl->tracking_damage)
256 window_pre_damage (window);
257}
258
259/* We want to know when cairo drawing causes damage to the window,
260 * so we engage in the _NET_WM_FRAME_DRAWN protocol with the
261 * window only when there actually is drawing. To do that we use
262 * a technique (hack) suggested by Uli Schlachter - if we set
263 * a dummy "mime data" on the cairo surface (this facility is
264 * used to attach JPEG data to an imager), then cairo wil flush
265 * and remove the mime data before making any changes to the window.
266 */
267
268static void
269hook_surface_changed (CdkWindow *window)
270{
271 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
272
273 /* The hooking we do below doesn't work if we're rendering with
274 * OpenGL (the cairo surface is not touched) so just always
275 * do the frame.
276 */
277 if (window->current_paint.use_gl)
278 {
279 window_pre_damage (window);
280 return;
281 }
282
283 if (impl->cairo_surface)
284 {
285 cairo_surface_set_mime_data (impl->cairo_surface,
286 "x-cdk/change-notify",
287 (unsigned char *)"X",
288 1,
289 on_surface_changed,
290 window);
291 impl->tracking_damage = 1;
292 }
293}
294
295static void
296unhook_surface_changed (CdkWindow *window)
297{
298 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
299
300 if (impl->cairo_surface)
301 {
302 impl->tracking_damage = 0;
303 cairo_surface_set_mime_data (impl->cairo_surface,
304 "x-cdk/change-notify",
305 NULL((void*)0), 0,
306 NULL((void*)0), NULL((void*)0));
307 }
308}
309
310static void
311cdk_x11_window_predict_presentation_time (CdkWindow *window)
312{
313 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
314 CdkFrameClock *clock;
315 CdkFrameTimings *timings;
316 gint64 presentation_time;
317 gint64 refresh_interval;
318
319 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
320 return;
321
322 clock = cdk_window_get_frame_clock (window);
323
324 timings = cdk_frame_clock_get_current_timings (clock);
325
326 cdk_frame_clock_get_refresh_info (clock,
327 timings->frame_time,
328 &refresh_interval, &presentation_time);
329
330 if (presentation_time != 0)
331 {
332 if (timings->slept_before)
333 {
334 presentation_time += refresh_interval;
335 }
336 else
337 {
338 if (presentation_time < timings->frame_time + refresh_interval / 2)
339 presentation_time += refresh_interval;
340 }
341 }
342 else
343 {
344 if (timings->slept_before)
345 presentation_time = timings->frame_time + refresh_interval + refresh_interval / 2;
346 else
347 presentation_time = timings->frame_time + refresh_interval;
348 }
349
350 if (presentation_time < impl->toplevel->throttled_presentation_time)
351 presentation_time = impl->toplevel->throttled_presentation_time;
352
353 timings->predicted_presentation_time = presentation_time;
354}
355
356static void
357cdk_x11_window_begin_frame (CdkWindow *window,
358 gboolean force_frame)
359{
360 CdkWindowImplX11 *impl;
361
362 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
363
364 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
365
366 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
||
367 impl->toplevel->extended_update_counter == None0L)
368 return;
369
370 impl->toplevel->in_frame = TRUE(!(0));
371
372 if (impl->toplevel->configure_counter_value != 0 &&
373 impl->toplevel->configure_counter_value_is_extended)
374 {
375 impl->toplevel->current_counter_value = impl->toplevel->configure_counter_value;
376 if ((impl->toplevel->current_counter_value % 2) == 1)
377 impl->toplevel->current_counter_value += 1;
378
379 impl->toplevel->configure_counter_value = 0;
380
381 window_pre_damage (window);
382 }
383 else if (force_frame)
384 {
385 /* When mapping the window, we really want to freeze the
386 rendering of the window by the compositor until we've
387 actually painted something into the window's buffer. */
388 window_pre_damage (window);
389 }
390 else
391 {
392 hook_surface_changed (window);
393 }
394}
395
396static void
397cdk_x11_window_end_frame (CdkWindow *window)
398{
399 CdkFrameClock *clock;
400 CdkFrameTimings *timings;
401 CdkWindowImplX11 *impl;
402
403 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
404
405 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
406
407 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
||
408 impl->toplevel->extended_update_counter == None0L ||
409 !impl->toplevel->in_frame)
410 return;
411
412 clock = cdk_window_get_frame_clock (window);
413 timings = cdk_frame_clock_get_current_timings (clock);
414
415 impl->toplevel->in_frame = FALSE(0);
416
417 if (impl->toplevel->current_counter_value % 2 == 1)
418 {
419#ifdef G_ENABLE_DEBUG1
420 if (CDK_DEBUG_CHECK (FRAMES)(_cdk_debug_flags & CDK_DEBUG_FRAMES))
421 {
422 XImage *image = XGetImage (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
423 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)
,
424 0, 0, 1, 1,
425 (1 << 24) - 1,
426 ZPixmap2);
427 XDestroyImage (image)((*((image)->f.destroy_image))((image)));
428 }
429#endif /* G_ENABLE_DEBUG */
430
431 /* An increment of 3 means that the frame was not drawn as fast as possible,
432 * but rather at a particular time. This can trigger different handling from
433 * the compositor.
434 */
435 if (timings->slept_before)
436 impl->toplevel->current_counter_value += 3;
437 else
438 impl->toplevel->current_counter_value += 1;
439
440 set_sync_counter(CDK_WINDOW_XDISPLAY (impl->wrapper)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (impl->wrapper)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
441 impl->toplevel->extended_update_counter,
442 impl->toplevel->current_counter_value);
443
444 if (impl->frame_sync_enabled &&
445 cdk_x11_screen_supports_net_wm_hint (cdk_window_get_screen (window),
446 cdk_atom_intern_static_string ("_NET_WM_FRAME_DRAWN")))
447 {
448 impl->toplevel->frame_pending = TRUE(!(0));
449 _cdk_frame_clock_freeze (cdk_window_get_frame_clock (window));
450 timings->cookie = impl->toplevel->current_counter_value;
451 }
452 }
453
454 unhook_surface_changed (window);
455
456 if (impl->toplevel->configure_counter_value != 0 &&
457 !impl->toplevel->configure_counter_value_is_extended)
458 {
459 set_sync_counter (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
460 impl->toplevel->update_counter,
461 impl->toplevel->configure_counter_value);
462
463 impl->toplevel->configure_counter_value = 0;
464 }
465
466 if (!impl->toplevel->frame_pending)
467 timings->complete = TRUE(!(0));
468}
469
470/*****************************************************
471 * X11 specific implementations of generic functions *
472 *****************************************************/
473
474static cairo_surface_t *
475cdk_x11_create_cairo_surface (CdkWindowImplX11 *impl,
476 int width,
477 int height)
478{
479 CdkVisual *visual;
480
481 visual = cdk_window_get_visual (impl->wrapper);
482 return cairo_xlib_surface_create (CDK_WINDOW_XDISPLAY (impl->wrapper)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (impl->wrapper)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
483 CDK_WINDOW_IMPL_X11 (impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((impl)), ((cdk_window_impl_x11_get_type ()))
))))
->xid,
484 CDK_VISUAL_XVISUAL (visual)(cdk_x11_visual_get_xvisual (visual)),
485 width, height);
486}
487
488static cairo_surface_t *
489cdk_x11_ref_cairo_surface (CdkWindow *window)
490{
491 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
492
493 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
494 return NULL((void*)0);
495
496 if (!impl->cairo_surface)
497 {
498 impl->cairo_surface = cdk_x11_create_cairo_surface (impl,
499 cdk_window_get_width (window) * impl->window_scale,
500 cdk_window_get_height (window) * impl->window_scale);
501 cairo_surface_set_device_scale (impl->cairo_surface, impl->window_scale, impl->window_scale);
502
503 if (WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
&& impl->toplevel->in_frame)
504 hook_surface_changed (window);
505 }
506
507 cairo_surface_reference (impl->cairo_surface);
508
509 return impl->cairo_surface;
510}
511
512static void
513cdk_window_impl_x11_finalize (GObject *object)
514{
515 CdkWindow *wrapper;
516 CdkWindowImplX11 *impl;
517
518 g_return_if_fail (CDK_IS_WINDOW_IMPL_X11 (object))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((object)); 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_IS_WINDOW_IMPL_X11 (object)"); return
; } } while (0)
;
519
520 impl = CDK_WINDOW_IMPL_X11 (object)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((cdk_window_impl_x11_get_type ()
))))))
;
521
522 wrapper = impl->wrapper;
523
524 if (WINDOW_IS_TOPLEVEL (wrapper)(((((CdkWindow *)(wrapper)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(wrapper)))->window_type) == CDK_WINDOW_TEMP
)
&& impl->toplevel->in_frame)
525 unhook_surface_changed (wrapper);
526
527 _cdk_x11_window_grab_check_destroy (wrapper);
528
529 if (!CDK_WINDOW_DESTROYED (wrapper)(((CdkWindow *)(wrapper))->destroyed))
530 {
531 CdkDisplay *display = CDK_WINDOW_DISPLAY (wrapper)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (wrapper)))), ((cdk_x11_screen_get_type
()))))))->display)
;
532
533 _cdk_x11_display_remove_window (display, impl->xid);
534 if (impl->toplevel && impl->toplevel->focus_window)
535 _cdk_x11_display_remove_window (display, impl->toplevel->focus_window);
536 }
537
538 g_free (impl->toplevel);
539
540 if (impl->cursor)
541 g_object_unref (impl->cursor);
542
543 g_hash_table_destroy (impl->device_cursor);
544
545 G_OBJECT_CLASS (cdk_window_impl_x11_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((cdk_window_impl_x11_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
546}
547
548typedef struct {
549 CdkDisplay *display;
550 Pixmap pixmap;
551} FreePixmapData;
552
553static void
554free_pixmap (gpointer datap)
555{
556 FreePixmapData *data = datap;
557
558 if (!cdk_display_is_closed (data->display))
559 {
560 XFreePixmap (CDK_DISPLAY_XDISPLAY (data->display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->display)), ((cdk_x11_display_get_type()))))))->
xdisplay)
,
561 data->pixmap);
562 }
563
564 g_object_unref (data->display);
565 g_slice_free (FreePixmapData, data)do { if (1) g_slice_free1 (sizeof (FreePixmapData), (data)); else
(void) ((FreePixmapData*) 0 == (data)); } while (0)
;
566}
567
568static void
569attach_free_pixmap_handler (cairo_surface_t *surface,
570 CdkDisplay *display,
571 Pixmap pixmap)
572{
573 static const cairo_user_data_key_t key;
574 FreePixmapData *data;
575
576 data = g_slice_new (FreePixmapData)((FreePixmapData*) g_slice_alloc (sizeof (FreePixmapData)));
577 data->display = g_object_ref (display)((__typeof__ (display)) (g_object_ref) (display));
578 data->pixmap = pixmap;
579
580 cairo_surface_set_user_data (surface, &key, data, free_pixmap);
581}
582
583/* Cairo does not guarantee we get an xlib surface if we call
584 * cairo_surface_create_similar(). In some cases however, we must use a
585 * pixmap or bitmap in the X11 API.
586 * These functions ensure an Xlib surface.
587 */
588cairo_surface_t *
589_cdk_x11_window_create_bitmap_surface (CdkWindow *window,
590 int width,
591 int height)
592{
593 cairo_surface_t *surface;
594 Pixmap pixmap;
595
596 pixmap = XCreatePixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
597 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)
,
598 width, height, 1);
599 surface = cairo_xlib_surface_create_for_bitmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
600 pixmap,
601 CDK_X11_SCREEN (CDK_WINDOW_SCREEN (window))((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))
->xscreen,
602 width, height);
603 attach_free_pixmap_handler (surface, CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, pixmap);
604
605 return surface;
606}
607
608/* Create a surface backed with a pixmap without alpha on the same screen as window */
609static cairo_surface_t *
610cdk_x11_window_create_pixmap_surface (CdkWindow *window,
611 int width,
612 int height)
613{
614 CdkScreen *screen = cdk_window_get_screen (window);
615 CdkVisual *visual = cdk_screen_get_system_visual (screen);
616 cairo_surface_t *surface;
617 Pixmap pixmap;
618
619 pixmap = XCreatePixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
620 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)
,
621 width, height,
622 cdk_visual_get_depth (visual));
623 surface = cairo_xlib_surface_create (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
624 pixmap,
625 CDK_VISUAL_XVISUAL (visual)(cdk_x11_visual_get_xvisual (visual)),
626 width, height);
627 attach_free_pixmap_handler (surface, CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, pixmap);
628
629 return surface;
630}
631
632static void
633tmp_unset_bg (CdkWindow *window)
634{
635 CdkWindowImplX11 *impl;
636
637 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
638
639 impl->no_bg = TRUE(!(0));
640
641 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
642 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)
, None0L);
643}
644
645static void
646tmp_reset_bg (CdkWindow *window)
647{
648 CdkWindowImplX11 *impl;
649
650 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
651
652 impl->no_bg = FALSE(0);
653
654 cdk_window_x11_set_background (window, window->background);
655}
656
657/* Unsetting and resetting window backgrounds.
658 *
659 * In many cases it is possible to avoid flicker by unsetting the
660 * background of windows. For example if the background of the
661 * parent window is unset when a window is unmapped, a brief flicker
662 * of background painting is avoided.
663 */
664void
665_cdk_x11_window_tmp_unset_bg (CdkWindow *window,
666 gboolean recurse)
667{
668 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
669
670 if (window->input_only || window->destroyed ||
671 (window->window_type != CDK_WINDOW_ROOT &&
672 !CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0)))
673 return;
674
675 if (_cdk_window_has_impl (window) &&
676 CDK_WINDOW_IS_X11 (window)((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*)
(((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; })))))
&&
677 window->window_type != CDK_WINDOW_ROOT &&
678 window->window_type != CDK_WINDOW_FOREIGN)
679 tmp_unset_bg (window);
680
681 if (recurse)
682 {
683 GList *l;
684
685 for (l = window->children; l != NULL((void*)0); l = l->next)
686 _cdk_x11_window_tmp_unset_bg (l->data, TRUE(!(0)));
687 }
688}
689
690void
691_cdk_x11_window_tmp_unset_parent_bg (CdkWindow *window)
692{
693 if (CDK_WINDOW_TYPE (window->parent)((((CdkWindow *)(window->parent)))->window_type) == CDK_WINDOW_ROOT)
694 return;
695
696 window = _cdk_window_get_impl_window (window->parent);
697 _cdk_x11_window_tmp_unset_bg (window, FALSE(0));
698}
699
700void
701_cdk_x11_window_tmp_reset_bg (CdkWindow *window,
702 gboolean recurse)
703{
704 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
705
706 if (window->input_only || window->destroyed ||
707 (window->window_type != CDK_WINDOW_ROOT &&
708 !CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0)))
709 return;
710
711
712 if (_cdk_window_has_impl (window) &&
713 CDK_WINDOW_IS_X11 (window)((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*)
(((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; })))))
&&
714 window->window_type != CDK_WINDOW_ROOT &&
715 window->window_type != CDK_WINDOW_FOREIGN)
716 tmp_reset_bg (window);
717
718 if (recurse)
719 {
720 GList *l;
721
722 for (l = window->children; l != NULL((void*)0); l = l->next)
723 _cdk_x11_window_tmp_reset_bg (l->data, TRUE(!(0)));
724 }
725}
726
727void
728_cdk_x11_window_tmp_reset_parent_bg (CdkWindow *window)
729{
730 if (CDK_WINDOW_TYPE (window->parent)((((CdkWindow *)(window->parent)))->window_type) == CDK_WINDOW_ROOT)
731 return;
732
733 window = _cdk_window_get_impl_window (window->parent);
734
735 _cdk_x11_window_tmp_reset_bg (window, FALSE(0));
736}
737
738void
739_cdk_x11_screen_init_root_window (CdkScreen *screen)
740{
741 CdkWindow *window;
742 CdkWindowImplX11 *impl;
743 CdkX11Screen *x11_screen;
744
745 x11_screen = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
;
746
747 g_assert (x11_screen->root_window == NULL)do { if (x11_screen->root_window == ((void*)0)) ; else g_assertion_message_expr
("Cdk", "cdkwindow-x11.c", 747, ((const char*) (__func__)), "x11_screen->root_window == NULL"
); } while (0)
;
748
749 window = x11_screen->root_window = _cdk_display_create_window (cdk_screen_get_display (screen));
750
751 window->impl = g_object_new (CDK_TYPE_WINDOW_IMPL_X11(cdk_window_impl_x11_get_type ()), NULL((void*)0));
752 window->impl_window = window;
753 window->visual = cdk_screen_get_system_visual (screen);
754
755 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
756
757 impl->xid = x11_screen->xroot_window;
758 impl->wrapper = window;
759 impl->window_scale = x11_screen->window_scale;
760
761 window->window_type = CDK_WINDOW_ROOT;
762 window->depth = DefaultDepthOfScreen (x11_screen->xscreen)((x11_screen->xscreen)->root_depth);
763
764 window->x = 0;
765 window->y = 0;
766 window->abs_x = 0;
767 window->abs_y = 0;
768 impl->unscaled_width = WidthOfScreen (x11_screen->xscreen)((x11_screen->xscreen)->width);
769 impl->unscaled_height = HeightOfScreen (x11_screen->xscreen)((x11_screen->xscreen)->height);
770 window->width = WidthOfScreen (x11_screen->xscreen)((x11_screen->xscreen)->width) / impl->window_scale;
771 window->height = HeightOfScreen (x11_screen->xscreen)((x11_screen->xscreen)->height) / impl->window_scale;
772 window->viewable = TRUE(!(0));
773
774 /* see init_randr_support() in cdkscreen-x11.c */
775 window->event_mask = CDK_STRUCTURE_MASK;
776
777 _cdk_window_update_size (x11_screen->root_window);
778
779 _cdk_x11_display_add_window (x11_screen->display,
780 &x11_screen->xroot_window,
781 x11_screen->root_window);
782}
783
784static void
785set_wm_protocols (CdkWindow *window)
786{
787 CdkDisplay *display = cdk_window_get_display (window);
788 Atom protocols[4];
789 int n = 0;
790
791 protocols[n++] = cdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
792 protocols[n++] = cdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
793 protocols[n++] = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
794
795#ifdef HAVE_XSYNC1
796 if (CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->use_sync)
797 protocols[n++] = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
798#endif
799
800 XSetWMProtocols (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)
, protocols, n);
801}
802
803static const gchar *
804get_default_title (void)
805{
806 const char *title;
807
808 title = g_get_application_name ();
809 if (!title)
810 title = g_get_prgname ();
811 if (!title)
812 title = "";
813
814 return title;
815}
816
817static void
818check_leader_window_title (CdkDisplay *display)
819{
820 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
821
822 if (display_x11->leader_window && !display_x11->leader_window_title_set)
823 {
824 set_wm_name (display,
825 display_x11->leader_window,
826 get_default_title ());
827
828 display_x11->leader_window_title_set = TRUE(!(0));
829 }
830}
831
832static Window
833create_focus_window (CdkDisplay *display,
834 XID parent)
835{
836 CdkX11Display *display_x11;
837 CdkEventMask event_mask;
838 Display *xdisplay;
839 Window focus_window;
840 XSetWindowAttributes attrs;
841
842 xdisplay = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
843 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
844
845 focus_window = XCreateWindow (xdisplay, parent,
846 -1, -1, 1, 1, 0,
847 0, /* depth */
848 InputOnly2,
849 CopyFromParent0L,
850 0, &attrs);
851
852 event_mask = (CDK_KEY_PRESS_MASK |
853 CDK_KEY_RELEASE_MASK |
854 CDK_FOCUS_CHANGE_MASK);
855
856 cdk_x11_event_source_select_events ((CdkEventSource *) display_x11->event_source,
857 focus_window,
858 event_mask, 0);
859
860 XMapWindow (xdisplay, focus_window);
861
862 return focus_window;
863}
864
865static void
866ensure_sync_counter (CdkWindow *window)
867{
868#ifdef HAVE_XSYNC1
869 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
870 {
871 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)
;
872 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
873
874 if (toplevel &&
875 toplevel->update_counter == None0L &&
876 CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->use_sync)
877 {
878 Display *xdisplay = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
879 XSyncValue value;
880 Atom atom;
881 XID counters[2];
882
883 XSyncIntToValue (&value, 0);
884
885 toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
886 toplevel->extended_update_counter = XSyncCreateCounter (xdisplay, value);
887
888 atom = cdk_x11_get_xatom_by_name_for_display (display,
889 "_NET_WM_SYNC_REQUEST_COUNTER");
890
891 counters[0] = toplevel->update_counter;
892 counters[1] = toplevel->extended_update_counter;
893 XChangeProperty (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)
,
894 atom, XA_CARDINAL((Atom) 6),
895 32, PropModeReplace0,
896 (guchar *)counters, 2);
897
898 toplevel->current_counter_value = 0;
899 }
900 }
901#endif
902}
903
904static void
905setup_toplevel_window (CdkWindow *window,
906 CdkWindow *parent)
907{
908 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
909 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
910 CdkDisplay *display = cdk_window_get_display (window);
911 Display *xdisplay = CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
;
912 XID xid = 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)
;
913 CdkX11Screen *x11_screen = CDK_X11_SCREEN (CDK_WINDOW_SCREEN (parent))((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (parent)))), ((cdk_x11_screen_get_type
()))))))
;
914 XSizeHints size_hints;
915 Window leader_window;
916
917 set_wm_protocols (window);
918
919 if (!window->input_only)
920 {
921 /* The focus window is off the visible area, and serves to receive key
922 * press events so they don't get sent to child windows.
923 */
924 toplevel->focus_window = create_focus_window (display, xid);
925 _cdk_x11_display_add_window (x11_screen->display,
926 &toplevel->focus_window,
927 window);
928 }
929
930 check_leader_window_title (x11_screen->display);
931
932 /* FIXME: Is there any point in doing this? Do any WM's pay
933 * attention to PSize, and even if they do, is this the
934 * correct value???
935 */
936 size_hints.flags = PSize(1L << 3);
937 size_hints.width = window->width * impl->window_scale;
938 size_hints.height = window->height * impl->window_scale;
939
940 XSetWMNormalHints (xdisplay, xid, &size_hints);
941
942 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
943 XSetWMProperties (xdisplay, xid, NULL((void*)0), NULL((void*)0), NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), NULL((void*)0));
944
945 if (!cdk_running_in_sandbox ())
946 {
947 /* if sandboxed, we're likely in a pid namespace and would only confuse the wm with this */
948 long pid = getpid ();
949 XChangeProperty (xdisplay, xid,
950 cdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_PID"),
951 XA_CARDINAL((Atom) 6), 32,
952 PropModeReplace0,
953 (guchar *)&pid, 1);
954 }
955
956 leader_window = CDK_X11_DISPLAY (x11_screen->display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((x11_screen->display)), ((cdk_x11_display_get_type()))
))))
->leader_window;
957 if (!leader_window)
958 leader_window = xid;
959 XChangeProperty (xdisplay, xid,
960 cdk_x11_get_xatom_by_name_for_display (x11_screen->display, "WM_CLIENT_LEADER"),
961 XA_WINDOW((Atom) 33), 32, PropModeReplace0,
962 (guchar *) &leader_window, 1);
963
964 if (toplevel->focus_window != None0L)
965 XChangeProperty (xdisplay, xid,
966 cdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_USER_TIME_WINDOW"),
967 XA_WINDOW((Atom) 33), 32, PropModeReplace0,
968 (guchar *) &toplevel->focus_window, 1);
969
970 if (!window->focus_on_map)
971 cdk_x11_window_set_user_time (window, 0);
972 else if (CDK_X11_DISPLAY (x11_screen->display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((x11_screen->display)), ((cdk_x11_display_get_type()))
))))
->user_time != 0)
973 cdk_x11_window_set_user_time (window, CDK_X11_DISPLAY (x11_screen->display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((x11_screen->display)), ((cdk_x11_display_get_type()))
))))
->user_time);
974
975 ensure_sync_counter (window);
976
977 /* Start off in a frozen state - we'll finish this when we first paint */
978 cdk_x11_window_begin_frame (window, TRUE(!(0)));
979}
980
981static void
982on_frame_clock_before_paint (CdkFrameClock *clock G_GNUC_UNUSED__attribute__ ((__unused__)),
983 CdkWindow *window)
984{
985 cdk_x11_window_predict_presentation_time (window);
986 cdk_x11_window_begin_frame (window, FALSE(0));
987}
988
989static void
990on_frame_clock_after_paint (CdkFrameClock *clock G_GNUC_UNUSED__attribute__ ((__unused__)),
991 CdkWindow *window)
992{
993 cdk_x11_window_end_frame (window);
994
995}
996
997static void
998connect_frame_clock (CdkWindow *window)
999{
1000 CdkWindowImplX11 *impl;
1001
1002 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1003 if (WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
&& !impl->frame_clock_connected)
1004 {
1005 CdkFrameClock *frame_clock = cdk_window_get_frame_clock (window);
1006
1007 g_signal_connect (frame_clock, "before-paint",g_signal_connect_data ((frame_clock), ("before-paint"), (((GCallback
) (on_frame_clock_before_paint))), (window), ((void*)0), (GConnectFlags
) 0)
1008 G_CALLBACK (on_frame_clock_before_paint), window)g_signal_connect_data ((frame_clock), ("before-paint"), (((GCallback
) (on_frame_clock_before_paint))), (window), ((void*)0), (GConnectFlags
) 0)
;
1009 g_signal_connect (frame_clock, "after-paint",g_signal_connect_data ((frame_clock), ("after-paint"), (((GCallback
) (on_frame_clock_after_paint))), (window), ((void*)0), (GConnectFlags
) 0)
1010 G_CALLBACK (on_frame_clock_after_paint), window)g_signal_connect_data ((frame_clock), ("after-paint"), (((GCallback
) (on_frame_clock_after_paint))), (window), ((void*)0), (GConnectFlags
) 0)
;
1011
1012 impl->frame_clock_connected = TRUE(!(0));
1013 }
1014}
1015
1016static void
1017clamp_window_size (CdkWindow *window,
1018 gint *width,
1019 gint *height)
1020{
1021 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1022
1023 if (*width * impl->window_scale > 32767 ||
1024 *height * impl->window_scale > 32767)
1025 {
1026 g_warning ("Native Windows wider or taller than 32767 pixels are not supported");
1027
1028 if (*width * impl->window_scale > 32767)
1029 *width = 32767 / impl->window_scale;
1030 if (*height * impl->window_scale > 32767)
1031 *height = 32767 / impl->window_scale;
1032 }
1033}
1034
1035void
1036_cdk_x11_display_create_window_impl (CdkDisplay *display,
1037 CdkWindow *window,
1038 CdkWindow *real_parent,
1039 CdkScreen *screen,
1040 CdkEventMask event_mask,
1041 CdkWindowAttr *attributes,
1042 gint attributes_mask)
1043{
1044 CdkWindowImplX11 *impl;
1045 CdkX11Screen *x11_screen;
1046 CdkX11Display *display_x11;
1047
1048 Window xparent;
1049 Visual *xvisual;
1050 Display *xdisplay;
1051
1052 XSetWindowAttributes xattributes;
1053 long xattributes_mask;
1054
1055 unsigned int class;
1056 const char *title;
1057
1058 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1059 xparent = CDK_WINDOW_XID (real_parent)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((real_parent)), ((cdk_window_get_type ())
)))))->impl)), ((cdk_window_impl_x11_get_type ()))))))->
xid)
;
1060 x11_screen = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
;
1061
1062 impl = g_object_new (CDK_TYPE_WINDOW_IMPL_X11(cdk_window_impl_x11_get_type ()), NULL((void*)0));
1063 window->impl = CDK_WINDOW_IMPL (impl)((((CdkWindowImpl*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((impl)), ((cdk_window_impl_get_type ()))))))
;
1064 impl->wrapper = CDK_WINDOW (window)((((CdkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((cdk_window_get_type ()))))))
;
1065 impl->window_scale = x11_screen->window_scale;
1066
1067 xdisplay = x11_screen->xdisplay;
1068
1069 xattributes_mask = 0;
1070
1071 xvisual = cdk_x11_visual_get_xvisual (window->visual);
1072
1073 if (attributes_mask & CDK_WA_NOREDIR)
1074 {
1075 xattributes.override_redirect =
1076 (attributes->override_redirect == FALSE(0))?False0:True1;
1077 xattributes_mask |= CWOverrideRedirect(1L<<9);
1078 }
1079 else
1080 xattributes.override_redirect = False0;
1081
1082 impl->override_redirect = xattributes.override_redirect;
1083
1084 /* This event mask will be set near the end of the function, but to avoid some
1085 * races, the window has to be created with this mask already.
1086 */
1087 xattributes.event_mask = StructureNotifyMask(1L<<17) | PropertyChangeMask(1L<<22);
1088 xattributes_mask |= CWEventMask(1L<<11);
1089
1090 /* Sanity checks */
1091 switch (window->window_type)
1092 {
1093 case CDK_WINDOW_TOPLEVEL:
1094 case CDK_WINDOW_TEMP:
1095 if (CDK_WINDOW_TYPE (window->parent)((((CdkWindow *)(window->parent)))->window_type) != CDK_WINDOW_ROOT)
1096 {
1097 /* The common code warns for this case */
1098 xparent = CDK_SCREEN_XROOTWIN (screen)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))->xroot_window
)
;
1099 }
1100 }
1101
1102 if (!window->input_only)
1103 {
1104 class = InputOutput1;
1105
1106 xattributes.background_pixel = BlackPixel (xdisplay, x11_screen->screen_num)((&((_XPrivDisplay)(xdisplay))->screens[x11_screen->
screen_num])->black_pixel)
;
1107
1108 xattributes.border_pixel = BlackPixel (xdisplay, x11_screen->screen_num)((&((_XPrivDisplay)(xdisplay))->screens[x11_screen->
screen_num])->black_pixel)
;
1109 xattributes_mask |= CWBorderPixel(1L<<3) | CWBackPixel(1L<<1);
1110
1111 xattributes.bit_gravity = NorthWestGravity1;
1112 xattributes_mask |= CWBitGravity(1L<<4);
1113
1114 xattributes.colormap = _cdk_visual_get_x11_colormap (window->visual);
1115 xattributes_mask |= CWColormap(1L<<13);
1116
1117 if (window->window_type == CDK_WINDOW_TEMP)
1118 {
1119 xattributes.save_under = True1;
1120 xattributes.override_redirect = True1;
1121 xattributes.cursor = None0L;
1122 xattributes_mask |= CWSaveUnder(1L<<10) | CWOverrideRedirect(1L<<9);
1123
1124 impl->override_redirect = TRUE(!(0));
1125 }
1126 }
1127 else
1128 {
1129 class = InputOnly2;
1130 }
1131
1132 clamp_window_size (window, &window->width, &window->height);
1133
1134 impl->unscaled_width = window->width * impl->window_scale;
1135 impl->unscaled_height = window->height * impl->window_scale;
1136
1137 impl->xid = XCreateWindow (xdisplay, xparent,
1138 (window->x + window->parent->abs_x) * impl->window_scale,
1139 (window->y + window->parent->abs_y) * impl->window_scale,
1140 window->width * impl->window_scale, window->height * impl->window_scale,
1141 0, window->depth, class, xvisual,
1142 xattributes_mask, &xattributes);
1143
1144 g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
1145 _cdk_x11_display_add_window (x11_screen->display, &impl->xid, window);
1146
1147 switch (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type))
1148 {
1149 case CDK_WINDOW_TOPLEVEL:
1150 case CDK_WINDOW_TEMP:
1151 if (attributes_mask & CDK_WA_TITLE)
1152 title = attributes->title;
1153 else
1154 title = get_default_title ();
1155
1156 cdk_window_set_title (window, title);
1157
1158 if (attributes_mask & CDK_WA_WMCLASS)
1159 {
1160 XClassHint *class_hint;
1161
1162 class_hint = XAllocClassHint ();
1163 class_hint->res_name = attributes->wmclass_name;
1164 class_hint->res_class = attributes->wmclass_class;
1165 XSetClassHint (xdisplay, impl->xid, class_hint);
1166 XFree (class_hint);
1167 }
1168
1169 setup_toplevel_window (window, window->parent);
1170 break;
1171
1172 case CDK_WINDOW_CHILD:
1173 default:
1174 break;
1175 }
1176
1177 if (attributes_mask & CDK_WA_TYPE_HINT)
1178 cdk_window_set_type_hint (window, attributes->type_hint);
1179
1180 if (!window->input_only)
1181 cdk_window_x11_set_background (window, NULL((void*)0));
1182
1183 cdk_x11_event_source_select_events ((CdkEventSource *) display_x11->event_source,
1184 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)
, event_mask,
1185 StructureNotifyMask(1L<<17) | PropertyChangeMask(1L<<22));
1186
1187 connect_frame_clock (window);
1188
1189 if (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD)
1190 cdk_window_freeze_toplevel_updates (window);
1191}
1192
1193static CdkEventMask
1194x_event_mask_to_cdk_event_mask (long mask)
1195{
1196 CdkEventMask event_mask = 0;
1197 int i;
1198
1199 for (i = 0; i < _cdk_x11_event_mask_table_size; i++)
1200 {
1201 if (mask & _cdk_x11_event_mask_table[i])
1202 event_mask |= 1 << (i + 1);
1203 }
1204
1205 return event_mask;
1206}
1207
1208/**
1209 * cdk_x11_window_foreign_new_for_display:
1210 * @display: (type CdkX11Display): the #CdkDisplay where the window handle comes from.
1211 * @window: an Xlib Window
1212 *
1213 * Wraps a native window in a #CdkWindow. The function will try to
1214 * look up the window using cdk_x11_window_lookup_for_display() first.
1215 * If it does not find it there, it will create a new window.
1216 *
1217 * This may fail if the window has been destroyed. If the window
1218 * was already known to CDK, a new reference to the existing
1219 * #CdkWindow is returned.
1220 *
1221 * Returns: (transfer full): a #CdkWindow wrapper for the native
1222 * window, or %NULL if the window has been destroyed. The wrapper
1223 * will be newly created, if one doesn’t exist already.
1224 *
1225 * Since: 2.24
1226 */
1227CdkWindow *
1228cdk_x11_window_foreign_new_for_display (CdkDisplay *display,
1229 Window window)
1230{
1231 CdkScreen *screen;
1232 CdkWindow *win;
1233 CdkWindowImplX11 *impl;
1234 CdkX11Display *display_x11;
1235 XWindowAttributes attrs;
1236 Window root, parent;
1237 Window *children = NULL((void*)0);
1238 guint nchildren;
1239 gboolean result;
1240
1241 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)
;
1242
1243 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1244
1245 if ((win = cdk_x11_window_lookup_for_display (display, window)) != NULL((void*)0))
1246 return g_object_ref (win)((__typeof__ (win)) (g_object_ref) (win));
1247
1248 cdk_x11_display_error_trap_push (display);
1249 result = XGetWindowAttributes (display_x11->xdisplay, window, &attrs);
1250 if (cdk_x11_display_error_trap_pop (display) || !result)
1251 return NULL((void*)0);
1252
1253 /* FIXME: This is pretty expensive.
1254 * Maybe the caller should supply the parent
1255 */
1256 cdk_x11_display_error_trap_push (display);
1257 result = XQueryTree (display_x11->xdisplay, window, &root, &parent, &children, &nchildren);
1258 if (cdk_x11_display_error_trap_pop (display) || !result)
1259 return NULL((void*)0);
1260
1261 if (children)
1262 XFree (children);
1263
1264 screen = _cdk_x11_display_screen_for_xrootwin (display, root);
1265 if (screen == NULL((void*)0))
1266 return NULL((void*)0);
1267
1268 win = _cdk_display_create_window (display);
1269 win->impl = g_object_new (CDK_TYPE_WINDOW_IMPL_X11(cdk_window_impl_x11_get_type ()), NULL((void*)0));
1270 win->impl_window = win;
1271 win->visual = cdk_x11_screen_lookup_visual (screen,
1272 XVisualIDFromVisual (attrs.visual));
1273
1274 impl = CDK_WINDOW_IMPL_X11 (win->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((win->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1275 impl->wrapper = win;
1276 impl->window_scale = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
->window_scale;
1277
1278 win->parent = cdk_x11_window_lookup_for_display (display, parent);
1279
1280 if (!win->parent || CDK_WINDOW_TYPE (win->parent)((((CdkWindow *)(win->parent)))->window_type) == CDK_WINDOW_FOREIGN)
1281 win->parent = cdk_screen_get_root_window (screen);
1282
1283 win->parent->children = g_list_concat (&win->children_list_node, win->parent->children);
1284 win->parent->impl_window->native_children =
1285 g_list_prepend (win->parent->impl_window->native_children, win);
1286
1287 impl->xid = window;
1288
1289 win->x = attrs.x / impl->window_scale;
1290 win->y = attrs.y / impl->window_scale;
1291 impl->unscaled_width = attrs.width;
1292 impl->unscaled_height = attrs.height;
1293 win->width = attrs.width / impl->window_scale;
1294 win->height = attrs.height / impl->window_scale;
1295 win->window_type = CDK_WINDOW_FOREIGN;
1296 win->destroyed = FALSE(0);
1297
1298 win->event_mask = x_event_mask_to_cdk_event_mask (attrs.your_event_mask);
1299
1300 if (attrs.map_state == IsUnmapped0)
1301 win->state = CDK_WINDOW_STATE_WITHDRAWN;
1302 else
1303 win->state = 0;
1304 win->viewable = TRUE(!(0));
1305
1306 win->depth = attrs.depth;
1307
1308 g_object_ref (win)((__typeof__ (win)) (g_object_ref) (win));
1309 _cdk_x11_display_add_window (display, &CDK_WINDOW_XID (win)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((win)), ((cdk_window_get_type ()))))))->
impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
, win);
1310
1311 /* Update the clip region, etc */
1312 _cdk_window_update_size (win);
1313
1314 return win;
1315}
1316
1317static void
1318cdk_toplevel_x11_free_contents (CdkDisplay *display,
1319 CdkToplevelX11 *toplevel)
1320{
1321 if (toplevel->icon_pixmap)
1322 {
1323 cairo_surface_destroy (toplevel->icon_pixmap);
1324 toplevel->icon_pixmap = NULL((void*)0);
1325 }
1326 if (toplevel->icon_mask)
1327 {
1328 cairo_surface_destroy (toplevel->icon_mask);
1329 toplevel->icon_mask = NULL((void*)0);
1330 }
1331 if (toplevel->group_leader)
1332 {
1333 g_object_unref (toplevel->group_leader);
1334 toplevel->group_leader = NULL((void*)0);
1335 }
1336#ifdef HAVE_XSYNC1
1337 if (toplevel->update_counter != None0L)
1338 {
1339 XSyncDestroyCounter (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
1340 toplevel->update_counter);
1341 XSyncDestroyCounter (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
1342 toplevel->extended_update_counter);
1343 toplevel->update_counter = None0L;
1344 toplevel->extended_update_counter = None0L;
1345
1346 toplevel->current_counter_value = 0;
1347 }
1348#endif
1349}
1350
1351static void
1352cdk_x11_window_destroy (CdkWindow *window,
1353 gboolean recursing,
1354 gboolean foreign_destroy)
1355{
1356 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1357 CdkToplevelX11 *toplevel;
1358
1359 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
1360
1361 _cdk_x11_selection_window_destroyed (window);
1362
1363 toplevel = _cdk_x11_window_get_toplevel (window);
1364 if (toplevel)
1365 cdk_toplevel_x11_free_contents (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, toplevel);
1366
1367 unhook_surface_changed (window);
1368
1369 if (impl->cairo_surface)
1370 {
1371 cairo_surface_finish (impl->cairo_surface);
1372 cairo_surface_destroy (impl->cairo_surface);
1373 impl->cairo_surface = NULL((void*)0);
1374 }
1375
1376 if (!recursing && !foreign_destroy)
1377 XDestroyWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
);
1378}
1379
1380static void
1381cdk_x11_window_destroy_foreign (CdkWindow *window)
1382{
1383 /* It's somebody else's window, but in our hierarchy,
1384 * so reparent it to the root window, and then send
1385 * it a delete event, as if we were a WM
1386 */
1387 XClientMessageEvent xclient;
1388 CdkDisplay *display;
1389
1390 display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
1391 cdk_x11_display_error_trap_push (display);
1392 cdk_window_hide (window);
1393 cdk_window_reparent (window, NULL((void*)0), 0, 0);
1394
1395 memset (&xclient, 0, sizeof (xclient));
1396 xclient.type = ClientMessage33;
1397 xclient.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)
;
1398 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
1399 xclient.format = 32;
1400 xclient.data.l[0] = cdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
1401 xclient.data.l[1] = CurrentTime0L;
1402 xclient.data.l[2] = 0;
1403 xclient.data.l[3] = 0;
1404 xclient.data.l[4] = 0;
1405
1406 XSendEvent (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1407 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)
,
1408 False0, 0, (XEvent *)&xclient);
1409 cdk_x11_display_error_trap_pop_ignored (display);
1410}
1411
1412static CdkWindow *
1413get_root (CdkWindow *window)
1414{
1415 CdkScreen *screen = cdk_window_get_screen (window);
1416
1417 return cdk_screen_get_root_window (screen);
1418}
1419
1420/* This function is called when the XWindow is really gone.
1421 */
1422static void
1423cdk_x11_window_destroy_notify (CdkWindow *window)
1424{
1425 CdkWindowImplX11 *window_impl;
1426
1427 window_impl = CDK_WINDOW_IMPL_X11 ((window)->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) (((window)->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1428
1429 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
1430 {
1431 if (CDK_WINDOW_TYPE(window)((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_FOREIGN)
1432 g_warning ("CdkWindow %#lx unexpectedly destroyed", 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)
);
1433
1434 _cdk_window_destroy (window, TRUE(!(0)));
1435 }
1436
1437 _cdk_x11_display_remove_window (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, 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)
);
1438 if (window_impl->toplevel && window_impl->toplevel->focus_window)
1439 _cdk_x11_display_remove_window (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, window_impl->toplevel->focus_window);
1440
1441 _cdk_x11_window_grab_check_destroy (window);
1442
1443 g_object_unref (window);
1444}
1445
1446static CdkDragProtocol
1447cdk_x11_window_get_drag_protocol (CdkWindow *window,
1448 CdkWindow **target)
1449{
1450 CdkDragProtocol protocol;
1451 CdkDisplay *display;
1452 guint version;
1453 Window xid;
1454
1455 display = cdk_window_get_display (window);
1456 xid = _cdk_x11_display_get_drag_protocol (display,
1457 CDK_WINDOW_XID (window->impl_window)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((window->impl_window)), ((cdk_window_get_type
()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))
->xid)
,
1458 &protocol,
1459 &version);
1460
1461 if (target)
1462 {
1463 if (xid != None0L)
1464 *target = cdk_x11_window_foreign_new_for_display (display, xid);
1465 else
1466 *target = NULL((void*)0);
1467 }
1468
1469 return protocol;
1470}
1471
1472static void
1473update_wm_hints (CdkWindow *window,
1474 gboolean force)
1475{
1476 CdkToplevelX11 *toplevel = _cdk_x11_window_get_toplevel (window);
1477 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)
;
1478 XWMHints wm_hints;
1479
1480 if (!force &&
1481 !toplevel->is_leader &&
1482 window->state & CDK_WINDOW_STATE_WITHDRAWN)
1483 return;
1484
1485 wm_hints.flags = StateHint(1L << 1) | InputHint(1L << 0);
1486 wm_hints.input = window->accept_focus ? True1 : False0;
1487 wm_hints.initial_state = NormalState1;
1488
1489 if (window->state & CDK_WINDOW_STATE_ICONIFIED)
1490 {
1491 wm_hints.flags |= StateHint(1L << 1);
1492 wm_hints.initial_state = IconicState3;
1493 }
1494
1495 if (toplevel->icon_pixmap)
1496 {
1497 wm_hints.flags |= IconPixmapHint(1L << 2);
1498 wm_hints.icon_pixmap = cairo_xlib_surface_get_drawable (toplevel->icon_pixmap);
1499 }
1500
1501 if (toplevel->icon_mask)
1502 {
1503 wm_hints.flags |= IconMaskHint(1L << 5);
1504 wm_hints.icon_mask = cairo_xlib_surface_get_drawable (toplevel->icon_mask);
1505 }
1506
1507 wm_hints.flags |= WindowGroupHint(1L << 6);
1508 if (toplevel->group_leader && !CDK_WINDOW_DESTROYED (toplevel->group_leader)(((CdkWindow *)(toplevel->group_leader))->destroyed))
1509 {
1510 wm_hints.flags |= WindowGroupHint(1L << 6);
1511 wm_hints.window_group = CDK_WINDOW_XID (toplevel->group_leader)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((toplevel->group_leader)), ((cdk_window_get_type
()))))))->impl)), ((cdk_window_impl_x11_get_type ()))))))
->xid)
;
1512 }
1513 else
1514 wm_hints.window_group = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->leader_window;
1515
1516 if (toplevel->urgency_hint)
1517 wm_hints.flags |= XUrgencyHint(1L << 8);
1518
1519 XSetWMHints (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1520 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)
,
1521 &wm_hints);
1522}
1523
1524static void
1525set_initial_hints (CdkWindow *window)
1526{
1527 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)
;
1528 Display *xdisplay = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
1529 Window xwindow = 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)
;
1530 CdkToplevelX11 *toplevel;
1531 Atom atoms[9];
1532 gint i;
1533
1534 toplevel = _cdk_x11_window_get_toplevel (window);
1535
1536 if (!toplevel)
1537 return;
1538
1539 update_wm_hints (window, TRUE(!(0)));
1540
1541 /* We set the spec hints regardless of whether the spec is supported,
1542 * since it can't hurt and it's kind of expensive to check whether
1543 * it's supported.
1544 */
1545
1546 i = 0;
1547
1548 if (window->state & CDK_WINDOW_STATE_MAXIMIZED)
1549 {
1550 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1551 "_NET_WM_STATE_MAXIMIZED_VERT");
1552 ++i;
1553 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1554 "_NET_WM_STATE_MAXIMIZED_HORZ");
1555 ++i;
1556 toplevel->have_maxhorz = toplevel->have_maxvert = TRUE(!(0));
1557 }
1558
1559 if (window->state & CDK_WINDOW_STATE_ABOVE)
1560 {
1561 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1562 "_NET_WM_STATE_ABOVE");
1563 ++i;
1564 }
1565
1566 if (window->state & CDK_WINDOW_STATE_BELOW)
1567 {
1568 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1569 "_NET_WM_STATE_BELOW");
1570 ++i;
1571 }
1572
1573 if (window->state & CDK_WINDOW_STATE_STICKY)
1574 {
1575 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1576 "_NET_WM_STATE_STICKY");
1577 ++i;
1578 toplevel->have_sticky = TRUE(!(0));
1579 }
1580
1581 if (window->state & CDK_WINDOW_STATE_FULLSCREEN)
1582 {
1583 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1584 "_NET_WM_STATE_FULLSCREEN");
1585 ++i;
1586 toplevel->have_fullscreen = TRUE(!(0));
1587 }
1588
1589 if (window->modal_hint)
1590 {
1591 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1592 "_NET_WM_STATE_MODAL");
1593 ++i;
1594 }
1595
1596 if (toplevel->skip_taskbar_hint)
1597 {
1598 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1599 "_NET_WM_STATE_SKIP_TASKBAR");
1600 ++i;
1601 }
1602
1603 if (toplevel->skip_pager_hint)
1604 {
1605 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1606 "_NET_WM_STATE_SKIP_PAGER");
1607 ++i;
1608 }
1609
1610 if (window->state & CDK_WINDOW_STATE_ICONIFIED)
1611 {
1612 atoms[i] = cdk_x11_get_xatom_by_name_for_display (display,
1613 "_NET_WM_STATE_HIDDEN");
1614 ++i;
1615 toplevel->have_hidden = TRUE(!(0));
1616 }
1617
1618 if (i > 0)
1619 {
1620 XChangeProperty (xdisplay,
1621 xwindow,
1622 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1623 XA_ATOM((Atom) 4), 32, PropModeReplace0,
1624 (guchar*) atoms, i);
1625 }
1626 else
1627 {
1628 XDeleteProperty (xdisplay,
1629 xwindow,
1630 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1631 }
1632
1633 if (window->state & CDK_WINDOW_STATE_STICKY)
1634 {
1635 atoms[0] = 0xFFFFFFFF;
1636 XChangeProperty (xdisplay,
1637 xwindow,
1638 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1639 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
1640 (guchar*) atoms, 1);
1641 toplevel->on_all_desktops = TRUE(!(0));
1642 }
1643 else
1644 {
1645 XDeleteProperty (xdisplay,
1646 xwindow,
1647 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1648 }
1649
1650 toplevel->map_serial = NextRequest (xdisplay)(((_XPrivDisplay)(xdisplay))->request + 1);
1651}
1652
1653static void
1654cdk_window_x11_show (CdkWindow *window, gboolean already_mapped)
1655{
1656 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1657 Display *xdisplay = CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
;
1658 Window xwindow = 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)
;
1659 gboolean unset_bg;
1660
1661 if (!already_mapped)
1662 set_initial_hints (window);
1663
1664 if (WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
1665 {
1666 CdkDisplay *display;
1667 CdkX11Display *display_x11;
1668 CdkToplevelX11 *toplevel;
1669
1670 display = cdk_window_get_display (window);
1671 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
1672 toplevel = _cdk_x11_window_get_toplevel (window);
1673
1674 if (toplevel->user_time != 0 &&
1675 display_x11->user_time != 0 &&
1676 XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time)( (( display_x11->user_time > toplevel->user_time ) &&
( display_x11->user_time - toplevel->user_time < ((
guint32)-1)/2 )) || (( display_x11->user_time < toplevel
->user_time ) && ( toplevel->user_time - display_x11
->user_time > ((guint32)-1)/2 )) )
)
1677 cdk_x11_window_set_user_time (window, display_x11->user_time);
1678 }
1679
1680 unset_bg = !window->input_only &&
1681 (window->window_type == CDK_WINDOW_CHILD ||
1682 impl->override_redirect) &&
1683 cdk_window_is_viewable (window);
1684
1685 if (unset_bg)
1686 _cdk_x11_window_tmp_unset_bg (window, TRUE(!(0)));
1687
1688 XMapWindow (xdisplay, xwindow);
1689
1690 if (unset_bg)
1691 _cdk_x11_window_tmp_reset_bg (window, TRUE(!(0)));
1692
1693 /* Fullscreen on current monitor is the default, no need to apply this mode
1694 * when mapping a window. This also ensures that the default behavior remains
1695 * consistent with pre-fullscreen mode implementation.
1696 */
1697 if (window->fullscreen_mode != CDK_FULLSCREEN_ON_CURRENT_MONITOR)
1698 cdk_x11_window_apply_fullscreen_mode (window);
1699}
1700
1701static void
1702pre_unmap (CdkWindow *window)
1703{
1704 CdkWindow *start_window = NULL((void*)0);
1705
1706 if (window->input_only)
1707 return;
1708
1709 if (window->window_type == CDK_WINDOW_CHILD)
1710 start_window = _cdk_window_get_impl_window ((CdkWindow *)window->parent);
1711 else if (window->window_type == CDK_WINDOW_TEMP)
1712 start_window = get_root (window);
1713
1714 if (start_window)
1715 _cdk_x11_window_tmp_unset_bg (start_window, TRUE(!(0)));
1716}
1717
1718static void
1719post_unmap (CdkWindow *window)
1720{
1721 CdkWindow *start_window = NULL((void*)0);
1722
1723 if (window->input_only)
1724 return;
1725
1726 if (window->window_type == CDK_WINDOW_CHILD)
1727 start_window = _cdk_window_get_impl_window ((CdkWindow *)window->parent);
1728 else if (window->window_type == CDK_WINDOW_TEMP)
1729 start_window = get_root (window);
1730
1731 if (start_window)
1732 {
1733 _cdk_x11_window_tmp_reset_bg (start_window, TRUE(!(0)));
1734
1735 if (window->window_type == CDK_WINDOW_CHILD && window->parent)
1736 {
1737 CdkRectangle invalid_rect;
1738
1739 cdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
1740 invalid_rect.width = cdk_window_get_width (window);
1741 invalid_rect.height = cdk_window_get_height (window);
1742 cdk_window_invalidate_rect ((CdkWindow *)window->parent,
1743 &invalid_rect, TRUE(!(0)));
1744 }
1745 }
1746}
1747
1748static void
1749cdk_window_x11_hide (CdkWindow *window)
1750{
1751 /* We'll get the unmap notify eventually, and handle it then,
1752 * but checking here makes things more consistent if we are
1753 * just doing stuff ourself.
1754 */
1755 _cdk_x11_window_grab_check_unmap (window,
1756 NextRequest (CDK_WINDOW_XDISPLAY (window))(((_XPrivDisplay)((((((CdkX11Screen*) (void *) g_type_check_instance_cast
((GTypeInstance*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)))->request + 1)
);
1757
1758 /* You can't simply unmap toplevel windows. */
1759 switch (window->window_type)
1760 {
1761 case CDK_WINDOW_TOPLEVEL:
1762 case CDK_WINDOW_TEMP: /* ? */
1763 cdk_window_withdraw (window);
1764 return;
1765
1766 case CDK_WINDOW_FOREIGN:
1767 case CDK_WINDOW_ROOT:
1768 case CDK_WINDOW_CHILD:
1769 break;
1770 }
1771
1772 _cdk_window_clear_update_area (window);
1773
1774 pre_unmap (window);
1775 XUnmapWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1776 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)
);
1777 post_unmap (window);
1778}
1779
1780static void
1781cdk_window_x11_withdraw (CdkWindow *window)
1782{
1783 if (!window->destroyed)
1784 {
1785 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
1786 cdk_synthesize_window_state (window,
1787 0,
1788 CDK_WINDOW_STATE_WITHDRAWN);
1789
1790 g_assert (!CDK_WINDOW_IS_MAPPED (window))do { if (!(((window)->state & CDK_WINDOW_STATE_WITHDRAWN
) == 0)) ; else g_assertion_message_expr ("Cdk", "cdkwindow-x11.c"
, 1790, ((const char*) (__func__)), "!CDK_WINDOW_IS_MAPPED (window)"
); } while (0)
;
1791
1792 pre_unmap (window);
1793
1794 XWithdrawWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1795 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)
, 0);
1796
1797 post_unmap (window);
1798 }
1799}
1800
1801static inline void
1802window_x11_move (CdkWindow *window,
1803 gint x,
1804 gint y)
1805{
1806 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1807
1808 if (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_CHILD)
1809 {
1810 /* The window isn't actually damaged, but it's parent is */
1811 window_pre_damage (window);
1812 _cdk_x11_window_move_resize_child (window,
1813 x, y,
1814 window->width, window->height);
1815 }
1816 else
1817 {
1818 XMoveWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1819 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)
,
1820 x * impl->window_scale, y * impl->window_scale);
1821
1822 if (impl->override_redirect)
1823 {
1824 window->x = x;
1825 window->y = y;
1826 }
1827 }
1828}
1829
1830static inline void
1831window_x11_resize (CdkWindow *window,
1832 gint width,
1833 gint height)
1834{
1835 if (width < 1)
1836 width = 1;
1837
1838 if (height < 1)
1839 height = 1;
1840
1841 window_pre_damage (window);
1842
1843 if (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_CHILD)
1844 {
1845 _cdk_x11_window_move_resize_child (window,
1846 window->x, window->y,
1847 width, height);
1848 }
1849 else
1850 {
1851 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1852
1853 XResizeWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1854 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)
,
1855 width * impl->window_scale, height * impl->window_scale);
1856
1857 if (impl->override_redirect)
1858 {
1859 impl->unscaled_width = width * impl->window_scale;
1860 impl->unscaled_height = height * impl->window_scale;
1861 window->width = width;
1862 window->height = height;
1863 _cdk_x11_window_update_size (CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
);
1864 }
1865 else
1866 {
1867 if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height)
1868 window->resize_count += 1;
1869 }
1870 }
1871}
1872
1873static inline void
1874window_x11_move_resize (CdkWindow *window,
1875 gint x,
1876 gint y,
1877 gint width,
1878 gint height)
1879{
1880 if (width < 1)
1881 width = 1;
1882
1883 if (height < 1)
1884 height = 1;
1885
1886 window_pre_damage (window);
1887
1888 if (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_CHILD)
1889 {
1890 _cdk_x11_window_move_resize_child (window, x, y, width, height);
1891 _cdk_x11_window_update_size (CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
);
1892 }
1893 else
1894 {
1895 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1896
1897 XMoveResizeWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1898 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)
,
1899 x * impl->window_scale, y * impl->window_scale,
1900 width * impl->window_scale, height * impl->window_scale);
1901
1902 if (impl->override_redirect)
1903 {
1904 window->x = x;
1905 window->y = y;
1906
1907 impl->unscaled_width = width * impl->window_scale;
1908 impl->unscaled_height = height * impl->window_scale;
1909 window->width = width;
1910 window->height = height;
1911
1912 _cdk_x11_window_update_size (CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
);
1913 }
1914 else
1915 {
1916 if (width * impl->window_scale != impl->unscaled_width || height * impl->window_scale != impl->unscaled_height)
1917 window->resize_count += 1;
1918 }
1919 }
1920}
1921
1922static void
1923cdk_window_x11_move_resize (CdkWindow *window,
1924 gboolean with_move,
1925 gint x,
1926 gint y,
1927 gint width,
1928 gint height)
1929{
1930 if (with_move && (width < 0 && height < 0))
1931 window_x11_move (window, x, y);
1932 else
1933 {
1934 clamp_window_size (window, &width, &height);
1935
1936 if (with_move)
1937 window_x11_move_resize (window, x, y, width, height);
1938 else
1939 window_x11_resize (window, width, height);
1940 }
1941}
1942
1943static void
1944set_scale_recursive (CdkWindow *window, int scale)
1945{
1946 GList *l;
1947
1948 for (l = window->children; l; l = l->next)
1949 {
1950 CdkWindow *child;
1951
1952 child = l->data;
1953
1954 if (child->impl != window->impl)
1955 _cdk_x11_window_set_window_scale (child, scale);
1956 else
1957 set_scale_recursive (child, scale);
1958 }
1959}
1960
1961void
1962_cdk_x11_window_set_window_scale (CdkWindow *window,
1963 int scale)
1964{
1965 CdkWindowImplX11 *impl;
1966 CdkToplevelX11 *toplevel;
1967 CdkWindowHints geom_mask;
1968
1969 if (window->window_type == CDK_WINDOW_OFFSCREEN)
1970 return;
1971
1972 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
1973
1974 impl->window_scale = scale;
1975 if (impl->cairo_surface)
1976 cairo_surface_set_device_scale (impl->cairo_surface, impl->window_scale, impl->window_scale);
1977 _cdk_window_update_size (window);
1978
1979 toplevel = _cdk_x11_window_get_toplevel (window);
1980 if (toplevel && window->window_type != CDK_WINDOW_FOREIGN)
1981 {
1982 /* These are affected by window scale: */
1983 geom_mask = toplevel->last_geometry_hints_mask &
1984 (CDK_HINT_MIN_SIZE | CDK_HINT_MAX_SIZE | CDK_HINT_BASE_SIZE | CDK_HINT_RESIZE_INC);
1985 if (geom_mask)
1986 cdk_window_set_geometry_hints (window,
1987 &toplevel->last_geometry_hints,
1988 geom_mask);
1989 }
1990
1991 if (window->window_type == CDK_WINDOW_FOREIGN)
1992 XMoveWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
1993 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)
,
1994 (window->x + window->parent->abs_x) * impl->window_scale,
1995 (window->y + window->parent->abs_y) * impl->window_scale);
1996 else if (WINDOW_IS_TOPLEVEL(window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
1997 {
1998 if (impl->override_redirect)
1999 {
2000 impl->unscaled_width = window->width * impl->window_scale;
2001 impl->unscaled_height = window->height * impl->window_scale;
2002 }
2003
2004 XResizeWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2005 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)
,
2006 window->width * impl->window_scale,
2007 window->height * impl->window_scale);
2008 }
2009 else
2010 {
2011 impl->unscaled_width = window->width * impl->window_scale;
2012 impl->unscaled_height = window->height * impl->window_scale;
2013
2014 XMoveResizeWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2015 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)
,
2016 (window->x + window->parent->abs_x) * impl->window_scale,
2017 (window->y + window->parent->abs_y) * impl->window_scale,
2018 window->width * impl->window_scale,
2019 window->height * impl->window_scale);
2020 }
2021
2022 cdk_window_invalidate_rect (window, NULL((void*)0), TRUE(!(0)));
2023
2024 set_scale_recursive (window, scale);
2025}
2026
2027static gboolean
2028cdk_window_x11_reparent (CdkWindow *window,
2029 CdkWindow *new_parent,
2030 gint x,
2031 gint y)
2032{
2033 CdkWindowImplX11 *impl;
2034
2035 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
2036
2037 _cdk_x11_window_tmp_unset_bg (window, TRUE(!(0)));
2038 _cdk_x11_window_tmp_unset_parent_bg (window);
2039 XReparentWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2040 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)
,
2041 CDK_WINDOW_XID (new_parent)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((new_parent)), ((cdk_window_get_type ()))
))))->impl)), ((cdk_window_impl_x11_get_type ()))))))->
xid)
,
2042 (new_parent->abs_x + x) * impl->window_scale,
2043 (new_parent->abs_y + y) * impl->window_scale);
2044 _cdk_x11_window_tmp_reset_parent_bg (window);
2045 _cdk_x11_window_tmp_reset_bg (window, TRUE(!(0)));
2046
2047 if (WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
2048 connect_frame_clock (window);
2049 else
2050 /* old frame clock was disposed, our signal handlers removed */
2051 impl->frame_clock_connected = FALSE(0);
2052
2053 if (CDK_WINDOW_TYPE (new_parent)((((CdkWindow *)(new_parent)))->window_type) == CDK_WINDOW_FOREIGN)
2054 new_parent = cdk_screen_get_root_window (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)));
2055
2056 window->parent = new_parent;
2057
2058 /* Switch the window type as appropriate */
2059
2060 switch (CDK_WINDOW_TYPE (new_parent)((((CdkWindow *)(new_parent)))->window_type))
2061 {
2062 case CDK_WINDOW_ROOT:
2063 case CDK_WINDOW_FOREIGN:
2064 /* Reparenting to toplevel */
2065
2066 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
&&
2067 CDK_WINDOW_TYPE (new_parent)((((CdkWindow *)(new_parent)))->window_type) == CDK_WINDOW_FOREIGN)
2068 {
2069 /* This is also done in common code at a later stage, but we
2070 need it in setup_toplevel, so do it here too */
2071 if (window->toplevel_window_type != -1)
2072 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) = window->toplevel_window_type;
2073 else if (CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_CHILD)
2074 CDK_WINDOW_TYPE (window)((((CdkWindow *)(window)))->window_type) = CDK_WINDOW_TOPLEVEL;
2075
2076 /* Wasn't a toplevel, set up */
2077 setup_toplevel_window (window, new_parent);
2078 }
2079
2080 break;
2081
2082 case CDK_WINDOW_TOPLEVEL:
2083 case CDK_WINDOW_CHILD:
2084 case CDK_WINDOW_TEMP:
2085 if (WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
&&
2086 impl->toplevel)
2087 {
2088 if (impl->toplevel->focus_window)
2089 {
2090 XDestroyWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, impl->toplevel->focus_window);
2091 _cdk_x11_display_remove_window (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, impl->toplevel->focus_window);
2092 }
2093
2094 cdk_toplevel_x11_free_contents (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
,
2095 impl->toplevel);
2096 g_free (impl->toplevel);
2097 impl->toplevel = NULL((void*)0);
2098 }
2099 }
2100
2101 return FALSE(0);
2102}
2103
2104static void
2105cdk_window_x11_raise (CdkWindow *window)
2106{
2107 XRaiseWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
);
2108}
2109
2110static void
2111cdk_window_x11_restack_under (CdkWindow *window,
2112 GList *native_siblings /* in requested order, first is bottom-most */)
2113{
2114 Window *windows;
2115 int n_windows, i;
2116 GList *l;
2117
2118 n_windows = g_list_length (native_siblings) + 1;
2119 windows = g_new (Window, n_windows)((Window *) g_malloc_n ((n_windows), sizeof (Window)));
2120
2121 windows[0] = 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)
;
2122 /* Reverse order, as input order is bottom-most first */
2123 i = n_windows - 1;
2124 for (l = native_siblings; l != NULL((void*)0); l = l->next)
2125 windows[i--] = CDK_WINDOW_XID (l->data)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((l->data)), ((cdk_window_get_type ()))
))))->impl)), ((cdk_window_impl_x11_get_type ()))))))->
xid)
;
2126
2127 XRestackWindows (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, windows, n_windows);
2128
2129 g_free (windows);
2130}
2131
2132static void
2133cdk_window_x11_restack_toplevel (CdkWindow *window,
2134 CdkWindow *sibling,
2135 gboolean above)
2136{
2137 XWindowChanges changes;
2138
2139 changes.sibling = CDK_WINDOW_XID (sibling)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((sibling)), ((cdk_window_get_type ())))))
)->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid
)
;
2140 changes.stack_mode = above ? Above0 : Below1;
2141 XReconfigureWMWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2142 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)
,
2143 cdk_x11_screen_get_number (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window))),
2144 CWStackMode(1<<6) | CWSibling(1<<5), &changes);
2145}
2146
2147static void
2148cdk_window_x11_lower (CdkWindow *window)
2149{
2150 XLowerWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
);
2151}
2152
2153/**
2154 * cdk_x11_window_move_to_current_desktop:
2155 * @window: (type CdkX11Window): a #CdkWindow
2156 *
2157 * Moves the window to the correct workspace when running under a
2158 * window manager that supports multiple workspaces, as described
2159 * in the [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec) specification.
2160 * Will not do anything if the window is already on all workspaces.
2161 *
2162 * Since: 2.8
2163 */
2164void
2165cdk_x11_window_move_to_current_desktop (CdkWindow *window)
2166{
2167 CdkToplevelX11 *toplevel;
2168
2169 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
2170 g_return_if_fail (CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD)do { if ((((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD
)) { } else { g_return_if_fail_warning ("Cdk", ((const char*)
(__func__)), "CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD")
; return; } } while (0)
;
2171
2172 toplevel = _cdk_x11_window_get_toplevel (window);
2173
2174 if (toplevel->on_all_desktops)
2175 return;
2176
2177 move_to_current_desktop (window);
2178}
2179
2180static void
2181move_to_current_desktop (CdkWindow *window)
2182{
2183 guint32 desktop;
2184
2185 desktop = cdk_x11_screen_get_current_desktop (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)));
2186 cdk_x11_window_move_to_desktop (window, desktop);
2187}
2188
2189static guint32
2190get_netwm_cardinal_property (CdkWindow *window,
2191 const gchar *name)
2192{
2193 CdkScreen *screen = CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window));
2194 CdkX11Screen *x11_screen = CDK_X11_SCREEN (screen)((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_x11_screen_get_type ()))))))
;
2195 CdkAtom atom;
2196 guint32 prop = 0;
2197 Atom type;
2198 gint format;
2199 gulong nitems;
2200 gulong bytes_after;
2201 guchar *data;
2202
2203 atom = cdk_atom_intern_static_string (name);
2204
2205 if (!cdk_x11_screen_supports_net_wm_hint (screen, atom))
2206 return 0;
2207
2208 XGetWindowProperty (x11_screen->xdisplay,
2209 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)
,
2210 cdk_x11_get_xatom_by_name_for_display (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, name),
2211 0, G_MAXLONG9223372036854775807L,
2212 False0, XA_CARDINAL((Atom) 6), &type, &format, &nitems,
2213 &bytes_after, &data);
2214 if (type == XA_CARDINAL((Atom) 6))
2215 {
2216 prop = *(gulong *)data;
2217 XFree (data);
2218 }
2219
2220 return prop;
2221}
2222
2223/**
2224 * cdk_x11_window_get_desktop:
2225 * @window: (type CdkX11Window): a #CdkWindow
2226 *
2227 * Gets the number of the workspace @window is on.
2228 *
2229 * Returns: the current workspace of @window
2230 *
2231 * Since: 3.10
2232 */
2233guint32
2234cdk_x11_window_get_desktop (CdkWindow *window)
2235{
2236 g_return_val_if_fail (CDK_IS_WINDOW (window), 0)do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return (0); } } while (0)
;
2237
2238 return get_netwm_cardinal_property (window, "_NET_WM_DESKTOP");
2239}
2240
2241/**
2242 * cdk_x11_window_move_to_desktop:
2243 * @window: (type CdkX11Window): a #CdkWindow
2244 * @desktop: the number of the workspace to move the window to
2245 *
2246 * Moves the window to the given workspace when running unde a
2247 * window manager that supports multiple workspaces, as described
2248 * in the [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec) specification.
2249 *
2250 * Since: 3.10
2251 */
2252void
2253cdk_x11_window_move_to_desktop (CdkWindow *window,
2254 guint32 desktop)
2255{
2256 CdkAtom atom;
2257 XClientMessageEvent xclient;
2258
2259 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
2260
2261 atom = cdk_atom_intern_static_string ("_NET_WM_DESKTOP");
2262 if (!cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)), atom))
2263 return;
2264
2265 memset (&xclient, 0, sizeof (xclient));
2266 xclient.type = ClientMessage33;
2267 xclient.serial = 0;
2268 xclient.send_event = True1;
2269 xclient.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)
;
2270 xclient.message_type = cdk_x11_atom_to_xatom_for_display (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, atom);
2271 xclient.format = 32;
2272
2273 xclient.data.l[0] = desktop;
2274 xclient.data.l[1] = 1; /* source indication */
2275 xclient.data.l[2] = 0;
2276 xclient.data.l[3] = 0;
2277 xclient.data.l[4] = 0;
2278
2279 XSendEvent (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2280 CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
,
2281 False0,
2282 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
2283 (XEvent *)&xclient);
2284}
2285
2286static void
2287cdk_x11_window_focus (CdkWindow *window,
2288 guint32 timestamp)
2289{
2290 CdkDisplay *display;
2291
2292 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
2293
2294 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2295 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2296 return;
2297
2298 display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
2299
2300 if (cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
2301 cdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
2302 {
2303 XClientMessageEvent xclient;
2304
2305 memset (&xclient, 0, sizeof (xclient));
2306 xclient.type = ClientMessage33;
2307 xclient.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)
;
2308 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (display,
2309 "_NET_ACTIVE_WINDOW");
2310 xclient.format = 32;
2311 xclient.data.l[0] = 1; /* requestor type; we're an app */
2312 xclient.data.l[1] = timestamp;
2313 xclient.data.l[2] = None0L; /* currently active window */
2314 xclient.data.l[3] = 0;
2315 xclient.data.l[4] = 0;
2316
2317 XSendEvent (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
2318 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
2319 (XEvent *)&xclient);
2320 }
2321 else
2322 {
2323 XRaiseWindow (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)
);
2324
2325 /* There is no way of knowing reliably whether we are viewable;
2326 * so trap errors asynchronously around the XSetInputFocus call
2327 */
2328 cdk_x11_display_error_trap_push (display);
2329 XSetInputFocus (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
2330 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)
,
2331 RevertToParent2,
2332 timestamp);
2333 cdk_x11_display_error_trap_pop_ignored (display);
2334 }
2335}
2336
2337static void
2338cdk_x11_window_set_type_hint (CdkWindow *window,
2339 CdkWindowTypeHint hint)
2340{
2341 CdkDisplay *display;
2342 Atom atom;
2343
2344 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2345 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2346 return;
2347
2348 display = cdk_window_get_display (window);
2349
2350 switch (hint)
2351 {
2352 case CDK_WINDOW_TYPE_HINT_DIALOG:
2353 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
2354 break;
2355 case CDK_WINDOW_TYPE_HINT_MENU:
2356 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
2357 break;
2358 case CDK_WINDOW_TYPE_HINT_TOOLBAR:
2359 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
2360 break;
2361 case CDK_WINDOW_TYPE_HINT_UTILITY:
2362 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
2363 break;
2364 case CDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2365 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
2366 break;
2367 case CDK_WINDOW_TYPE_HINT_DOCK:
2368 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
2369 break;
2370 case CDK_WINDOW_TYPE_HINT_DESKTOP:
2371 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
2372 break;
2373 case CDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
2374 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
2375 break;
2376 case CDK_WINDOW_TYPE_HINT_POPUP_MENU:
2377 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
2378 break;
2379 case CDK_WINDOW_TYPE_HINT_TOOLTIP:
2380 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
2381 break;
2382 case CDK_WINDOW_TYPE_HINT_NOTIFICATION:
2383 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
2384 break;
2385 case CDK_WINDOW_TYPE_HINT_COMBO:
2386 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
2387 break;
2388 case CDK_WINDOW_TYPE_HINT_DND:
2389 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
2390 break;
2391 default:
2392 g_warning ("Unknown hint %d passed to cdk_window_set_type_hint", hint);
2393 /* Fall thru */
2394 case CDK_WINDOW_TYPE_HINT_NORMAL:
2395 atom = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
2396 break;
2397 }
2398
2399 XChangeProperty (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)
,
2400 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2401 XA_ATOM((Atom) 4), 32, PropModeReplace0,
2402 (guchar *)&atom, 1);
2403}
2404
2405static CdkWindowTypeHint
2406cdk_x11_window_get_type_hint (CdkWindow *window)
2407{
2408 CdkDisplay *display;
2409 CdkWindowTypeHint type;
2410 Atom type_return;
2411 gint format_return;
2412 gulong nitems_return;
2413 gulong bytes_after_return;
2414 guchar *data = NULL((void*)0);
2415
2416 g_return_val_if_fail (CDK_IS_WINDOW (window), CDK_WINDOW_TYPE_HINT_NORMAL)do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return (CDK_WINDOW_TYPE_HINT_NORMAL
); } } while (0)
;
2417
2418 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2419 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2420 return CDK_WINDOW_TYPE_HINT_NORMAL;
2421
2422 type = CDK_WINDOW_TYPE_HINT_NORMAL;
2423
2424 display = cdk_window_get_display (window);
2425
2426 if (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)
,
2427 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2428 0, G_MAXLONG9223372036854775807L, False0, XA_ATOM((Atom) 4), &type_return,
2429 &format_return, &nitems_return, &bytes_after_return,
2430 &data) == Success0)
2431 {
2432 if ((type_return == XA_ATOM((Atom) 4)) && (format_return == 32) &&
2433 (data) && (nitems_return == 1))
2434 {
2435 Atom atom = *(Atom*)data;
2436
2437 if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
2438 type = CDK_WINDOW_TYPE_HINT_DIALOG;
2439 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"))
2440 type = CDK_WINDOW_TYPE_HINT_MENU;
2441 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
2442 type = CDK_WINDOW_TYPE_HINT_TOOLBAR;
2443 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY"))
2444 type = CDK_WINDOW_TYPE_HINT_UTILITY;
2445 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH"))
2446 type = CDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
2447 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK"))
2448 type = CDK_WINDOW_TYPE_HINT_DOCK;
2449 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
2450 type = CDK_WINDOW_TYPE_HINT_DESKTOP;
2451 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
2452 type = CDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
2453 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
2454 type = CDK_WINDOW_TYPE_HINT_POPUP_MENU;
2455 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
2456 type = CDK_WINDOW_TYPE_HINT_TOOLTIP;
2457 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
2458 type = CDK_WINDOW_TYPE_HINT_NOTIFICATION;
2459 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
2460 type = CDK_WINDOW_TYPE_HINT_COMBO;
2461 else if (atom == cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
2462 type = CDK_WINDOW_TYPE_HINT_DND;
2463 }
2464
2465 if (type_return != None0L && data != NULL((void*)0))
2466 XFree (data);
2467 }
2468
2469 return type;
2470}
2471
2472static void
2473cdk_wmspec_change_state (gboolean add,
2474 CdkWindow *window,
2475 CdkAtom state1,
2476 CdkAtom state2)
2477{
2478 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)
;
2479 XClientMessageEvent xclient;
2480
2481#define _NET_WM_STATE_REMOVE0 0 /* remove/unset property */
2482#define _NET_WM_STATE_ADD1 1 /* add/set property */
2483#define _NET_WM_STATE_TOGGLE2 2 /* toggle property */
2484
2485 memset (&xclient, 0, sizeof (xclient));
2486 xclient.type = ClientMessage33;
2487 xclient.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)
;
2488 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
2489 xclient.format = 32;
2490 xclient.data.l[0] = add ? _NET_WM_STATE_ADD1 : _NET_WM_STATE_REMOVE0;
2491 xclient.data.l[1] = cdk_x11_atom_to_xatom_for_display (display, state1);
2492 xclient.data.l[2] = cdk_x11_atom_to_xatom_for_display (display, state2);
2493 xclient.data.l[3] = 1; /* source indication */
2494 xclient.data.l[4] = 0;
2495
2496 XSendEvent (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
2497 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
2498 (XEvent *)&xclient);
2499}
2500
2501static void
2502cdk_x11_window_set_modal_hint (CdkWindow *window,
2503 gboolean modal)
2504{
2505 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2506 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2507 return;
2508
2509 window->modal_hint = modal;
2510
2511 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
2512 cdk_wmspec_change_state (modal, window,
2513 cdk_atom_intern_static_string ("_NET_WM_STATE_MODAL"),
2514 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
2515}
2516
2517static void
2518cdk_x11_window_set_skip_taskbar_hint (CdkWindow *window,
2519 gboolean skips_taskbar)
2520{
2521 CdkToplevelX11 *toplevel;
2522
2523 g_return_if_fail (CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD)do { if ((((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD
)) { } else { g_return_if_fail_warning ("Cdk", ((const char*)
(__func__)), "CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD")
; return; } } while (0)
;
2524
2525 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2526 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2527 return;
2528
2529 toplevel = _cdk_x11_window_get_toplevel (window);
2530 toplevel->skip_taskbar_hint = skips_taskbar;
2531
2532 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
2533 cdk_wmspec_change_state (skips_taskbar, window,
2534 cdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_TASKBAR"),
2535 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
2536}
2537
2538static void
2539cdk_x11_window_set_skip_pager_hint (CdkWindow *window,
2540 gboolean skips_pager)
2541{
2542 CdkToplevelX11 *toplevel;
2543
2544 g_return_if_fail (CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD)do { if ((((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD
)) { } else { g_return_if_fail_warning ("Cdk", ((const char*)
(__func__)), "CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD")
; return; } } while (0)
;
2545
2546 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2547 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2548 return;
2549
2550 toplevel = _cdk_x11_window_get_toplevel (window);
2551 toplevel->skip_pager_hint = skips_pager;
2552
2553 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
2554 cdk_wmspec_change_state (skips_pager, window,
2555 cdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_PAGER"),
2556 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
2557}
2558
2559static void
2560cdk_x11_window_set_urgency_hint (CdkWindow *window,
2561 gboolean urgent)
2562{
2563 CdkToplevelX11 *toplevel;
2564
2565 g_return_if_fail (CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD)do { if ((((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD
)) { } else { g_return_if_fail_warning ("Cdk", ((const char*)
(__func__)), "CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD")
; return; } } while (0)
;
2566
2567 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2568 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2569 return;
2570
2571 toplevel = _cdk_x11_window_get_toplevel (window);
2572 toplevel->urgency_hint = urgent;
2573
2574 update_wm_hints (window, FALSE(0));
2575}
2576
2577static void
2578cdk_x11_window_set_geometry_hints (CdkWindow *window,
2579 const CdkGeometry *geometry,
2580 CdkWindowHints geom_mask)
2581{
2582 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
2583 XSizeHints size_hints;
2584 CdkToplevelX11 *toplevel;
2585
2586 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
1
Assuming field 'destroyed' is 0
3
Taking false branch
2587 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2
Assuming field 'window_type' is equal to CDK_WINDOW_TOPLEVEL
2588 return;
2589
2590 toplevel = _cdk_x11_window_get_toplevel (window);
2591 if (toplevel)
4
Assuming 'toplevel' is non-null
5
Taking true branch
2592 {
2593 if (geometry)
6
Assuming 'geometry' is null
7
Taking false branch
2594 toplevel->last_geometry_hints = *geometry;
2595 toplevel->last_geometry_hints_mask = geom_mask;
2596 }
2597
2598 size_hints.flags = 0;
2599
2600 if (geom_mask & CDK_HINT_POS)
8
Assuming the condition is false
9
Taking false branch
2601 {
2602 size_hints.flags |= PPosition(1L << 2);
2603 /* We need to initialize the following obsolete fields because KWM
2604 * apparently uses these fields if they are non-zero.
2605 * #@#!#!$!.
2606 */
2607 size_hints.x = 0;
2608 size_hints.y = 0;
2609 }
2610
2611 if (geom_mask & CDK_HINT_USER_POS)
10
Assuming the condition is false
11
Taking false branch
2612 {
2613 size_hints.flags |= USPosition(1L << 0);
2614 }
2615
2616 if (geom_mask & CDK_HINT_USER_SIZE)
12
Assuming the condition is false
13
Taking false branch
2617 {
2618 size_hints.flags |= USSize(1L << 1);
2619 }
2620
2621 if (geom_mask & CDK_HINT_MIN_SIZE)
14
Assuming the condition is false
15
Taking false branch
2622 {
2623 size_hints.flags |= PMinSize(1L << 4);
2624 size_hints.min_width = geometry->min_width * impl->window_scale;
2625 size_hints.min_height = geometry->min_height * impl->window_scale;
2626 }
2627
2628 if (geom_mask & CDK_HINT_MAX_SIZE)
16
Assuming the condition is false
17
Taking false branch
2629 {
2630 size_hints.flags |= PMaxSize(1L << 5);
2631 size_hints.max_width = MAX (geometry->max_width, 1)(((geometry->max_width) > (1)) ? (geometry->max_width
) : (1))
* impl->window_scale;
2632 size_hints.max_height = MAX (geometry->max_height, 1)(((geometry->max_height) > (1)) ? (geometry->max_height
) : (1))
* impl->window_scale;
2633 }
2634
2635 if (geom_mask & CDK_HINT_BASE_SIZE)
18
Assuming the condition is true
19
Taking true branch
2636 {
2637 size_hints.flags |= PBaseSize(1L << 8);
2638 size_hints.base_width = geometry->base_width * impl->window_scale;
20
Access to field 'base_width' results in a dereference of a null pointer (loaded from variable 'geometry')
2639 size_hints.base_height = geometry->base_height * impl->window_scale;
2640 }
2641
2642 if (geom_mask & CDK_HINT_RESIZE_INC)
2643 {
2644 size_hints.flags |= PResizeInc(1L << 6);
2645 size_hints.width_inc = geometry->width_inc * impl->window_scale;
2646 size_hints.height_inc = geometry->height_inc * impl->window_scale;
2647 }
2648 else if (impl->window_scale > 1)
2649 {
2650 size_hints.flags |= PResizeInc(1L << 6);
2651 size_hints.width_inc = impl->window_scale;
2652 size_hints.height_inc = impl->window_scale;
2653 }
2654
2655 if (geom_mask & CDK_HINT_ASPECT)
2656 {
2657 size_hints.flags |= PAspect(1L << 7);
2658 if (geometry->min_aspect <= 1)
2659 {
2660 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2661 size_hints.min_aspect.y = 65536;
2662 }
2663 else
2664 {
2665 size_hints.min_aspect.x = 65536;
2666 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2667 }
2668 if (geometry->max_aspect <= 1)
2669 {
2670 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2671 size_hints.max_aspect.y = 65536;
2672 }
2673 else
2674 {
2675 size_hints.max_aspect.x = 65536;
2676 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2677 }
2678 }
2679
2680 if (geom_mask & CDK_HINT_WIN_GRAVITY)
2681 {
2682 size_hints.flags |= PWinGravity(1L << 9);
2683 size_hints.win_gravity = geometry->win_gravity;
2684 }
2685
2686 /* FIXME: Would it be better to delete this property if
2687 * geom_mask == 0? It would save space on the server
2688 */
2689 XSetWMNormalHints (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2690 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)
,
2691 &size_hints);
2692}
2693
2694static void
2695cdk_window_get_geometry_hints (CdkWindow *window,
2696 CdkGeometry *geometry,
2697 CdkWindowHints *geom_mask)
2698{
2699 CdkWindowImplX11 *impl;
2700 XSizeHints *size_hints;
2701 glong junk_supplied_mask = 0;
2702
2703 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
2704 g_return_if_fail (geometry != NULL)do { if ((geometry != ((void*)0))) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "geometry != NULL"); return
; } } while (0)
;
2705 g_return_if_fail (geom_mask != NULL)do { if ((geom_mask != ((void*)0))) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "geom_mask != NULL"); return
; } } while (0)
;
2706
2707 *geom_mask = 0;
2708
2709 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2710 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2711 return;
2712
2713 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
2714
2715 size_hints = XAllocSizeHints ();
2716 if (!size_hints)
2717 return;
2718
2719 if (!XGetWMNormalHints (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2720 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)
,
2721 size_hints,
2722 &junk_supplied_mask))
2723 size_hints->flags = 0;
2724
2725 if (size_hints->flags & PMinSize(1L << 4))
2726 {
2727 *geom_mask |= CDK_HINT_MIN_SIZE;
2728 geometry->min_width = size_hints->min_width / impl->window_scale;
2729 geometry->min_height = size_hints->min_height / impl->window_scale;
2730 }
2731
2732 if (size_hints->flags & PMaxSize(1L << 5))
2733 {
2734 *geom_mask |= CDK_HINT_MAX_SIZE;
2735 geometry->max_width = MAX (size_hints->max_width, 1)(((size_hints->max_width) > (1)) ? (size_hints->max_width
) : (1))
/ impl->window_scale;
2736 geometry->max_height = MAX (size_hints->max_height, 1)(((size_hints->max_height) > (1)) ? (size_hints->max_height
) : (1))
/ impl->window_scale;
2737 }
2738
2739 if (size_hints->flags & PResizeInc(1L << 6))
2740 {
2741 *geom_mask |= CDK_HINT_RESIZE_INC;
2742 geometry->width_inc = size_hints->width_inc / impl->window_scale;
2743 geometry->height_inc = size_hints->height_inc / impl->window_scale;
2744 }
2745
2746 if (size_hints->flags & PAspect(1L << 7))
2747 {
2748 *geom_mask |= CDK_HINT_ASPECT;
2749
2750 geometry->min_aspect = (gdouble) size_hints->min_aspect.x / (gdouble) size_hints->min_aspect.y;
2751 geometry->max_aspect = (gdouble) size_hints->max_aspect.x / (gdouble) size_hints->max_aspect.y;
2752 }
2753
2754 if (size_hints->flags & PWinGravity(1L << 9))
2755 {
2756 *geom_mask |= CDK_HINT_WIN_GRAVITY;
2757 geometry->win_gravity = size_hints->win_gravity;
2758 }
2759
2760 XFree (size_hints);
2761}
2762
2763static gboolean
2764utf8_is_latin1 (const gchar *str)
2765{
2766 const char *p = str;
2767
2768 while (*p)
2769 {
2770 gunichar ch = g_utf8_get_char (p);
2771
2772 if (ch > 0xff)
2773 return FALSE(0);
2774
2775 p = g_utf8_next_char (p)((p) + g_utf8_skip[*(const guchar *)(p)]);
2776 }
2777
2778 return TRUE(!(0));
2779}
2780
2781/* Set the property to @utf8_str as STRING if the @utf8_str is fully
2782 * convertable to STRING, otherwise, set it as compound text
2783 */
2784static void
2785set_text_property (CdkDisplay *display,
2786 Window xwindow,
2787 Atom property,
2788 const gchar *utf8_str)
2789{
2790 gchar *prop_text = NULL((void*)0);
2791 Atom prop_type;
2792 gint prop_length;
2793 gint prop_format;
2794 gboolean is_compound_text;
2795
2796 if (utf8_is_latin1 (utf8_str))
2797 {
2798 prop_type = XA_STRING((Atom) 31);
2799 prop_text = _cdk_x11_display_utf8_to_string_target (display, utf8_str);
2800 prop_length = prop_text ? strlen (prop_text) : 0;
2801 prop_format = 8;
2802 is_compound_text = FALSE(0);
2803 }
2804 else
2805 {
2806 CdkAtom cdk_type;
2807
2808 cdk_x11_display_utf8_to_compound_text (display,
2809 utf8_str, &cdk_type, &prop_format,
2810 (guchar **)&prop_text, &prop_length);
2811 prop_type = cdk_x11_atom_to_xatom_for_display (display, cdk_type);
2812 is_compound_text = TRUE(!(0));
2813 }
2814
2815 if (prop_text)
2816 {
2817 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
2818 xwindow,
2819 property,
2820 prop_type, prop_format,
2821 PropModeReplace0, (guchar *)prop_text,
2822 prop_length);
2823
2824 if (is_compound_text)
2825 cdk_x11_free_compound_text ((guchar *)prop_text);
2826 else
2827 g_free (prop_text);
2828 }
2829}
2830
2831/* Set WM_NAME and _NET_WM_NAME
2832 */
2833static void
2834set_wm_name (CdkDisplay *display,
2835 Window xwindow,
2836 const gchar *name)
2837{
2838 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xwindow,
2839 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2840 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2841 PropModeReplace0, (guchar *)name, strlen (name));
2842
2843 set_text_property (display, xwindow,
2844 cdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2845 name);
2846}
2847
2848static void
2849cdk_x11_window_set_title (CdkWindow *window,
2850 const gchar *title)
2851{
2852 CdkDisplay *display;
2853 Display *xdisplay;
2854 Window xwindow;
2855
2856 g_return_if_fail (title != NULL)do { if ((title != ((void*)0))) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "title != NULL"); return
; } } while (0)
;
2857
2858 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2859 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2860 return;
2861
2862 display = cdk_window_get_display (window);
2863 xdisplay = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
2864 xwindow = 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)
;
2865
2866 set_wm_name (display, xwindow, title);
2867
2868 if (!cdk_window_icon_name_set (window))
2869 {
2870 XChangeProperty (xdisplay, xwindow,
2871 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2872 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2873 PropModeReplace0, (guchar *)title, strlen (title));
2874
2875 set_text_property (display, xwindow,
2876 cdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2877 title);
2878 }
2879}
2880
2881static void
2882cdk_x11_window_set_role (CdkWindow *window,
2883 const gchar *role)
2884{
2885 CdkDisplay *display;
2886
2887 display = cdk_window_get_display (window);
2888
2889 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2890 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2891 return;
2892
2893 if (role)
2894 XChangeProperty (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)
,
2895 cdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2896 XA_STRING((Atom) 31), 8, PropModeReplace0, (guchar *)role, strlen (role));
2897 else
2898 XDeleteProperty (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)
,
2899 cdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2900}
2901
2902static void
2903cdk_x11_window_set_startup_id (CdkWindow *window,
2904 const gchar *startup_id)
2905{
2906 CdkDisplay *display;
2907
2908 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
2909
2910 display = cdk_window_get_display (window);
2911
2912 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
2913 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2914 return;
2915
2916 if (startup_id)
2917 XChangeProperty (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)
,
2918 cdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
2919 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2920 PropModeReplace0, (unsigned char *)startup_id, strlen (startup_id));
2921 else
2922 XDeleteProperty (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)
,
2923 cdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
2924}
2925
2926static void
2927cdk_x11_window_set_transient_for (CdkWindow *window,
2928 CdkWindow *parent)
2929{
2930 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) && !CDK_WINDOW_DESTROYED (parent)(((CdkWindow *)(parent))->destroyed) &&
2931 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
2932 XSetTransientForHint (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2933 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)
,
2934 CDK_WINDOW_XID (parent)(((((CdkWindowImplX11*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWindow*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((parent)), ((cdk_window_get_type ()))))))
->impl)), ((cdk_window_impl_x11_get_type ()))))))->xid)
);
2935}
2936
2937static gboolean
2938cdk_window_x11_set_back_color (CdkWindow *window,
2939 double red,
2940 double green,
2941 double blue,
2942 double alpha)
2943{
2944 CdkVisual *visual = cdk_window_get_visual (window);
2945
2946 /* I suppose we could handle these, but that'd require fiddling with
2947 * xrender formats... */
2948 if (alpha != 1.0)
2949 return FALSE(0);
2950
2951 switch (visual->type)
2952 {
2953 case CDK_VISUAL_DIRECT_COLOR:
2954 case CDK_VISUAL_TRUE_COLOR:
2955 {
2956 /* If bits not used for color are used for something other than padding,
2957 * it's likely alpha, so we set them to 1s.
2958 */
2959 guint padding, pixel;
2960 gint red_prec, red_shift, green_prec, green_shift, blue_prec, blue_shift;
2961
2962 /* Shifting by >= width-of-type isn't defined in C */
2963 if (visual->depth >= 32)
2964 padding = 0;
2965 else
2966 padding = ((~(guint32)0)) << visual->depth;
2967
2968 pixel = ~ (visual->red_mask | visual->green_mask | visual->blue_mask | padding);
2969
2970 cdk_visual_get_red_pixel_details (visual, NULL((void*)0), &red_shift, &red_prec);
2971 cdk_visual_get_green_pixel_details (visual, NULL((void*)0), &green_shift, &green_prec);
2972 cdk_visual_get_blue_pixel_details (visual, NULL((void*)0), &blue_shift, &blue_prec);
2973
2974 pixel += (((int) (red * ((1 << red_prec ) - 1))) << red_shift ) +
2975 (((int) (green * ((1 << green_prec) - 1))) << green_shift) +
2976 (((int) (blue * ((1 << blue_prec ) - 1))) << blue_shift );
2977
2978 XSetWindowBackground (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
2979 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)
, pixel);
2980 }
2981 return TRUE(!(0));
2982
2983 /* These require fiddling with the colormap, and as they're essentially unused
2984 * we're just gonna skip them for now.
2985 */
2986 case CDK_VISUAL_PSEUDO_COLOR:
2987 case CDK_VISUAL_GRAYSCALE:
2988 case CDK_VISUAL_STATIC_GRAY:
2989 case CDK_VISUAL_STATIC_COLOR:
2990 default:
2991 break;
2992 }
2993
2994 return FALSE(0);
2995}
2996
2997static gboolean
2998matrix_is_identity (cairo_matrix_t *matrix)
2999{
3000 return matrix->xx == 1.0 && matrix->yy == 1.0 &&
3001 matrix->yx == 0.0 && matrix->xy == 0.0 &&
3002 matrix->x0 == 0.0 && matrix->y0 == 0.0;
3003}
3004
3005static void
3006cdk_window_x11_set_background (CdkWindow *window,
3007 cairo_pattern_t *pattern)
3008{
3009 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3010 double r, g, b, a;
3011 cairo_surface_t *surface;
3012 cairo_matrix_t matrix;
3013 cairo_pattern_t *parent_relative_pattern;
3014
3015 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3016 return;
3017
3018 if (pattern == NULL((void*)0))
3019 {
3020 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3021 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)
, None0L);
3022 return;
3023 }
3024
3025G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
3026 parent_relative_pattern = cdk_x11_get_parent_relative_pattern ();
3027G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop
3028
3029 if (pattern == parent_relative_pattern)
3030 {
3031 Window xroot, xparent, *xchildren;
3032 guint nxchildren, xparent_depth;
3033 XWindowAttributes xattrs;
3034
3035 if (!XQueryTree (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
,
3036 &xroot, &xparent, &xchildren, &nxchildren))
3037 {
3038 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3039 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)
, None0L);
3040 return;
3041 }
3042
3043 if (xchildren)
3044 XFree (xchildren);
3045
3046 if (xparent) {
3047 XGetWindowAttributes (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, xparent, &xattrs);
3048 xparent_depth = xattrs.depth;
3049 }
3050
3051 /* X throws BadMatch if the parent has a different depth when
3052 * using ParentRelative */
3053 if (xparent && window->depth == xparent_depth &&
3054 cairo_pattern_status (pattern) == CAIRO_STATUS_SUCCESS)
3055 {
3056 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3057 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)
, ParentRelative1L);
3058 return;
3059 }
3060 else
3061 {
3062 g_warning ("Can't set ParentRelative background for window %#lx, depth of parent doesn't match",
3063 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)
);
3064 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3065 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)
, None0L);
3066 return;
3067 }
3068 }
3069
3070 switch (cairo_pattern_get_type (pattern))
3071 {
3072 case CAIRO_PATTERN_TYPE_SOLID:
3073 cairo_pattern_get_rgba (pattern, &r, &g, &b, &a);
3074 if (cdk_window_x11_set_back_color (window, r, g, b, a))
3075 return;
3076 break;
3077 case CAIRO_PATTERN_TYPE_SURFACE:
3078 cairo_pattern_get_matrix (pattern, &matrix);
3079 if (cairo_pattern_get_surface (pattern, &surface) == CAIRO_STATUS_SUCCESS &&
3080 matrix_is_identity (&matrix) &&
3081 cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB &&
3082 cairo_xlib_surface_get_visual (surface) == CDK_VISUAL_XVISUAL (cdk_window_get_visual ((window)))(cdk_x11_visual_get_xvisual (cdk_window_get_visual ((window))
))
&&
3083 cairo_xlib_surface_get_display (surface) == CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
)
3084 {
3085 double x, y, sx, sy;
3086
3087 cairo_surface_get_device_offset (surface, &x, &y);
3088 sx = sy = 1.;
3089 cairo_surface_get_device_scale (surface, &sx, &sy);
3090 /* XXX: This still bombs for non-pixmaps, but there's no way to
3091 * detect we're not a pixmap in Cairo... */
3092 if (x == 0.0 && y == 0.0 &&
3093 sx == impl->window_scale && sy == impl->window_scale)
3094 {
3095 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3096 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)
,
3097 cairo_xlib_surface_get_drawable (surface));
3098 return;
3099 }
3100 }
3101 /* fall through */
3102 case CAIRO_PATTERN_TYPE_LINEAR:
3103 case CAIRO_PATTERN_TYPE_RADIAL:
3104 default:
3105 /* fallback: just use black */
3106 break;
3107 }
3108
3109 XSetWindowBackgroundPixmap (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3110 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)
, None0L);
3111}
3112
3113static void
3114cdk_window_x11_set_device_cursor (CdkWindow *window,
3115 CdkDevice *device,
3116 CdkCursor *cursor)
3117{
3118 CdkWindowImplX11 *impl;
3119
3120 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
3121 g_return_if_fail (CDK_IS_DEVICE (device))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((device)); GType __t = ((cdk_device_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_DEVICE (device)"); return; } } while (0)
;
3122
3123 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3124
3125 if (!cursor)
3126 g_hash_table_remove (impl->device_cursor, device);
3127 else
3128 {
3129 _cdk_x11_cursor_update_theme (cursor);
3130 g_hash_table_replace (impl->device_cursor,
3131 device, g_object_ref (cursor)((__typeof__ (cursor)) (g_object_ref) (cursor)));
3132 }
3133
3134 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3135 CDK_DEVICE_GET_CLASS (device)((((CdkDeviceClass*) (((GTypeInstance*) ((device)))->g_class
))))
->set_window_cursor (device, window, cursor);
3136}
3137
3138CdkCursor *
3139_cdk_x11_window_get_cursor (CdkWindow *window)
3140{
3141 CdkWindowImplX11 *impl;
3142
3143 g_return_val_if_fail (CDK_IS_WINDOW (window), NULL)do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return (((void*)0)); } } while
(0)
;
3144
3145 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3146
3147 return impl->cursor;
3148}
3149
3150static void
3151cdk_window_x11_get_geometry (CdkWindow *window,
3152 gint *x,
3153 gint *y,
3154 gint *width,
3155 gint *height)
3156{
3157 Window root;
3158 gint tx;
3159 gint ty;
3160 guint twidth;
3161 guint theight;
3162 guint tborder_width;
3163 guint tdepth;
3164
3165 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3166 {
3167 CdkWindowImplX11 *impl;
3168
3169 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3170
3171 XGetGeometry (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3172 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)
,
3173 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
3174
3175 if (x)
3176 *x = tx / impl->window_scale;
3177 if (y)
3178 *y = ty / impl->window_scale;
3179 if (width)
3180 *width = twidth / impl->window_scale;
3181 if (height)
3182 *height = theight / impl->window_scale;
3183 }
3184}
3185
3186static void
3187cdk_window_x11_get_root_coords (CdkWindow *window,
3188 gint x,
3189 gint y,
3190 gint *root_x,
3191 gint *root_y)
3192{
3193 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3194 Window child;
3195 gint tx;
3196 gint ty;
3197
3198 XTranslateCoordinates (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3199 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)
,
3200 CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
,
3201 x * impl->window_scale, y * impl->window_scale, &tx, &ty,
3202 &child);
3203
3204 if (root_x)
3205 *root_x = tx / impl->window_scale;
3206 if (root_y)
3207 *root_y = ty / impl->window_scale;
3208}
3209
3210static void
3211cdk_x11_window_get_frame_extents (CdkWindow *window,
3212 CdkRectangle *rect)
3213{
3214 CdkDisplay *display;
3215 CdkWindowImplX11 *impl;
3216 Window xwindow;
3217 Window xparent;
3218 Window root;
3219 Window child;
3220 Window *children;
3221 guchar *data;
3222 Window *vroots;
3223 Atom type_return;
3224 guint nchildren;
3225 guint nvroots;
3226 gulong nitems_return;
3227 gulong bytes_after_return;
3228 gint format_return;
3229 gint i;
3230 guint ww, wh, wb, wd;
3231 gint wx, wy;
3232 gboolean got_frame_extents = FALSE(0);
3233
3234 g_return_if_fail (rect != NULL)do { if ((rect != ((void*)0))) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "rect != NULL"); return;
} } while (0)
;
3235
3236 rect->x = 0;
3237 rect->y = 0;
3238 rect->width = 1;
3239 rect->height = 1;
3240
3241 while (window->parent && (window->parent)->parent)
3242 window = window->parent;
3243
3244 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3245
3246 /* Refine our fallback answer a bit using local information */
3247 rect->x = window->x * impl->window_scale;
3248 rect->y = window->y * impl->window_scale;
3249 rect->width = window->width * impl->window_scale;
3250 rect->height = window->height * impl->window_scale;
3251
3252 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) || impl->override_redirect)
3253 return;
3254
3255 nvroots = 0;
3256 vroots = NULL((void*)0);
3257
3258 display = cdk_window_get_display (window);
3259
3260 cdk_x11_display_error_trap_push (display);
3261
3262 xwindow = 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)
;
3263
3264 /* first try: use _NET_FRAME_EXTENTS */
3265 if (cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
3266 cdk_atom_intern_static_string ("_NET_FRAME_EXTENTS")) &&
3267 XGetWindowProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xwindow,
3268 cdk_x11_get_xatom_by_name_for_display (display,
3269 "_NET_FRAME_EXTENTS"),
3270 0, G_MAXLONG9223372036854775807L, False0, XA_CARDINAL((Atom) 6), &type_return,
3271 &format_return, &nitems_return, &bytes_after_return,
3272 &data)
3273 == Success0)
3274 {
3275 if ((type_return == XA_CARDINAL((Atom) 6)) && (format_return == 32) &&
3276 (nitems_return == 4) && (data))
3277 {
3278 gulong *ldata = (gulong *) data;
3279 got_frame_extents = TRUE(!(0));
3280
3281 /* try to get the real client window geometry */
3282 if (XGetGeometry (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xwindow,
3283 &root, &wx, &wy, &ww, &wh, &wb, &wd) &&
3284 XTranslateCoordinates (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3285 xwindow, root, 0, 0, &wx, &wy, &child))
3286 {
3287 rect->x = wx;
3288 rect->y = wy;
3289 rect->width = ww;
3290 rect->height = wh;
3291 }
3292
3293 /* _NET_FRAME_EXTENTS format is left, right, top, bottom */
3294 rect->x -= ldata[0];
3295 rect->y -= ldata[2];
3296 rect->width += ldata[0] + ldata[1];
3297 rect->height += ldata[2] + ldata[3];
3298 }
3299
3300 if (data)
3301 XFree (data);
3302 }
3303
3304 if (got_frame_extents)
3305 goto out;
3306
3307 /* no frame extents property available, which means we either have a WM that
3308 is not EWMH compliant or is broken - try fallback and walk up the window
3309 tree to get our window's parent which hopefully is the window frame */
3310
3311 /* use NETWM_VIRTUAL_ROOTS if available */
3312 root = CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
;
3313
3314 if (cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
3315 cdk_atom_intern_static_string ("_NET_VIRTUAL_ROOTS")) &&
3316 XGetWindowProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, root,
3317 cdk_x11_get_xatom_by_name_for_display (display,
3318 "_NET_VIRTUAL_ROOTS"),
3319 0, G_MAXLONG9223372036854775807L, False0, XA_WINDOW((Atom) 33), &type_return,
3320 &format_return, &nitems_return, &bytes_after_return,
3321 &data)
3322 == Success0)
3323 {
3324 if ((type_return == XA_WINDOW((Atom) 33)) && (format_return == 32) && (data))
3325 {
3326 nvroots = nitems_return;
3327 vroots = (Window *)data;
3328 }
3329 }
3330
3331 xparent = 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)
;
3332
3333 do
3334 {
3335 xwindow = xparent;
3336
3337 if (!XQueryTree (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xwindow,
3338 &root, &xparent,
3339 &children, &nchildren))
3340 goto out;
3341
3342 if (children)
3343 XFree (children);
3344
3345 /* check virtual roots */
3346 for (i = 0; i < nvroots; i++)
3347 {
3348 if (xparent == vroots[i])
3349 {
3350 root = xparent;
3351 break;
3352 }
3353 }
3354 }
3355 while (xparent != root);
3356
3357 if (XGetGeometry (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xwindow,
3358 &root, &wx, &wy, &ww, &wh, &wb, &wd))
3359 {
3360 rect->x = wx;
3361 rect->y = wy;
3362 rect->width = ww;
3363 rect->height = wh;
3364 }
3365
3366 out:
3367 if (vroots)
3368 XFree (vroots);
3369
3370 /* Here we extend the size to include the extra pixels if we round x/y down
3371 as well as round the size up when we divide by scale so that the returned
3372 size is guaranteed to cover the real pixels, but it may overshoot a bit
3373 in case the window is not positioned/sized according to the scale */
3374 rect->width = (rect->width + rect->x % impl->window_scale + impl->window_scale - 1) / impl->window_scale;
3375 rect->height = (rect->height + rect->y % impl->window_scale + impl->window_scale - 1) / impl->window_scale;
3376 rect->x = rect->x / impl->window_scale;
3377 rect->y = rect->y / impl->window_scale;
3378 cdk_x11_display_error_trap_pop_ignored (display);
3379}
3380
3381static gboolean
3382cdk_window_x11_get_device_state (CdkWindow *window,
3383 CdkDevice *device,
3384 gdouble *x,
3385 gdouble *y,
3386 CdkModifierType *mask)
3387{
3388 CdkWindow *child;
3389
3390 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3391 return FALSE(0);
3392
3393 /*HIDPI: handle coords here?*/
3394 CDK_DEVICE_GET_CLASS (device)((((CdkDeviceClass*) (((GTypeInstance*) ((device)))->g_class
))))
->query_state (device, window,
3395 NULL((void*)0), &child,
3396 NULL((void*)0), NULL((void*)0),
3397 x, y, mask);
3398 return child != NULL((void*)0);
3399}
3400
3401static CdkEventMask
3402cdk_window_x11_get_events (CdkWindow *window)
3403{
3404 XWindowAttributes attrs;
3405 CdkEventMask event_mask;
3406 CdkEventMask filtered;
3407
3408 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3409 return 0;
3410 else
3411 {
3412 XGetWindowAttributes (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3413 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)
,
3414 &attrs);
3415 event_mask = x_event_mask_to_cdk_event_mask (attrs.your_event_mask);
3416 /* if property change was filtered out before, keep it filtered out */
3417 filtered = CDK_STRUCTURE_MASK | CDK_PROPERTY_CHANGE_MASK;
3418 window->event_mask = event_mask & ((window->event_mask & filtered) | ~filtered);
3419
3420 return event_mask;
3421 }
3422}
3423static void
3424cdk_window_x11_set_events (CdkWindow *window,
3425 CdkEventMask event_mask)
3426{
3427 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3428 {
3429 CdkX11Display *display_x11;
3430 long xevent_mask = 0;
3431
3432 if (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)
!= CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
)
3433 xevent_mask = StructureNotifyMask(1L<<17) | PropertyChangeMask(1L<<22);
3434
3435 display_x11 = CDK_X11_DISPLAY (cdk_window_get_display (window))((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cdk_window_get_display (window))), ((cdk_x11_display_get_type
()))))))
;
3436 cdk_x11_event_source_select_events ((CdkEventSource *) display_x11->event_source,
3437 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)
, event_mask,
3438 xevent_mask);
3439 }
3440}
3441
3442static inline void
3443do_shape_combine_region (CdkWindow *window,
3444 const cairo_region_t *shape_region,
3445 gint offset_x,
3446 gint offset_y,
3447 gint shape)
3448{
3449 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3450
3451 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
3452 return;
3453
3454 if (shape_region == NULL((void*)0))
3455 {
3456 /* Use NULL mask to unset the shape */
3457 if (shape == ShapeBounding0
3458 ? cdk_display_supports_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
)
3459 : cdk_display_supports_input_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
))
3460 {
3461 if (shape == ShapeBounding0)
3462 {
3463 _cdk_x11_window_tmp_unset_parent_bg (window);
3464 _cdk_x11_window_tmp_unset_bg (window, TRUE(!(0)));
3465 }
3466 XShapeCombineMask (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3467 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)
,
3468 shape,
3469 0, 0,
3470 None0L,
3471 ShapeSet0);
3472 if (shape == ShapeBounding0)
3473 {
3474 _cdk_x11_window_tmp_reset_parent_bg (window);
3475 _cdk_x11_window_tmp_reset_bg (window, TRUE(!(0)));
3476 }
3477 }
3478 return;
3479 }
3480
3481 if (shape == ShapeBounding0
3482 ? cdk_display_supports_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
)
3483 : cdk_display_supports_input_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
))
3484 {
3485 gint n_rects = 0;
3486 XRectangle *xrects = NULL((void*)0);
3487
3488 _cdk_x11_region_get_xrectangles (shape_region,
3489 0, 0, impl->window_scale,
3490 &xrects, &n_rects);
3491
3492 if (shape == ShapeBounding0)
3493 {
3494 _cdk_x11_window_tmp_unset_parent_bg (window);
3495 _cdk_x11_window_tmp_unset_bg (window, TRUE(!(0)));
3496 }
3497 XShapeCombineRectangles (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3498 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)
,
3499 shape,
3500 offset_x * impl->window_scale,
3501 offset_y * impl->window_scale,
3502 xrects, n_rects,
3503 ShapeSet0,
3504 YXBanded3);
3505
3506 if (shape == ShapeBounding0)
3507 {
3508 _cdk_x11_window_tmp_reset_parent_bg (window);
3509 _cdk_x11_window_tmp_reset_bg (window, TRUE(!(0)));
3510 }
3511
3512 g_free (xrects);
3513 }
3514}
3515
3516static void
3517cdk_window_x11_shape_combine_region (CdkWindow *window,
3518 const cairo_region_t *shape_region,
3519 gint offset_x,
3520 gint offset_y)
3521{
3522 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding0);
3523}
3524
3525static void
3526cdk_window_x11_input_shape_combine_region (CdkWindow *window,
3527 const cairo_region_t *shape_region,
3528 gint offset_x,
3529 gint offset_y)
3530{
3531#ifdef ShapeInput2
3532 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput2);
3533#endif
3534}
3535
3536
3537static void
3538cdk_x11_window_set_override_redirect (CdkWindow *window,
3539 gboolean override_redirect)
3540{
3541 XSetWindowAttributes attr;
3542
3543 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) &&
3544 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
3545 {
3546 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3547
3548 attr.override_redirect = (override_redirect? True1 : False0);
3549 XChangeWindowAttributes (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3550 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)
,
3551 CWOverrideRedirect(1L<<9),
3552 &attr);
3553
3554 impl->override_redirect = attr.override_redirect;
3555 }
3556}
3557
3558static void
3559cdk_x11_window_set_accept_focus (CdkWindow *window,
3560 gboolean accept_focus)
3561{
3562 accept_focus = accept_focus != FALSE(0);
3563
3564 if (window->accept_focus != accept_focus)
3565 {
3566 window->accept_focus = accept_focus;
3567
3568 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) &&
3569 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
3570 update_wm_hints (window, FALSE(0));
3571 }
3572}
3573
3574static void
3575cdk_x11_window_set_focus_on_map (CdkWindow *window,
3576 gboolean focus_on_map)
3577{
3578 focus_on_map = focus_on_map != FALSE(0);
3579
3580 if (window->focus_on_map != focus_on_map)
3581 {
3582 window->focus_on_map = focus_on_map;
3583
3584 if ((!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed)) &&
3585 (!window->focus_on_map) &&
3586 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
3587 cdk_x11_window_set_user_time (window, 0);
3588 }
3589}
3590
3591/**
3592 * cdk_x11_window_set_user_time:
3593 * @window: (type CdkX11Window): A toplevel #CdkWindow
3594 * @timestamp: An XServer timestamp to which the property should be set
3595 *
3596 * The application can use this call to update the _NET_WM_USER_TIME
3597 * property on a toplevel window. This property stores an Xserver
3598 * time which represents the time of the last user input event
3599 * received for this window. This property may be used by the window
3600 * manager to alter the focus, stacking, and/or placement behavior of
3601 * windows when they are mapped depending on whether the new window
3602 * was created by a user action or is a "pop-up" window activated by a
3603 * timer or some other event.
3604 *
3605 * Note that this property is automatically updated by CDK, so this
3606 * function should only be used by applications which handle input
3607 * events bypassing CDK.
3608 *
3609 * Since: 2.6
3610 **/
3611void
3612cdk_x11_window_set_user_time (CdkWindow *window,
3613 guint32 timestamp)
3614{
3615 CdkDisplay *display;
3616 CdkX11Display *display_x11;
3617 CdkToplevelX11 *toplevel;
3618 glong timestamp_long = (glong)timestamp;
3619 Window xid;
3620
3621 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
3622 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
3623 return;
3624
3625 display = cdk_window_get_display (window);
3626 display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
3627 toplevel = _cdk_x11_window_get_toplevel (window);
3628
3629 if (!toplevel)
3630 {
3631 g_warning ("cdk_window_set_user_time called on non-toplevel\n");
3632 return;
3633 }
3634
3635 if (toplevel->focus_window != None0L &&
3636 cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
3637 cdk_atom_intern_static_string ("_NET_WM_USER_TIME_WINDOW")))
3638 xid = toplevel->focus_window;
3639 else
3640 xid = 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)
;
3641
3642 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, xid,
3643 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
3644 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
3645 (guchar *)&timestamp_long, 1);
3646
3647 if (timestamp_long != CDK_CURRENT_TIME0L &&
3648 (display_x11->user_time == CDK_CURRENT_TIME0L ||
3649 XSERVER_TIME_IS_LATER (timestamp_long, display_x11->user_time)( (( timestamp_long > display_x11->user_time ) &&
( timestamp_long - display_x11->user_time < ((guint32)
-1)/2 )) || (( timestamp_long < display_x11->user_time )
&& ( display_x11->user_time - timestamp_long >
((guint32)-1)/2 )) )
))
3650 display_x11->user_time = timestamp_long;
3651
3652 if (toplevel)
3653 toplevel->user_time = timestamp_long;
3654}
3655
3656/**
3657 * cdk_x11_window_set_utf8_property:
3658 * @window: (type CdkX11Window): a #CdkWindow
3659 * @name: Property name, will be interned as an X atom
3660 * @value: (allow-none): Property value, or %NULL to delete
3661 *
3662 * This function modifies or removes an arbitrary X11 window
3663 * property of type UTF8_STRING. If the given @window is
3664 * not a toplevel window, it is ignored.
3665 *
3666 * Since: 3.4
3667 */
3668void
3669cdk_x11_window_set_utf8_property (CdkWindow *window,
3670 const gchar *name,
3671 const gchar *value)
3672{
3673 CdkDisplay *display;
3674
3675 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
3676 return;
3677
3678 display = cdk_window_get_display (window);
3679
3680 if (value != NULL((void*)0))
3681 {
3682 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3683 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)
,
3684 cdk_x11_get_xatom_by_name_for_display (display, name),
3685 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3686 PropModeReplace0, (guchar *)value, strlen (value));
3687 }
3688 else
3689 {
3690 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3691 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)
,
3692 cdk_x11_get_xatom_by_name_for_display (display, name));
3693 }
3694}
3695
3696/**
3697 * cdk_x11_window_set_hide_titlebar_when_maximized:
3698 * @window: (type CdkX11Window): a #CdkWindow
3699 * @hide_titlebar_when_maximized: whether to hide the titlebar when
3700 * maximized
3701 *
3702 * Set a hint for the window manager, requesting that the titlebar
3703 * should be hidden when the window is maximized.
3704 *
3705 * Note that this property is automatically updated by CTK+, so this
3706 * function should only be used by applications which do not use CTK+
3707 * to create toplevel windows.
3708 *
3709 * Since: 3.4
3710 */
3711void
3712cdk_x11_window_set_hide_titlebar_when_maximized (CdkWindow *window,
3713 gboolean hide_titlebar_when_maximized)
3714{
3715 CdkDisplay *display;
3716
3717 if (!WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
3718 return;
3719
3720 display = cdk_window_get_display (window);
3721
3722 if (hide_titlebar_when_maximized)
3723 {
3724 gulong hide = 1;
3725 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3726 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)
,
3727 cdk_x11_get_xatom_by_name_for_display (display, "_CTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"),
3728 XA_CARDINAL((Atom) 6), 32,
3729 PropModeReplace0, (guchar *)&hide, 1);
3730 }
3731 else
3732 {
3733 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
3734 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)
,
3735 cdk_x11_get_xatom_by_name_for_display (display, "_CTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"));
3736 }
3737}
3738
3739static void
3740cdk_x11_window_set_shadow_width (CdkWindow *window,
3741 int left,
3742 int right,
3743 int top,
3744 int bottom)
3745{
3746 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
3747 Atom frame_extents;
3748 gulong data[4] = {
3749 left * impl->window_scale,
3750 right * impl->window_scale,
3751 top * impl->window_scale,
3752 bottom * impl->window_scale
3753 };
3754
3755 frame_extents = cdk_x11_get_xatom_by_name_for_display (cdk_window_get_display (window),
3756 "_CTK_FRAME_EXTENTS");
3757 XChangeProperty (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
3758 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)
,
3759 frame_extents, XA_CARDINAL((Atom) 6),
3760 32, PropModeReplace0,
3761 (guchar *) &data, 4);
3762}
3763
3764/**
3765 * cdk_x11_window_set_frame_extents:
3766 * @window: (type CdkX11Window): a #CdkWindow
3767 * @left: The left extent
3768 * @right: The right extent
3769 * @top: The top extent
3770 * @bottom: The bottom extent
3771 *
3772 * This is the same as cdk_window_set_shadow_width() but it only works
3773 * on CdkX11Window.
3774 *
3775 * Since: 3.10
3776 *
3777 * Deprecated: 3.12: Use cdk_window_set_shadow_width() instead.
3778 */
3779void
3780cdk_x11_window_set_frame_extents (CdkWindow *window,
3781 int left,
3782 int right,
3783 int top,
3784 int bottom)
3785{
3786 cdk_x11_window_set_shadow_width (window, left, right, top, bottom);
3787}
3788
3789/**
3790 * cdk_x11_window_set_theme_variant:
3791 * @window: (type CdkX11Window): a #CdkWindow
3792 * @variant: the theme variant to export
3793 *
3794 * CTK+ applications can request a dark theme variant. In order to
3795 * make other applications - namely window managers using CTK+ for
3796 * themeing - aware of this choice, CTK+ uses this function to
3797 * export the requested theme variant as _CTK_THEME_VARIANT property
3798 * on toplevel windows.
3799 *
3800 * Note that this property is automatically updated by CTK+, so this
3801 * function should only be used by applications which do not use CTK+
3802 * to create toplevel windows.
3803 *
3804 * Since: 3.2
3805 */
3806void
3807cdk_x11_window_set_theme_variant (CdkWindow *window,
3808 char *variant)
3809{
3810 cdk_x11_window_set_utf8_property (window, "_CTK_THEME_VARIANT",
3811 variant ? variant : "");
3812}
3813
3814#define CDK_SELECTION_MAX_SIZE(display)(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
\
3815 MIN(262144, \(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
3816 XExtendedMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) == 0 \(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
3817 ? XMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) - 100 \(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
3818 : XExtendedMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) - 100)(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
3819
3820static void
3821cdk_window_update_icon (CdkWindow *window,
3822 GList *icon_list)
3823{
3824 CdkToplevelX11 *toplevel;
3825 GdkPixbuf *best_icon;
3826 GList *tmp_list;
3827 int best_size;
3828
3829 toplevel = _cdk_x11_window_get_toplevel (window);
3830
3831 if (toplevel->icon_pixmap != NULL((void*)0))
3832 {
3833 cairo_surface_destroy (toplevel->icon_pixmap);
3834 toplevel->icon_pixmap = NULL((void*)0);
3835 }
3836
3837 if (toplevel->icon_mask != NULL((void*)0))
3838 {
3839 cairo_surface_destroy (toplevel->icon_mask);
3840 toplevel->icon_mask = NULL((void*)0);
3841 }
3842
3843#define IDEAL_SIZE48 48
3844
3845 best_size = G_MAXINT2147483647;
3846 best_icon = NULL((void*)0);
3847 for (tmp_list = icon_list; tmp_list; tmp_list = tmp_list->next)
3848 {
3849 GdkPixbuf *pixbuf = tmp_list->data;
3850 int this;
3851
3852 /* average width and height - if someone passes in a rectangular
3853 * icon they deserve what they get.
3854 */
3855 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3856 this /= 2;
3857
3858 if (best_icon == NULL((void*)0))
3859 {
3860 best_icon = pixbuf;
3861 best_size = this;
3862 }
3863 else
3864 {
3865 /* icon is better if it's 32 pixels or larger, and closer to
3866 * the ideal size than the current best.
3867 */
3868 if (this >= 32 &&
3869 (ABS (best_size - IDEAL_SIZE)(((best_size - 48) < 0) ? -(best_size - 48) : (best_size -
48))
<
3870 ABS (this - IDEAL_SIZE)(((this - 48) < 0) ? -(this - 48) : (this - 48))))
3871 {
3872 best_icon = pixbuf;
3873 best_size = this;
3874 }
3875 }
3876 }
3877
3878 if (best_icon)
3879 {
3880 int width = gdk_pixbuf_get_width (best_icon);
3881 int height = gdk_pixbuf_get_height (best_icon);
3882 cairo_t *cr;
3883
3884 toplevel->icon_pixmap = cdk_x11_window_create_pixmap_surface (window,
3885 width,
3886 height);
3887
3888 cr = cairo_create (toplevel->icon_pixmap);
3889 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
3890 cdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
3891 if (gdk_pixbuf_get_has_alpha (best_icon))
3892 {
3893 /* Saturate the image, so it has bilevel alpha */
3894 cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
3895 cairo_paint (cr);
3896 cairo_set_operator (cr, CAIRO_OPERATOR_SATURATE);
3897 cairo_paint (cr);
3898 cairo_pop_group_to_source (cr);
3899 }
3900 cairo_paint (cr);
3901 cairo_destroy (cr);
3902
3903 if (gdk_pixbuf_get_has_alpha (best_icon))
3904 {
3905 toplevel->icon_mask = _cdk_x11_window_create_bitmap_surface (window,
3906 width,
3907 height);
3908
3909 cr = cairo_create (toplevel->icon_mask);
3910 cdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
3911 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
3912 cairo_paint (cr);
3913 cairo_destroy (cr);
3914 }
3915 }
3916
3917 update_wm_hints (window, FALSE(0));
3918}
3919
3920static void
3921cdk_x11_window_set_icon_list (CdkWindow *window,
3922 GList *pixbufs)
3923{
3924 gulong *data;
3925 guchar *pixels;
3926 gulong *p;
3927 gint size;
3928 GList *l;
3929 GdkPixbuf *pixbuf;
3930 gint width, height, stride;
3931 gint x, y;
3932 gint n_channels;
3933 CdkDisplay *display;
3934 gint n;
3935
3936 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
3937 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
3938 return;
3939
3940 display = cdk_window_get_display (window);
3941
3942 l = pixbufs;
3943 size = 0;
3944 n = 0;
3945 while (l)
3946 {
3947 pixbuf = l->data;
3948 g_return_if_fail (GDK_IS_PIXBUF (pixbuf))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((pixbuf)); GType __t = ((gdk_pixbuf_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__
)), "GDK_IS_PIXBUF (pixbuf)"); return; } } while (0)
;
3949
3950 width = gdk_pixbuf_get_width (pixbuf);
3951 height = gdk_pixbuf_get_height (pixbuf);
3952
3953 /* silently ignore overlarge icons */
3954 if (size + 2 + width * height > CDK_SELECTION_MAX_SIZE(display)(((262144) < (XExtendedMaxRequestSize ((((((CdkX11Display*
) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
? (262144) : (XExtendedMaxRequestSize ((((((CdkX11Display*) (
void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) == 0 ? XMaxRequestSize
((((((CdkX11Display*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((display)), ((cdk_x11_display_get_type()))))
))->xdisplay)) - 100 : XExtendedMaxRequestSize ((((((CdkX11Display
*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((display
)), ((cdk_x11_display_get_type()))))))->xdisplay)) - 100))
)
3955 break;
3956
3957 n++;
3958 size += 2 + width * height;
3959
3960 l = l->next;
3961 }
3962
3963 data = g_malloc (size * sizeof (gulong));
3964
3965 l = pixbufs;
3966 p = data;
3967 while (l && n > 0)
3968 {
3969 pixbuf = l->data;
3970
3971 width = gdk_pixbuf_get_width (pixbuf);
3972 height = gdk_pixbuf_get_height (pixbuf);
3973 stride = gdk_pixbuf_get_rowstride (pixbuf);
3974 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
3975
3976 *p++ = width;
3977 *p++ = height;
3978
3979 pixels = gdk_pixbuf_get_pixels (pixbuf);
3980
3981 for (y = 0; y < height; y++)
3982 {
3983 for (x = 0; x < width; x++)
3984 {
3985 guchar r, g, b, a;
3986
3987 r = pixels[y*stride + x*n_channels + 0];
3988 g = pixels[y*stride + x*n_channels + 1];
3989 b = pixels[y*stride + x*n_channels + 2];
3990 if (n_channels >= 4)
3991 a = pixels[y*stride + x*n_channels + 3];
3992 else
3993 a = 255;
3994
3995 *p++ = a << 24 | r << 16 | g << 8 | b ;
3996 }
3997 }
3998
3999 l = l->next;
4000 n--;
4001 }
4002
4003 if (size > 0)
4004 {
4005 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
4006 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)
,
4007 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
4008 XA_CARDINAL((Atom) 6), 32,
4009 PropModeReplace0,
4010 (guchar*) data, size);
4011 }
4012 else
4013 {
4014 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
4015 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)
,
4016 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
4017 }
4018
4019 g_free (data);
4020
4021 cdk_window_update_icon (window, pixbufs);
4022}
4023
4024static gboolean
4025cdk_window_icon_name_set (CdkWindow *window)
4026{
4027 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),((guint) (gulong) (g_object_get_qdata (((((GObject*) (void *)
g_type_check_instance_cast ((GTypeInstance*) ((window)), (((
GType) ((20) << (2)))))))), g_quark_from_static_string (
"cdk-icon-name-set"))))
4028 g_quark_from_static_string ("cdk-icon-name-set")))((guint) (gulong) (g_object_get_qdata (((((GObject*) (void *)
g_type_check_instance_cast ((GTypeInstance*) ((window)), (((
GType) ((20) << (2)))))))), g_quark_from_static_string (
"cdk-icon-name-set"))))
;
4029}
4030
4031static void
4032cdk_x11_window_set_icon_name (CdkWindow *window,
4033 const gchar *name)
4034{
4035 CdkDisplay *display;
4036
4037 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4038 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4039 return;
4040
4041 display = cdk_window_get_display (window);
4042
4043 g_object_set_qdata (G_OBJECT (window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), (((GType) ((20) << (2))))))))
, g_quark_from_static_string ("cdk-icon-name-set"),
4044 GUINT_TO_POINTER (name != NULL)((gpointer) (gulong) (name != ((void*)0))));
4045
4046 if (name != NULL((void*)0))
4047 {
4048 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
4049 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)
,
4050 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
4051 cdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
4052 PropModeReplace0, (guchar *)name, strlen (name));
4053
4054 set_text_property (display, 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)
,
4055 cdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
4056 name);
4057 }
4058 else
4059 {
4060 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
4061 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)
,
4062 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"));
4063 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
4064 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)
,
4065 cdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"));
4066 }
4067}
4068
4069static void
4070cdk_x11_window_iconify (CdkWindow *window)
4071{
4072 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4073 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4074 return;
4075
4076 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4077 {
4078 XIconifyWindow (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
4079 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)
,
4080 cdk_x11_screen_get_number (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window))));
4081 }
4082 else
4083 {
4084 /* Flip our client side flag, the real work happens on map. */
4085 cdk_synthesize_window_state (window,
4086 0,
4087 CDK_WINDOW_STATE_ICONIFIED);
4088 cdk_wmspec_change_state (TRUE(!(0)), window,
4089 cdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
4090 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4091 }
4092}
4093
4094static void
4095cdk_x11_window_deiconify (CdkWindow *window)
4096{
4097 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4098 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4099 return;
4100
4101 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4102 {
4103 cdk_window_show (window);
4104 cdk_wmspec_change_state (FALSE(0), window,
4105 cdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
4106 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4107 }
4108 else
4109 {
4110 /* Flip our client side flag, the real work happens on map. */
4111 cdk_synthesize_window_state (window,
4112 CDK_WINDOW_STATE_ICONIFIED,
4113 0);
4114 cdk_wmspec_change_state (FALSE(0), window,
4115 cdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
4116 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4117 }
4118}
4119
4120static void
4121cdk_x11_window_stick (CdkWindow *window)
4122{
4123 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4124 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4125 return;
4126
4127 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4128 {
4129 /* "stick" means stick to all desktops _and_ do not scroll with the
4130 * viewport. i.e. glue to the monitor glass in all cases.
4131 */
4132
4133 XClientMessageEvent xclient;
4134
4135 /* Request stick during viewport scroll */
4136 cdk_wmspec_change_state (TRUE(!(0)), window,
4137 cdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4138 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4139
4140 /* Request desktop 0xFFFFFFFF */
4141 memset (&xclient, 0, sizeof (xclient));
4142 xclient.type = ClientMessage33;
4143 xclient.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)
;
4144 xclient.display = CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
;
4145 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
,
4146 "_NET_WM_DESKTOP");
4147 xclient.format = 32;
4148
4149 xclient.data.l[0] = 0xFFFFFFFF;
4150 xclient.data.l[1] = 0;
4151 xclient.data.l[2] = 0;
4152 xclient.data.l[3] = 0;
4153 xclient.data.l[4] = 0;
4154
4155 XSendEvent (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
4156 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
4157 (XEvent *)&xclient);
4158 }
4159 else
4160 {
4161 /* Flip our client side flag, the real work happens on map. */
4162 cdk_synthesize_window_state (window,
4163 0,
4164 CDK_WINDOW_STATE_STICKY);
4165 }
4166}
4167
4168static void
4169cdk_x11_window_unstick (CdkWindow *window)
4170{
4171 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4172 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4173 return;
4174
4175 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4176 {
4177 /* Request unstick from viewport */
4178 cdk_wmspec_change_state (FALSE(0), window,
4179 cdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4180 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4181
4182 move_to_current_desktop (window);
4183 }
4184 else
4185 {
4186 /* Flip our client side flag, the real work happens on map. */
4187 cdk_synthesize_window_state (window,
4188 CDK_WINDOW_STATE_STICKY,
4189 0);
4190
4191 }
4192}
4193
4194static void
4195cdk_x11_window_maximize (CdkWindow *window)
4196{
4197 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4198 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4199 return;
4200
4201 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4202 cdk_wmspec_change_state (TRUE(!(0)), window,
4203 cdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4204 cdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4205 else
4206 cdk_synthesize_window_state (window,
4207 0,
4208 CDK_WINDOW_STATE_MAXIMIZED);
4209}
4210
4211static void
4212cdk_x11_window_unmaximize (CdkWindow *window)
4213{
4214 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4215 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4216 return;
4217
4218 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4219 cdk_wmspec_change_state (FALSE(0), window,
4220 cdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4221 cdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4222 else
4223 cdk_synthesize_window_state (window,
4224 CDK_WINDOW_STATE_MAXIMIZED,
4225 0);
4226}
4227
4228static void
4229cdk_x11_window_apply_fullscreen_mode (CdkWindow *window)
4230{
4231 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4232 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4233 return;
4234
4235 /* _NET_WM_FULLSCREEN_MONITORS gives an indication to the window manager as
4236 * to which monitors so span across when the window is fullscreen, but it's
4237 * not a state in itself so this would have no effect if the window is not
4238 * mapped.
4239 */
4240
4241 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4242 {
4243 XClientMessageEvent xclient;
4244 gint monitors[4];
4245 gint i;
4246
4247 memset (&xclient, 0, sizeof (xclient));
4248 xclient.type = ClientMessage33;
4249 xclient.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)
;
4250 xclient.display = CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
;
4251 xclient.format = 32;
4252
4253 switch (window->fullscreen_mode)
4254 {
4255 case CDK_FULLSCREEN_ON_CURRENT_MONITOR:
4256
4257 /* FIXME: This is not part of the EWMH spec!
4258 *
4259 * There is no documented mechanism to remove the property
4260 * _NET_WM_FULLSCREEN_MONITORS once set, so we use use a set of
4261 * invalid, largest possible value.
4262 *
4263 * When given values larger than actual possible monitor values, most
4264 * window managers who support the _NET_WM_FULLSCREEN_MONITORS spec
4265 * will simply unset _NET_WM_FULLSCREEN_MONITORS and revert to their
4266 * default behavior.
4267 *
4268 * Successfully tested on mutter/metacity, kwin, compiz and xfwm4.
4269 *
4270 * Note, this (non documented) mechanism is unlikely to be an issue
4271 * as it's used only for transitionning back from "all monitors" to
4272 * "current monitor" mode.
4273 *
4274 * Applications who don't change the default mode won't trigger this
4275 * mechanism.
4276 */
4277 for (i = 0; i < 4; ++i)
4278 xclient.data.l[i] = G_MAXLONG9223372036854775807L;
4279
4280 break;
4281
4282 case CDK_FULLSCREEN_ON_ALL_MONITORS:
4283
4284 _cdk_x11_screen_get_edge_monitors (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
4285 &monitors[0],
4286 &monitors[1],
4287 &monitors[2],
4288 &monitors[3]);
4289 /* Translate all 4 monitors from the CDK set into XINERAMA indices */
4290 for (i = 0; i < 4; ++i)
4291 {
4292 xclient.data.l[i] = monitors[i];
4293 /* Sanity check, if XINERAMA is not available, we could have invalid
4294 * negative values for the XINERAMA indices.
4295 */
4296 if (xclient.data.l[i] < 0)
4297 {
4298 g_warning ("cdk_x11_window_apply_fullscreen_mode: Invalid XINERAMA monitor index");
4299 return;
4300 }
4301 }
4302 break;
4303
4304 default:
4305 g_warning ("cdk_x11_window_apply_fullscreen_mode: Unhandled fullscreen mode %d",
4306 window->fullscreen_mode);
4307 return;
4308 }
4309
4310 /* Send fullscreen monitors client message */
4311 xclient.data.l[4] = 1; /* source indication */
4312 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
,
4313 "_NET_WM_FULLSCREEN_MONITORS");
4314 XSendEvent (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
4315 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
4316 (XEvent *)&xclient);
4317 }
4318}
4319
4320static void
4321cdk_x11_window_fullscreen (CdkWindow *window)
4322{
4323 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4324 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4325 return;
4326
4327 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4328 {
4329 cdk_wmspec_change_state (TRUE(!(0)), window,
4330 cdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4331 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4332 /* Actual XRandR layout may have change since we computed the fullscreen
4333 * monitors in CDK_FULLSCREEN_ON_ALL_MONITORS mode.
4334 */
4335 if (window->fullscreen_mode == CDK_FULLSCREEN_ON_ALL_MONITORS)
4336 cdk_x11_window_apply_fullscreen_mode (window);
4337 }
4338 else
4339 cdk_synthesize_window_state (window,
4340 0,
4341 CDK_WINDOW_STATE_FULLSCREEN);
4342}
4343
4344static void
4345cdk_x11_window_fullscreen_on_monitor (CdkWindow *window,
4346 gint monitor)
4347{
4348 CdkRectangle monitor_geom;
4349
4350 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4351 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4352 return;
4353
4354G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push clang diagnostic ignored "-Wdeprecated-declarations"
4355 cdk_screen_get_monitor_geometry (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)), monitor, &monitor_geom);
4356 cdk_window_move (window, monitor_geom.x, monitor_geom.y);
4357G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop
4358
4359 cdk_window_set_fullscreen_mode (window, CDK_FULLSCREEN_ON_CURRENT_MONITOR);
4360 cdk_x11_window_fullscreen (window);
4361}
4362
4363static void
4364cdk_x11_window_unfullscreen (CdkWindow *window)
4365{
4366 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4367 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4368 return;
4369
4370 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4371 cdk_wmspec_change_state (FALSE(0), window,
4372 cdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4373 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4374
4375 else
4376 cdk_synthesize_window_state (window,
4377 CDK_WINDOW_STATE_FULLSCREEN,
4378 0);
4379}
4380
4381static void
4382cdk_x11_window_set_keep_above (CdkWindow *window,
4383 gboolean setting)
4384{
4385 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
4386
4387 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4388 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4389 return;
4390
4391 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4392 {
4393 if (setting)
4394 cdk_wmspec_change_state (FALSE(0), window,
4395 cdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4396 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4397 cdk_wmspec_change_state (setting, window,
4398 cdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4399 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4400 }
4401 else
4402 cdk_synthesize_window_state (window,
4403 setting ? CDK_WINDOW_STATE_BELOW : CDK_WINDOW_STATE_ABOVE,
4404 setting ? CDK_WINDOW_STATE_ABOVE : 0);
4405}
4406
4407static void
4408cdk_x11_window_set_keep_below (CdkWindow *window, gboolean setting)
4409{
4410 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
4411
4412 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4413 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4414 return;
4415
4416 if (CDK_WINDOW_IS_MAPPED (window)(((window)->state & CDK_WINDOW_STATE_WITHDRAWN) == 0))
4417 {
4418 if (setting)
4419 cdk_wmspec_change_state (FALSE(0), window,
4420 cdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4421 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4422 cdk_wmspec_change_state (setting, window,
4423 cdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4424 CDK_NONE((CdkAtom)((gpointer) (gulong) (0))));
4425 }
4426 else
4427 cdk_synthesize_window_state (window,
4428 setting ? CDK_WINDOW_STATE_ABOVE : CDK_WINDOW_STATE_BELOW,
4429 setting ? CDK_WINDOW_STATE_BELOW : 0);
4430}
4431
4432static CdkWindow *
4433cdk_x11_window_get_group (CdkWindow *window)
4434{
4435 CdkToplevelX11 *toplevel;
4436
4437 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4438 !WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
4439 return NULL((void*)0);
4440
4441 toplevel = _cdk_x11_window_get_toplevel (window);
4442
4443 return toplevel->group_leader;
4444}
4445
4446static void
4447cdk_x11_window_set_group (CdkWindow *window,
4448 CdkWindow *leader)
4449{
4450 CdkToplevelX11 *toplevel;
4451
4452 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
4453 g_return_if_fail (CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD)do { if ((((((CdkWindow *)(window)))->window_type) != CDK_WINDOW_CHILD
)) { } else { g_return_if_fail_warning ("Cdk", ((const char*)
(__func__)), "CDK_WINDOW_TYPE (window) != CDK_WINDOW_CHILD")
; return; } } while (0)
;
4454 g_return_if_fail (leader == NULL || CDK_IS_WINDOW (leader))do { if ((leader == ((void*)0) || (((__extension__ ({ GTypeInstance
*__inst = (GTypeInstance*) ((leader)); 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; })))))) { } else { g_return_if_fail_warning ("Cdk", ((const
char*) (__func__)), "leader == NULL || CDK_IS_WINDOW (leader)"
); return; } } while (0)
;
4455
4456 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4457 (leader != NULL((void*)0) && CDK_WINDOW_DESTROYED (leader)(((CdkWindow *)(leader))->destroyed)) ||
4458 !WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
4459 return;
4460
4461 toplevel = _cdk_x11_window_get_toplevel (window);
4462
4463 if (leader == NULL((void*)0))
4464 leader = cdk_display_get_default_group (cdk_window_get_display (window));
4465
4466 if (toplevel->group_leader != leader)
4467 {
4468 if (toplevel->group_leader)
4469 g_object_unref (toplevel->group_leader);
4470 toplevel->group_leader = g_object_ref (leader)((__typeof__ (leader)) (g_object_ref) (leader));
4471 (_cdk_x11_window_get_toplevel (leader))->is_leader = TRUE(!(0));
4472 }
4473
4474 update_wm_hints (window, FALSE(0));
4475}
4476
4477static MotifWmHints *
4478cdk_window_get_mwm_hints (CdkWindow *window)
4479{
4480 CdkDisplay *display;
4481 Atom hints_atom = None0L;
4482 guchar *data;
4483 Atom type;
4484 gint format;
4485 gulong nitems;
4486 gulong bytes_after;
4487
4488 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
4489 return NULL((void*)0);
4490
4491 display = cdk_window_get_display (window);
4492
4493 hints_atom = cdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
4494
4495 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)
,
4496 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4497 False0, AnyPropertyType0L, &type, &format, &nitems,
4498 &bytes_after, &data);
4499
4500 if (type == None0L)
4501 return NULL((void*)0);
4502
4503 return (MotifWmHints *)data;
4504}
4505
4506static void
4507cdk_window_set_mwm_hints (CdkWindow *window,
4508 MotifWmHints *new_hints)
4509{
4510 CdkDisplay *display;
4511 Atom hints_atom = None0L;
4512 guchar *data;
4513 MotifWmHints *hints;
4514 Atom type;
4515 gint format;
4516 gulong nitems;
4517 gulong bytes_after;
4518
4519 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
4520 return;
4521
4522 display = cdk_window_get_display (window);
4523
4524 hints_atom = cdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS");
4525
4526 XGetWindowProperty (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
,
4527 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4528 False0, AnyPropertyType0L, &type, &format, &nitems,
4529 &bytes_after, &data);
4530
4531 if (type == None0L)
4532 hints = new_hints;
4533 else
4534 {
4535 hints = (MotifWmHints *)data;
4536
4537 if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0))
4538 {
4539 hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0);
4540 hints->functions = new_hints->functions;
4541 }
4542 if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
4543 {
4544 hints->flags |= MWM_HINTS_DECORATIONS(1L << 1);
4545 hints->decorations = new_hints->decorations;
4546 }
4547 }
4548
4549 XChangeProperty (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_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)
,
4550 hints_atom, hints_atom, 32, PropModeReplace0,
4551 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
4552
4553 if (hints != new_hints)
4554 XFree (hints);
4555}
4556
4557static void
4558cdk_x11_window_set_decorations (CdkWindow *window,
4559 CdkWMDecoration decorations)
4560{
4561 MotifWmHints hints;
4562
4563 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4564 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4565 return;
4566
4567 /* initialize to zero to avoid writing uninitialized data to socket */
4568 memset(&hints, 0, sizeof(hints));
4569 hints.flags = MWM_HINTS_DECORATIONS(1L << 1);
4570 hints.decorations = decorations;
4571
4572 cdk_window_set_mwm_hints (window, &hints);
4573}
4574
4575static gboolean
4576cdk_x11_window_get_decorations(CdkWindow *window,
4577 CdkWMDecoration *decorations)
4578{
4579 MotifWmHints *hints;
4580 gboolean result = FALSE(0);
4581
4582 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4583 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4584 return FALSE(0);
4585
4586 hints = cdk_window_get_mwm_hints (window);
4587
4588 if (hints)
4589 {
4590 if (hints->flags & MWM_HINTS_DECORATIONS(1L << 1))
4591 {
4592 if (decorations)
4593 *decorations = hints->decorations;
4594 result = TRUE(!(0));
4595 }
4596
4597 XFree (hints);
4598 }
4599
4600 return result;
4601}
4602
4603static void
4604cdk_x11_window_set_functions (CdkWindow *window,
4605 CdkWMFunction functions)
4606{
4607 MotifWmHints hints;
4608
4609 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
4610
4611 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
4612 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
4613 return;
4614
4615 /* initialize to zero to avoid writing uninitialized data to socket */
4616 memset(&hints, 0, sizeof(hints));
4617 hints.flags = MWM_HINTS_FUNCTIONS(1L << 0);
4618 hints.functions = functions;
4619
4620 cdk_window_set_mwm_hints (window, &hints);
4621}
4622
4623cairo_region_t *
4624_cdk_x11_xwindow_get_shape (Display *xdisplay,
4625 Window window,
4626 gint scale,
4627 gint shape_type)
4628{
4629 cairo_region_t *shape;
4630 CdkRectangle *rl;
4631 XRectangle *xrl;
4632 gint rn, ord, i;
4633
4634 shape = NULL((void*)0);
4635 rn = 0;
4636
4637 /* Note that XShapeGetRectangles returns NULL in two situations:
4638 * - the server doesn't support the SHAPE extension
4639 * - the shape is empty
4640 *
4641 * Since we can't discriminate these here, we always return
4642 * an empty shape. It is the callers responsibility to check
4643 * whether the server supports the SHAPE extensions beforehand.
4644 */
4645 xrl = XShapeGetRectangles (xdisplay, window, shape_type, &rn, &ord);
4646
4647 if (rn == 0)
4648 return cairo_region_create (); /* Empty */
4649
4650 if (ord != YXBanded3)
4651 {
4652 /* This really shouldn't happen with any xserver, as they
4653 * generally convert regions to YXBanded internally
4654 */
4655 g_warning ("non YXBanded shape masks not supported");
4656 XFree (xrl);
4657 return NULL((void*)0);
4658 }
4659
4660 /* NOTE: The scale divisions here may lose some precision if someone
4661 else set the shape to be non-scale precision */
4662 rl = g_new (CdkRectangle, rn)((CdkRectangle *) g_malloc_n ((rn), sizeof (CdkRectangle)));
4663 for (i = 0; i < rn; i++)
4664 {
4665 rl[i].x = xrl[i].x / scale;
4666 rl[i].y = xrl[i].y / scale;
4667 rl[i].width = xrl[i].width / scale;
4668 rl[i].height = xrl[i].height / scale;
4669 }
4670 XFree (xrl);
4671
4672 shape = cairo_region_create_rectangles (rl, rn);
4673 g_free (rl);
4674
4675 return shape;
4676}
4677
4678
4679static cairo_region_t *
4680cdk_x11_window_get_shape (CdkWindow *window)
4681{
4682 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
4683
4684 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) &&
4685 cdk_display_supports_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
))
4686 return _cdk_x11_xwindow_get_shape (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
4687 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)
,
4688 impl->window_scale,
4689 ShapeBounding0);
4690
4691 return NULL((void*)0);
4692}
4693
4694static cairo_region_t *
4695cdk_x11_window_get_input_shape (CdkWindow *window)
4696{
4697#if defined(ShapeInput2)
4698 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
4699
4700 if (!CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) &&
4701 cdk_display_supports_input_shapes (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
))
4702 return _cdk_x11_xwindow_get_shape (CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
,
4703 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)
,
4704 impl->window_scale,
4705 ShapeInput2);
4706#endif
4707
4708 return NULL((void*)0);
4709}
4710
4711/* From the WM spec */
4712#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT0 0
4713#define _NET_WM_MOVERESIZE_SIZE_TOP1 1
4714#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT2 2
4715#define _NET_WM_MOVERESIZE_SIZE_RIGHT3 3
4716#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT4 4
4717#define _NET_WM_MOVERESIZE_SIZE_BOTTOM5 5
4718#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT6 6
4719#define _NET_WM_MOVERESIZE_SIZE_LEFT7 7
4720#define _NET_WM_MOVERESIZE_MOVE8 8 /* movement only */
4721#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD9 9 /* size via keyboard */
4722#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD10 10 /* move via keyboard */
4723#define _NET_WM_MOVERESIZE_CANCEL11 11 /* cancel operation */
4724
4725static void
4726wmspec_send_message (CdkDisplay *display,
4727 CdkWindow *window,
4728 gint root_x,
4729 gint root_y,
4730 gint action,
4731 gint button)
4732{
4733 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
4734 XClientMessageEvent xclient;
4735
4736 memset (&xclient, 0, sizeof (xclient));
4737 xclient.type = ClientMessage33;
4738 xclient.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)
;
4739 xclient.message_type =
4740 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
4741 xclient.format = 32;
4742 xclient.data.l[0] = root_x * impl->window_scale;
4743 xclient.data.l[1] = root_y * impl->window_scale;
4744 xclient.data.l[2] = action;
4745 xclient.data.l[3] = button;
4746 xclient.data.l[4] = 1; /* source indication */
4747
4748 XSendEvent (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
4749 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
4750 (XEvent *)&xclient);
4751}
4752
4753static void
4754handle_wmspec_button_release (CdkDisplay *display,
4755 XEvent *xevent)
4756{
4757 CdkX11Display *display_x11 = CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
;
4758 CdkWindow *window;
4759
4760#if defined (HAVE_XGENERICEVENTS1) && defined (XINPUT_21)
4761 XIEvent *xiev = (XIEvent *) xevent->xcookie.data;
4762 XIDeviceEvent *xidev = (XIDeviceEvent *) xiev;
4763
4764 if (xevent->xany.type == GenericEvent35)
4765 window = cdk_x11_window_lookup_for_display (display, xidev->event);
4766 else
4767#endif
4768 window = cdk_x11_window_lookup_for_display (display, xevent->xany.window);
4769
4770 if (display_x11->wm_moveresize_button != 0 && window != NULL((void*)0))
4771 {
4772 if ((xevent->xany.type == ButtonRelease5 &&
4773 xevent->xbutton.button == display_x11->wm_moveresize_button)
4774#if defined (HAVE_XGENERICEVENTS1) && defined (XINPUT_21)
4775 ||
4776 (xevent->xany.type == GenericEvent35 &&
4777 xiev->evtype == XI_ButtonRelease5 &&
4778 xidev->detail == display_x11->wm_moveresize_button)
4779#endif
4780 )
4781 {
4782 display_x11->wm_moveresize_button = 0;
4783 wmspec_send_message (display, window, 0, 0, _NET_WM_MOVERESIZE_CANCEL11, 0);
4784 }
4785 }
4786}
4787
4788static void
4789wmspec_moveresize (CdkWindow *window,
4790 gint direction,
4791 CdkDevice *device,
4792 gint button,
4793 gint root_x,
4794 gint root_y,
4795 guint32 timestamp G_GNUC_UNUSED__attribute__ ((__unused__)))
4796{
4797 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)
;
4798
4799 if (button != 0)
4800 cdk_seat_ungrab (cdk_device_get_seat (device)); /* Release passive grab */
4801 CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->wm_moveresize_button = button;
4802
4803 wmspec_send_message (display, window, root_x, root_y, direction, button);
4804}
4805
4806static void
4807wmspec_resize_drag (CdkWindow *window,
4808 CdkWindowEdge edge,
4809 CdkDevice *device,
4810 gint button,
4811 gint root_x,
4812 gint root_y,
4813 guint32 timestamp)
4814{
4815 gint direction;
4816
4817 if (button == 0)
4818 direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD9;
4819 else
4820 switch (edge)
4821 {
4822 /* Let the compiler turn a switch into a table, instead
4823 * of doing the table manually, this way is easier to verify.
4824 */
4825 case CDK_WINDOW_EDGE_NORTH_WEST:
4826 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT0;
4827 break;
4828
4829 case CDK_WINDOW_EDGE_NORTH:
4830 direction = _NET_WM_MOVERESIZE_SIZE_TOP1;
4831 break;
4832
4833 case CDK_WINDOW_EDGE_NORTH_EAST:
4834 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT2;
4835 break;
4836
4837 case CDK_WINDOW_EDGE_WEST:
4838 direction = _NET_WM_MOVERESIZE_SIZE_LEFT7;
4839 break;
4840
4841 case CDK_WINDOW_EDGE_EAST:
4842 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT3;
4843 break;
4844
4845 case CDK_WINDOW_EDGE_SOUTH_WEST:
4846 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT6;
4847 break;
4848
4849 case CDK_WINDOW_EDGE_SOUTH:
4850 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM5;
4851 break;
4852
4853 case CDK_WINDOW_EDGE_SOUTH_EAST:
4854 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT4;
4855 break;
4856
4857 default:
4858 g_warning ("cdk_window_begin_resize_drag: bad resize edge %d!",
4859 edge);
4860 return;
4861 }
4862
4863 wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
4864}
4865
4866typedef struct _MoveResizeData MoveResizeData;
4867
4868struct _MoveResizeData
4869{
4870 CdkDisplay *display;
4871
4872 CdkWindow *moveresize_window;
4873 CdkWindow *moveresize_emulation_window;
4874 gboolean is_resize;
4875 CdkWindowEdge resize_edge;
4876 CdkDevice *device;
4877 gint moveresize_button;
4878 gint moveresize_x;
4879 gint moveresize_y;
4880 gint moveresize_orig_x;
4881 gint moveresize_orig_y;
4882 gint moveresize_orig_width;
4883 gint moveresize_orig_height;
4884 CdkWindowHints moveresize_geom_mask;
4885 CdkGeometry moveresize_geometry;
4886 Time moveresize_process_time;
4887 XEvent *moveresize_pending_event;
4888};
4889
4890static MoveResizeData *
4891get_move_resize_data (CdkDisplay *display,
4892 gboolean create)
4893{
4894 MoveResizeData *mv_resize;
4895 static GQuark move_resize_quark = 0;
4896
4897 if (!move_resize_quark)
4898 move_resize_quark = g_quark_from_static_string ("cdk-window-moveresize");
4899
4900 mv_resize = g_object_get_qdata (G_OBJECT (display)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), (((GType) ((20) << (2))))))))
, move_resize_quark);
4901
4902 if (!mv_resize && create)
4903 {
4904 mv_resize = g_new0 (MoveResizeData, 1)((MoveResizeData *) g_malloc0_n ((1), sizeof (MoveResizeData)
))
;
4905 mv_resize->display = display;
4906
4907 g_object_set_qdata (G_OBJECT (display)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), (((GType) ((20) << (2))))))))
, move_resize_quark, mv_resize);
4908 }
4909
4910 return mv_resize;
4911}
4912
4913static void
4914check_maximize (MoveResizeData *mv_resize,
4915 gdouble x_root G_GNUC_UNUSED__attribute__ ((__unused__)),
4916 gdouble y_root)
4917{
4918 CdkWindowState state;
4919 gint y;
4920
4921 if (mv_resize->is_resize)
4922 return;
4923
4924 state = cdk_window_get_state (mv_resize->moveresize_window);
4925
4926 if (state & CDK_WINDOW_STATE_MAXIMIZED)
4927 return;
4928
4929 y = mv_resize->moveresize_orig_y + (y_root - mv_resize->moveresize_y);
4930
4931 if (y < 10)
4932 cdk_window_maximize (mv_resize->moveresize_window);
4933}
4934
4935static void
4936check_unmaximize (MoveResizeData *mv_resize,
4937 gdouble x_root,
4938 gdouble y_root)
4939{
4940 CdkWindowState state;
4941 gint dx, dy;
4942
4943 if (mv_resize->is_resize)
4944 return;
4945
4946 state = cdk_window_get_state (mv_resize->moveresize_window);
4947
4948 if ((state & (CDK_WINDOW_STATE_MAXIMIZED | CDK_WINDOW_STATE_TILED)) == 0)
4949 return;
4950
4951 dx = x_root - mv_resize->moveresize_x;
4952 dy = y_root - mv_resize->moveresize_y;
4953
4954 if (ABS (dx)(((dx) < 0) ? -(dx) : (dx)) > 20 || ABS (dy)(((dy) < 0) ? -(dy) : (dy)) > 20)
4955 cdk_window_unmaximize (mv_resize->moveresize_window);
4956}
4957
4958static void
4959update_pos (MoveResizeData *mv_resize,
4960 gint new_root_x,
4961 gint new_root_y)
4962{
4963 gint dx, dy;
4964
4965 check_unmaximize (mv_resize, new_root_x, new_root_y);
4966 dx = new_root_x - mv_resize->moveresize_x;
4967 dy = new_root_y - mv_resize->moveresize_y;
4968
4969 if (mv_resize->is_resize)
4970 {
4971 gint x, y, w, h;
4972
4973 x = mv_resize->moveresize_orig_x;
4974 y = mv_resize->moveresize_orig_y;
4975
4976 w = mv_resize->moveresize_orig_width;
4977 h = mv_resize->moveresize_orig_height;
4978
4979 switch (mv_resize->resize_edge)
4980 {
4981 case CDK_WINDOW_EDGE_NORTH_WEST:
4982 x += dx;
4983 y += dy;
4984 w -= dx;
4985 h -= dy;
4986 break;
4987 case CDK_WINDOW_EDGE_NORTH:
4988 y += dy;
4989 h -= dy;
4990 break;
4991 case CDK_WINDOW_EDGE_NORTH_EAST:
4992 y += dy;
4993 h -= dy;
4994 w += dx;
4995 break;
4996 case CDK_WINDOW_EDGE_SOUTH_WEST:
4997 h += dy;
4998 x += dx;
4999 w -= dx;
5000 break;
5001 case CDK_WINDOW_EDGE_SOUTH_EAST:
5002 w += dx;
5003 h += dy;
5004 break;
5005 case CDK_WINDOW_EDGE_SOUTH:
5006 h += dy;
5007 break;
5008 case CDK_WINDOW_EDGE_EAST:
5009 w += dx;
5010 break;
5011 case CDK_WINDOW_EDGE_WEST:
5012 x += dx;
5013 w -= dx;
5014 break;
5015 }
5016
5017 x = MAX (x, 0)(((x) > (0)) ? (x) : (0));
5018 y = MAX (y, 0)(((y) > (0)) ? (y) : (0));
5019 w = MAX (w, 1)(((w) > (1)) ? (w) : (1));
5020 h = MAX (h, 1)(((h) > (1)) ? (h) : (1));
5021
5022 if (mv_resize->moveresize_geom_mask)
5023 {
5024 cdk_window_constrain_size (&mv_resize->moveresize_geometry,
5025 mv_resize->moveresize_geom_mask,
5026 w, h, &w, &h);
5027 }
5028
5029 cdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
5030 }
5031 else
5032 {
5033 gint x, y;
5034
5035 x = mv_resize->moveresize_orig_x + dx;
5036 y = mv_resize->moveresize_orig_y + dy;
5037
5038 cdk_window_move (mv_resize->moveresize_window, x, y);
5039 }
5040}
5041
5042static void
5043finish_drag (MoveResizeData *mv_resize)
5044{
5045 cdk_window_destroy (mv_resize->moveresize_emulation_window);
5046 mv_resize->moveresize_emulation_window = NULL((void*)0);
5047 g_clear_object (&mv_resize->moveresize_window)do { _Static_assert (sizeof *((&mv_resize->moveresize_window
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&mv_resize->moveresize_window))) _pp = ((&mv_resize
->moveresize_window)); __typeof__ (*((&mv_resize->moveresize_window
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
5048 g_clear_pointer (&mv_resize->moveresize_pending_event, g_free)do { _Static_assert (sizeof *(&mv_resize->moveresize_pending_event
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
((&mv_resize->moveresize_pending_event)) _pp = (&
mv_resize->moveresize_pending_event); __typeof__ (*(&mv_resize
->moveresize_pending_event)) _ptr = *_pp; *_pp = ((void*)0
); if (_ptr) (g_free) (_ptr); } while (0)
;
5049}
5050
5051static int
5052lookahead_motion_predicate (Display *xdisplay,
5053 XEvent *event,
5054 XPointer arg)
5055{
5056 gboolean *seen_release = (gboolean *)arg;
5057 CdkDisplay *display = cdk_x11_lookup_xdisplay (xdisplay);
5058 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE(0));
5059
5060 if (*seen_release)
5061 return False0;
5062
5063 switch (event->xany.type)
5064 {
5065 case ButtonRelease5:
5066 *seen_release = TRUE(!(0));
5067 break;
5068 case MotionNotify6:
5069 mv_resize->moveresize_process_time = event->xmotion.time;
5070 break;
5071 default:
5072 break;
5073 }
5074
5075 return False0;
5076}
5077
5078static gboolean
5079moveresize_lookahead (MoveResizeData *mv_resize,
5080 XEvent *event)
5081{
5082 XEvent tmp_event;
5083 gboolean seen_release = FALSE(0);
5084
5085 if (mv_resize->moveresize_process_time)
5086 {
5087 if (event->xmotion.time == mv_resize->moveresize_process_time)
5088 {
5089 mv_resize->moveresize_process_time = 0;
5090 return TRUE(!(0));
5091 }
5092 else
5093 return FALSE(0);
5094 }
5095
5096 XCheckIfEvent (event->xany.display, &tmp_event,
5097 lookahead_motion_predicate, (XPointer) & seen_release);
5098
5099 return mv_resize->moveresize_process_time == 0;
5100}
5101
5102gboolean
5103_cdk_x11_moveresize_handle_event (XEvent *event)
5104{
5105 guint button_mask = 0;
5106 CdkDisplay *display = cdk_x11_lookup_xdisplay (event->xany.display);
5107 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE(0));
5108 CdkWindowImplX11 *impl;
5109
5110 if (!mv_resize || !mv_resize->moveresize_window)
5111 {
5112 handle_wmspec_button_release (display, event);
5113 return FALSE(0);
5114 }
5115
5116 impl = CDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((mv_resize->moveresize_window->impl)),
((cdk_window_impl_x11_get_type ()))))))
;
5117
5118 if (mv_resize->moveresize_button != 0)
5119 button_mask = CDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
5120
5121 switch (event->xany.type)
5122 {
5123 case MotionNotify6:
5124 if (mv_resize->moveresize_window->resize_count > 0)
5125 {
5126 if (mv_resize->moveresize_pending_event)
5127 *mv_resize->moveresize_pending_event = *event;
5128 else
5129 mv_resize->moveresize_pending_event =
5130 g_memdup2 (event, sizeof (XEvent));
5131
5132 break;
5133 }
5134 if (!moveresize_lookahead (mv_resize, event))
5135 break;
5136
5137 update_pos (mv_resize,
5138 event->xmotion.x_root / impl->window_scale,
5139 event->xmotion.y_root / impl->window_scale);
5140
5141 /* This should never be triggered in normal cases, but in the
5142 * case where the drag started without an implicit grab being
5143 * in effect, we could miss the release if it occurs before
5144 * we grab the pointer; this ensures that we will never
5145 * get a permanently stuck grab.
5146 */
5147 if ((event->xmotion.state & button_mask) == 0)
5148 {
5149 check_maximize (mv_resize,
5150 event->xmotion.x_root / impl->window_scale,
5151 event->xmotion.y_root / impl->window_scale);
5152 finish_drag (mv_resize);
5153 }
5154 break;
5155
5156 case ButtonRelease5:
5157 update_pos (mv_resize,
5158 event->xbutton.x_root / impl->window_scale,
5159 event->xbutton.y_root / impl->window_scale);
5160
5161 if (event->xbutton.button == mv_resize->moveresize_button)
5162 {
5163 check_maximize (mv_resize,
5164 event->xmotion.x_root / impl->window_scale,
5165 event->xmotion.y_root / impl->window_scale);
5166 finish_drag (mv_resize);
5167 }
5168 break;
5169
5170#if defined (HAVE_XGENERICEVENTS1) && defined (XINPUT_21)
5171 case GenericEvent35:
5172 {
5173 /* we just assume this is an XI2 event */
5174 XIEvent *ev = (XIEvent *) event->xcookie.data;
5175 XIDeviceEvent *xev = (XIDeviceEvent *)ev;
5176 gint state;
5177 switch (ev->evtype)
5178 {
5179 case XI_Motion6:
5180 update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale);
5181 state = _cdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
5182 if ((state & button_mask) == 0)
5183 {
5184 check_maximize (mv_resize,
5185 xev->root_x / impl->window_scale,
5186 xev->root_y / impl->window_scale);
5187 finish_drag (mv_resize);
5188 }
5189 break;
5190
5191 case XI_ButtonRelease5:
5192 update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale);
5193 if (xev->detail == mv_resize->moveresize_button)
5194 {
5195 check_maximize (mv_resize,
5196 xev->root_x / impl->window_scale,
5197 xev->root_y / impl->window_scale);
5198 finish_drag (mv_resize);
5199 }
5200 break;
5201 }
5202 }
5203 break;
5204#endif
5205
5206 }
5207 return TRUE(!(0));
5208}
5209
5210gboolean
5211_cdk_x11_moveresize_configure_done (CdkDisplay *display,
5212 CdkWindow *window)
5213{
5214 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE(0));
5215
5216 if (!mv_resize || window != mv_resize->moveresize_window)
5217 return FALSE(0);
5218
5219 if (mv_resize->moveresize_pending_event)
5220 {
5221 XEvent *tmp_event;
5222
5223 tmp_event = mv_resize->moveresize_pending_event;
5224 mv_resize->moveresize_pending_event = NULL((void*)0);
5225 _cdk_x11_moveresize_handle_event (tmp_event);
5226 g_free (tmp_event);
5227 }
5228
5229 return TRUE(!(0));
5230}
5231
5232static void
5233create_moveresize_window (MoveResizeData *mv_resize,
5234 guint32 timestamp G_GNUC_UNUSED__attribute__ ((__unused__)))
5235{
5236 CdkWindowAttr attributes;
5237 gint attributes_mask;
5238 CdkGrabStatus status;
5239
5240 g_assert (mv_resize->moveresize_emulation_window == NULL)do { if (mv_resize->moveresize_emulation_window == ((void*
)0)) ; else g_assertion_message_expr ("Cdk", "cdkwindow-x11.c"
, 5240, ((const char*) (__func__)), "mv_resize->moveresize_emulation_window == NULL"
); } while (0)
;
5241
5242 attributes.x = -100;
5243 attributes.y = -100;
5244 attributes.width = 10;
5245 attributes.height = 10;
5246 attributes.window_type = CDK_WINDOW_TEMP;
5247 attributes.wclass = CDK_INPUT_ONLY;
5248 attributes.override_redirect = TRUE(!(0));
5249 attributes.event_mask = 0;
5250
5251 attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_NOREDIR;
5252
5253 mv_resize->moveresize_emulation_window =
5254 cdk_window_new (cdk_screen_get_root_window (cdk_display_get_default_screen (mv_resize->display)),
5255 &attributes,
5256 attributes_mask);
5257
5258 cdk_window_show (mv_resize->moveresize_emulation_window);
5259
5260 status = cdk_seat_grab (cdk_device_get_seat (mv_resize->device),
5261 mv_resize->moveresize_emulation_window,
5262 CDK_SEAT_CAPABILITY_POINTER, FALSE(0),
5263 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
5264
5265 if (status != CDK_GRAB_SUCCESS)
5266 {
5267 /* If this fails, some other client has grabbed the window
5268 * already.
5269 */
5270 finish_drag (mv_resize);
5271 }
5272
5273 mv_resize->moveresize_process_time = 0;
5274}
5275
5276/*
5277 Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
5278 so that calling XMoveWindow with these coordinates will not move the
5279 window.
5280 Note that this depends on the WM to implement ICCCM-compliant reference
5281 point handling.
5282*/
5283static void
5284calculate_unmoving_origin (MoveResizeData *mv_resize)
5285{
5286 CdkRectangle rect;
5287 gint width, height;
5288
5289 if (mv_resize->moveresize_geom_mask & CDK_HINT_WIN_GRAVITY &&
5290 mv_resize->moveresize_geometry.win_gravity == CDK_GRAVITY_STATIC)
5291 {
5292 cdk_window_get_origin (mv_resize->moveresize_window,
5293 &mv_resize->moveresize_orig_x,
5294 &mv_resize->moveresize_orig_y);
5295 }
5296 else
5297 {
5298 cdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
5299 cdk_window_get_geometry (mv_resize->moveresize_window,
5300 NULL((void*)0), NULL((void*)0), &width, &height);
5301
5302 switch (mv_resize->moveresize_geometry.win_gravity)
5303 {
5304 case CDK_GRAVITY_NORTH_WEST:
5305 mv_resize->moveresize_orig_x = rect.x;
5306 mv_resize->moveresize_orig_y = rect.y;
5307 break;
5308 case CDK_GRAVITY_NORTH:
5309 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5310 mv_resize->moveresize_orig_y = rect.y;
5311 break;
5312 case CDK_GRAVITY_NORTH_EAST:
5313 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5314 mv_resize->moveresize_orig_y = rect.y;
5315 break;
5316 case CDK_GRAVITY_WEST:
5317 mv_resize->moveresize_orig_x = rect.x;
5318 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5319 break;
5320 case CDK_GRAVITY_CENTER:
5321 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5322 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5323 break;
5324 case CDK_GRAVITY_EAST:
5325 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5326 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5327 break;
5328 case CDK_GRAVITY_SOUTH_WEST:
5329 mv_resize->moveresize_orig_x = rect.x;
5330 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5331 break;
5332 case CDK_GRAVITY_SOUTH:
5333 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5334 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5335 break;
5336 case CDK_GRAVITY_SOUTH_EAST:
5337 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5338 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5339 break;
5340 default:
5341 mv_resize->moveresize_orig_x = rect.x;
5342 mv_resize->moveresize_orig_y = rect.y;
5343 break;
5344 }
5345 }
5346}
5347
5348static void
5349emulate_resize_drag (CdkWindow *window,
5350 CdkWindowEdge edge,
5351 CdkDevice *device,
5352 gint button,
5353 gint root_x,
5354 gint root_y,
5355 guint32 timestamp)
5356{
5357 MoveResizeData *mv_resize = get_move_resize_data (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, TRUE(!(0)));
5358
5359 if (mv_resize->moveresize_window != NULL((void*)0))
5360 return; /* already a drag operation in progress */
5361
5362 mv_resize->is_resize = TRUE(!(0));
5363 mv_resize->moveresize_button = button;
5364 mv_resize->resize_edge = edge;
5365 mv_resize->device = device;
5366 mv_resize->moveresize_x = root_x;
5367 mv_resize->moveresize_y = root_y;
5368 mv_resize->moveresize_window = g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
5369
5370 mv_resize->moveresize_orig_width = cdk_window_get_width (window);
5371 mv_resize->moveresize_orig_height = cdk_window_get_height (window);
5372
5373 mv_resize->moveresize_geom_mask = 0;
5374 cdk_window_get_geometry_hints (window,
5375 &mv_resize->moveresize_geometry,
5376 &mv_resize->moveresize_geom_mask);
5377
5378 calculate_unmoving_origin (mv_resize);
5379
5380 create_moveresize_window (mv_resize, timestamp);
5381}
5382
5383static void
5384emulate_move_drag (CdkWindow *window,
5385 CdkDevice *device,
5386 gint button,
5387 gint root_x,
5388 gint root_y,
5389 guint32 timestamp)
5390{
5391 MoveResizeData *mv_resize = get_move_resize_data (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
, TRUE(!(0)));
5392
5393 if (mv_resize->moveresize_window != NULL((void*)0))
5394 return; /* already a drag operation in progress */
5395
5396 mv_resize->is_resize = FALSE(0);
5397 mv_resize->device = device;
5398 mv_resize->moveresize_button = button;
5399 mv_resize->moveresize_x = root_x;
5400 mv_resize->moveresize_y = root_y;
5401
5402 mv_resize->moveresize_window = g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
5403
5404 calculate_unmoving_origin (mv_resize);
5405
5406 create_moveresize_window (mv_resize, timestamp);
5407}
5408
5409static gboolean
5410_should_perform_ewmh_drag (CdkWindow *window,
5411 CdkDevice *device)
5412{
5413 CdkPointerWindowInfo *info;
5414 CdkDisplay *display;
5415
5416 display = cdk_window_get_display (window);
5417 info = _cdk_display_get_pointer_info (display, device);
5418
5419 if ((!info->last_slave || cdk_device_get_source (info->last_slave) != CDK_SOURCE_TOUCHSCREEN) &&
5420 cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
5421 cdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
5422 return TRUE(!(0));
5423
5424 return FALSE(0);
5425}
5426
5427static void
5428cdk_x11_window_begin_resize_drag (CdkWindow *window,
5429 CdkWindowEdge edge,
5430 CdkDevice *device,
5431 gint button,
5432 gint root_x,
5433 gint root_y,
5434 guint32 timestamp)
5435{
5436 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
5437 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_FOREIGN
)
)
5438 return;
5439
5440 /* Avoid EWMH for touch devices */
5441 if (_should_perform_ewmh_drag (window, device))
5442 wmspec_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
5443 else
5444 emulate_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
5445}
5446
5447static void
5448cdk_x11_window_begin_move_drag (CdkWindow *window,
5449 CdkDevice *device,
5450 gint button,
5451 gint root_x,
5452 gint root_y,
5453 guint32 timestamp)
5454{
5455 gint direction;
5456
5457 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) || !WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
5458 return;
5459
5460 if (button == 0)
5461 direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD10;
5462 else
5463 direction = _NET_WM_MOVERESIZE_MOVE8;
5464
5465 /* Avoid EWMH for touch devices */
5466 if (_should_perform_ewmh_drag (window, device))
5467 wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
5468 else
5469 emulate_move_drag (window, device, button, root_x, root_y, timestamp);
5470}
5471
5472static gboolean
5473cdk_x11_window_beep (CdkWindow *window)
5474{
5475 CdkDisplay *display;
5476
5477 display = CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
;
5478
5479 if (!CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->trusted_client)
5480 return FALSE(0);
5481
5482#ifdef HAVE_XKB1
5483 if (CDK_X11_DISPLAY (display)((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))
->use_xkb)
5484 {
5485 XkbBell (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
5486 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)
,
5487 0,
5488 None0L);
5489 return TRUE(!(0));
5490 }
5491#endif
5492
5493 return FALSE(0);
5494}
5495
5496static void
5497cdk_x11_window_set_opacity (CdkWindow *window,
5498 gdouble opacity)
5499{
5500 CdkDisplay *display;
5501 gulong cardinal;
5502
5503 g_return_if_fail (CDK_IS_WINDOW (window))do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return; } } while (0)
;
5504
5505 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed) ||
5506 !WINDOW_IS_TOPLEVEL (window)(((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TOPLEVEL
|| ((((CdkWindow *)(window)))->window_type) == CDK_WINDOW_TEMP
)
)
5507 return;
5508
5509 display = cdk_window_get_display (window);
5510
5511 if (opacity < 0)
5512 opacity = 0;
5513 else if (opacity > 1)
5514 opacity = 1;
5515
5516 cardinal = opacity * 0xffffffff;
5517
5518 if (cardinal == 0xffffffff)
5519 XDeleteProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
5520 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)
,
5521 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"));
5522 else
5523 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
5524 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)
,
5525 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"),
5526 XA_CARDINAL((Atom) 6), 32,
5527 PropModeReplace0,
5528 (guchar *) &cardinal, 1);
5529}
5530
5531static void
5532cdk_x11_window_set_composited (CdkWindow *window,
5533 gboolean composited)
5534{
5535#if defined(HAVE_XCOMPOSITE1) && defined(HAVE_XDAMAGE1) && defined (HAVE_XFIXES1)
5536 CdkWindowImplX11 *impl;
5537 CdkDisplay *display;
5538 Display *dpy;
5539 Window xid;
5540
5541 impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
5542
5543 display = cdk_window_get_display (window);
5544 dpy = CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
;
5545 xid = 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)
;
5546
5547 if (composited)
5548 {
5549 XCompositeRedirectWindow (dpy, xid, CompositeRedirectManual1);
5550 impl->damage = XDamageCreate (dpy, xid, XDamageReportBoundingBox2);
5551 }
5552 else
5553 {
5554 XCompositeUnredirectWindow (dpy, xid, CompositeRedirectManual1);
5555 XDamageDestroy (dpy, impl->damage);
5556 impl->damage = None0L;
5557 }
5558#endif
5559}
5560
5561void
5562_cdk_x11_display_before_process_all_updates (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)))
5563{
5564}
5565
5566void
5567_cdk_x11_display_after_process_all_updates (CdkDisplay *display)
5568{
5569 /* Sync after all drawing, otherwise the client can get "ahead" of
5570 the server rendering during animations, such that we fill up
5571 the Xserver pipes with sync rendering ops not letting other
5572 clients (including the VM) do anything. */
5573 XSync (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, FALSE(0));
5574}
5575
5576static Boolint
5577timestamp_predicate (Display *display,
5578 XEvent *xevent,
5579 XPointer arg)
5580{
5581 Window xwindow = GPOINTER_TO_UINT (arg)((guint) (gulong) (arg));
5582 CdkDisplay *cdk_display = cdk_x11_lookup_xdisplay (display);
5583
5584 if (xevent->type == PropertyNotify28 &&
5585 xevent->xproperty.window == xwindow &&
5586 xevent->xproperty.atom == cdk_x11_get_xatom_by_name_for_display (cdk_display,
5587 "CDK_TIMESTAMP_PROP"))
5588 return True1;
5589
5590 return False0;
5591}
5592
5593/**
5594 * cdk_x11_get_server_time:
5595 * @window: (type CdkX11Window): a #CdkWindow, used for communication
5596 * with the server. The window must have
5597 * CDK_PROPERTY_CHANGE_MASK in its events mask or a hang will
5598 * result.
5599 *
5600 * Routine to get the current X server time stamp.
5601 *
5602 * Returns: the time stamp.
5603 **/
5604guint32
5605cdk_x11_get_server_time (CdkWindow *window)
5606{
5607 Display *xdisplay;
5608 Window xwindow;
5609 guchar c = 'a';
5610 XEvent xevent;
5611 Atom timestamp_prop_atom;
5612
5613 g_return_val_if_fail (CDK_IS_WINDOW (window), 0)do { if (((((__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; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_WINDOW (window)"); return (0); } } while (0)
;
5614 g_return_val_if_fail (!CDK_WINDOW_DESTROYED (window), 0)do { if ((!(((CdkWindow *)(window))->destroyed))) { } else
{ g_return_if_fail_warning ("Cdk", ((const char*) (__func__)
), "!CDK_WINDOW_DESTROYED (window)"); return (0); } } while (
0)
;
5615
5616 xdisplay = CDK_WINDOW_XDISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xdisplay)
;
5617 xwindow = 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)
;
5618 timestamp_prop_atom =
5619 cdk_x11_get_xatom_by_name_for_display (CDK_WINDOW_DISPLAY (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->display)
,
5620 "CDK_TIMESTAMP_PROP");
5621
5622 XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
5623 timestamp_prop_atom,
5624 8, PropModeReplace0, &c, 1);
5625
5626 XIfEvent (xdisplay, &xevent,
5627 timestamp_predicate, GUINT_TO_POINTER(xwindow)((gpointer) (gulong) (xwindow)));
5628
5629 return xevent.xproperty.time;
5630}
5631
5632/**
5633 * cdk_x11_window_get_xid:
5634 * @window: (type CdkX11Window): a native #CdkWindow.
5635 *
5636 * Returns the X resource (window) belonging to a #CdkWindow.
5637 *
5638 * Returns: the ID of @drawable’s X resource.
5639 **/
5640XID
5641cdk_x11_window_get_xid (CdkWindow *window)
5642{
5643 /* Try to ensure the window has a native window */
5644 if (!_cdk_window_has_impl (window))
5645 {
5646 cdk_window_ensure_native (window);
5647
5648 /* We sync here to ensure the window is created in the Xserver when
5649 * this function returns. This is required because the returned XID
5650 * for this window must be valid immediately, even with another
5651 * connection to the Xserver */
5652 cdk_display_sync (cdk_window_get_display (window));
5653 }
5654
5655 if (!CDK_WINDOW_IS_X11 (window)((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*)
(((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; })))))
)
5656 {
5657 g_warning (G_STRLOC"cdkwindow-x11.c" ":" "5657" " drawable is not a native X11 window");
5658 return None0L;
5659 }
5660
5661 return CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
->xid;
5662}
5663
5664static gint
5665cdk_x11_window_get_scale_factor (CdkWindow *window)
5666{
5667 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
5668
5669 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
5670 return 1;
5671
5672 return impl->window_scale;
5673}
5674
5675/**
5676 * cdk_x11_window_set_frame_sync_enabled:
5677 * @window: (type CdkX11Window): a native #CdkWindow
5678 * @frame_sync_enabled: whether frame-synchronization should be enabled
5679 *
5680 * This function can be used to disable frame synchronization for a window.
5681 * Normally frame synchronziation will be enabled or disabled based on whether
5682 * the system has a compositor that supports frame synchronization, but if
5683 * the window is not directly managed by the window manager, then frame
5684 * synchronziation may need to be disabled. This is the case for a window
5685 * embedded via the XEMBED protocol.
5686 *
5687 * Since: 3.8
5688 */
5689void
5690cdk_x11_window_set_frame_sync_enabled (CdkWindow *window,
5691 gboolean frame_sync_enabled G_GNUC_UNUSED__attribute__ ((__unused__)))
5692{
5693 /* Try to ensure the window has a native window */
5694 if (!_cdk_window_has_impl (window))
5695 cdk_window_ensure_native (window);
5696
5697 if (!CDK_WINDOW_IS_X11 (window)((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*)
(((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; })))))
)
5698 {
5699 g_warning (G_STRLOC"cdkwindow-x11.c" ":" "5699" " drawable is not a native X11 window");
5700 return;
5701 }
5702
5703 CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
->frame_sync_enabled = FALSE(0);
5704}
5705
5706static void
5707cdk_x11_window_set_opaque_region (CdkWindow *window,
5708 cairo_region_t *region)
5709{
5710 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
5711 CdkDisplay *display;
5712 int nitems;
5713 gulong *data;
5714
5715 if (CDK_WINDOW_DESTROYED (window)(((CdkWindow *)(window))->destroyed))
5716 return;
5717
5718 if (region != NULL((void*)0))
5719 {
5720 int i, nrects;
5721
5722 nrects = cairo_region_num_rectangles (region);
5723 nitems = nrects * 4;
5724 data = g_new (gulong, nitems)((gulong *) g_malloc_n ((nitems), sizeof (gulong)));
5725
5726 for (i = 0; i < nrects; i++)
5727 {
5728 cairo_rectangle_int_t rect;
5729 cairo_region_get_rectangle (region, i, &rect);
5730 data[i*4+0] = rect.x * impl->window_scale;
5731 data[i*4+1] = rect.y * impl->window_scale;
5732 data[i*4+2] = rect.width * impl->window_scale;
5733 data[i*4+3] = rect.height * impl->window_scale;
5734 }
5735 }
5736 else
5737 {
5738 nitems = 0;
5739 data = NULL((void*)0);
5740 }
5741
5742 display = cdk_window_get_display (window);
5743
5744 XChangeProperty (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
,
5745 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)
,
5746 cdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_OPAQUE_REGION"),
5747 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
5748 (guchar *) data, nitems);
5749
5750 g_free (data);
5751}
5752
5753static gboolean
5754cdk_x11_window_show_window_menu (CdkWindow *window,
5755 CdkEvent *event)
5756{
5757 CdkWindowImplX11 *impl = CDK_WINDOW_IMPL_X11 (window->impl)((((CdkWindowImplX11*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((window->impl)), ((cdk_window_impl_x11_get_type
()))))))
;
5758 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)
;
5759 CdkDevice *device;
5760 int device_id;
5761 double x_root, y_root;
5762 XClientMessageEvent xclient = { 0 };
5763
5764 switch (event->type)
5765 {
5766 case CDK_BUTTON_PRESS:
5767 case CDK_BUTTON_RELEASE:
5768 break;
5769 default:
5770 return FALSE(0);
5771 }
5772
5773 if (!cdk_x11_screen_supports_net_wm_hint (CDK_WINDOW_SCREEN (window)(cdk_window_get_screen (window)),
5774 cdk_atom_intern_static_string ("_CTK_SHOW_WINDOW_MENU")))
5775 return FALSE(0);
5776
5777 cdk_event_get_root_coords (event, &x_root, &y_root);
5778 device = cdk_event_get_device (event);
5779 g_object_get (G_OBJECT (device)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((device)), (((GType) ((20) << (2))))))))
,
5780 "device-id", &device_id,
5781 NULL((void*)0));
5782
5783 /* Ungrab the implicit grab */
5784 cdk_seat_ungrab (cdk_device_get_seat (device));
5785
5786 xclient.type = ClientMessage33;
5787 xclient.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)
;
5788 xclient.message_type = cdk_x11_get_xatom_by_name_for_display (display, "_CTK_SHOW_WINDOW_MENU");
5789 xclient.data.l[0] = device_id;
5790 xclient.data.l[1] = x_root * impl->window_scale;
5791 xclient.data.l[2] = y_root * impl->window_scale;
5792 xclient.format = 32;
5793
5794 XSendEvent (CDK_DISPLAY_XDISPLAY (display)(((((CdkX11Display*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display)), ((cdk_x11_display_get_type()))))))->xdisplay
)
, CDK_WINDOW_XROOTWIN (window)(((((CdkX11Screen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((cdk_window_get_screen (window)))), ((cdk_x11_screen_get_type
()))))))->xroot_window)
, False0,
5795 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
5796 (XEvent *)&xclient);
5797
5798 return TRUE(!(0));
5799}
5800
5801static void
5802cdk_window_impl_x11_class_init (CdkWindowImplX11Class *klass)
5803{
5804 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
5805 CdkWindowImplClass *impl_class = CDK_WINDOW_IMPL_CLASS (klass)((((CdkWindowImplClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((cdk_window_impl_get_type ()))))))
;
5806
5807 object_class->finalize = cdk_window_impl_x11_finalize;
5808
5809 impl_class->ref_cairo_surface = cdk_x11_ref_cairo_surface;
5810 impl_class->show = cdk_window_x11_show;
5811 impl_class->hide = cdk_window_x11_hide;
5812 impl_class->withdraw = cdk_window_x11_withdraw;
5813 impl_class->set_events = cdk_window_x11_set_events;
5814 impl_class->get_events = cdk_window_x11_get_events;
5815 impl_class->raise = cdk_window_x11_raise;
5816 impl_class->lower = cdk_window_x11_lower;
5817 impl_class->restack_under = cdk_window_x11_restack_under;
5818 impl_class->restack_toplevel = cdk_window_x11_restack_toplevel;
5819 impl_class->move_resize = cdk_window_x11_move_resize;
5820 impl_class->set_background = cdk_window_x11_set_background;
5821 impl_class->reparent = cdk_window_x11_reparent;
5822 impl_class->set_device_cursor = cdk_window_x11_set_device_cursor;
5823 impl_class->get_geometry = cdk_window_x11_get_geometry;
5824 impl_class->get_root_coords = cdk_window_x11_get_root_coords;
5825 impl_class->get_device_state = cdk_window_x11_get_device_state;
5826 impl_class->shape_combine_region = cdk_window_x11_shape_combine_region;
5827 impl_class->input_shape_combine_region = cdk_window_x11_input_shape_combine_region;
5828 impl_class->queue_antiexpose = _cdk_x11_window_queue_antiexpose;
5829 impl_class->destroy = cdk_x11_window_destroy;
5830 impl_class->destroy_foreign = cdk_x11_window_destroy_foreign;
5831 impl_class->get_shape = cdk_x11_window_get_shape;
5832 impl_class->get_input_shape = cdk_x11_window_get_input_shape;
5833 impl_class->beep = cdk_x11_window_beep;
5834
5835 impl_class->focus = cdk_x11_window_focus;
5836 impl_class->set_type_hint = cdk_x11_window_set_type_hint;
5837 impl_class->get_type_hint = cdk_x11_window_get_type_hint;
5838 impl_class->set_modal_hint = cdk_x11_window_set_modal_hint;
5839 impl_class->set_skip_taskbar_hint = cdk_x11_window_set_skip_taskbar_hint;
5840 impl_class->set_skip_pager_hint = cdk_x11_window_set_skip_pager_hint;
5841 impl_class->set_urgency_hint = cdk_x11_window_set_urgency_hint;
5842 impl_class->set_geometry_hints = cdk_x11_window_set_geometry_hints;
5843 impl_class->set_title = cdk_x11_window_set_title;
5844 impl_class->set_role = cdk_x11_window_set_role;
5845 impl_class->set_startup_id = cdk_x11_window_set_startup_id;
5846 impl_class->set_transient_for = cdk_x11_window_set_transient_for;
5847 impl_class->get_frame_extents = cdk_x11_window_get_frame_extents;
5848 impl_class->set_override_redirect = cdk_x11_window_set_override_redirect;
5849 impl_class->set_accept_focus = cdk_x11_window_set_accept_focus;
5850 impl_class->set_focus_on_map = cdk_x11_window_set_focus_on_map;
5851 impl_class->set_icon_list = cdk_x11_window_set_icon_list;
5852 impl_class->set_icon_name = cdk_x11_window_set_icon_name;
5853 impl_class->iconify = cdk_x11_window_iconify;
5854 impl_class->deiconify = cdk_x11_window_deiconify;
5855 impl_class->stick = cdk_x11_window_stick;
5856 impl_class->unstick = cdk_x11_window_unstick;
5857 impl_class->maximize = cdk_x11_window_maximize;
5858 impl_class->unmaximize = cdk_x11_window_unmaximize;
5859 impl_class->fullscreen = cdk_x11_window_fullscreen;
5860 impl_class->fullscreen_on_monitor = cdk_x11_window_fullscreen_on_monitor;
5861 impl_class->apply_fullscreen_mode = cdk_x11_window_apply_fullscreen_mode;
5862 impl_class->unfullscreen = cdk_x11_window_unfullscreen;
5863 impl_class->set_keep_above = cdk_x11_window_set_keep_above;
5864 impl_class->set_keep_below = cdk_x11_window_set_keep_below;
5865 impl_class->get_group = cdk_x11_window_get_group;
5866 impl_class->set_group = cdk_x11_window_set_group;
5867 impl_class->set_decorations = cdk_x11_window_set_decorations;
5868 impl_class->get_decorations = cdk_x11_window_get_decorations;
5869 impl_class->set_functions = cdk_x11_window_set_functions;
5870 impl_class->begin_resize_drag = cdk_x11_window_begin_resize_drag;
5871 impl_class->begin_move_drag = cdk_x11_window_begin_move_drag;
5872 impl_class->set_opacity = cdk_x11_window_set_opacity;
5873 impl_class->set_composited = cdk_x11_window_set_composited;
5874 impl_class->destroy_notify = cdk_x11_window_destroy_notify;
5875 impl_class->get_drag_protocol = cdk_x11_window_get_drag_protocol;
5876 impl_class->register_dnd = _cdk_x11_window_register_dnd;
5877 impl_class->drag_begin = _cdk_x11_window_drag_begin;
5878 impl_class->sync_rendering = _cdk_x11_window_sync_rendering;
5879 impl_class->simulate_key = _cdk_x11_window_simulate_key;
5880 impl_class->simulate_button = _cdk_x11_window_simulate_button;
5881 impl_class->get_property = _cdk_x11_window_get_property;
5882 impl_class->change_property = _cdk_x11_window_change_property;
5883 impl_class->delete_property = _cdk_x11_window_delete_property;
5884 impl_class->get_scale_factor = cdk_x11_window_get_scale_factor;
5885 impl_class->set_opaque_region = cdk_x11_window_set_opaque_region;
5886 impl_class->set_shadow_width = cdk_x11_window_set_shadow_width;
5887 impl_class->show_window_menu = cdk_x11_window_show_window_menu;
5888 impl_class->create_gl_context = cdk_x11_window_create_gl_context;
5889 impl_class->invalidate_for_new_frame = cdk_x11_window_invalidate_for_new_frame;
5890 impl_class->get_unscaled_size = cdk_x11_window_get_unscaled_size;
5891}