File: | cdk/x11/cdkwindow-x11.c |
Warning: | line 4503, column 10 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
75 | const 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 | |
100 | const 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 */ |
103 | static void cdk_x11_window_apply_fullscreen_mode (CdkWindow *window); |
104 | static gboolean cdk_window_icon_name_set (CdkWindow *window); |
105 | static void set_wm_name (CdkDisplay *display, |
106 | Window xwindow, |
107 | const gchar *name); |
108 | static void move_to_current_desktop (CdkWindow *window); |
109 | static void cdk_window_x11_set_background (CdkWindow *window, |
110 | cairo_pattern_t *pattern); |
111 | |
112 | static 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 | |
131 | struct _CdkX11Window { |
132 | CdkWindow parent; |
133 | }; |
134 | |
135 | struct _CdkX11WindowClass { |
136 | CdkWindowClass parent_class; |
137 | }; |
138 | |
139 | G_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 | |
141 | static void |
142 | cdk_x11_window_class_init (CdkX11WindowClass *x11_window_class G_GNUC_UNUSED__attribute__ ((__unused__))) |
143 | { |
144 | } |
145 | |
146 | static void |
147 | cdk_x11_window_init (CdkX11Window *x11_window G_GNUC_UNUSED__attribute__ ((__unused__))) |
148 | { |
149 | } |
150 | |
151 | |
152 | G_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 | |
154 | static void |
155 | cdk_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 | |
163 | CdkToplevelX11 * |
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 | **/ |
191 | void |
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 | |
201 | void |
202 | cdk_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 | |
215 | static void |
216 | set_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 | |
228 | static void |
229 | window_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 | |
249 | static void |
250 | on_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 | |
268 | static void |
269 | hook_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 | |
295 | static void |
296 | unhook_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 | |
310 | static void |
311 | cdk_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 | |
356 | static void |
357 | cdk_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 | |
396 | static void |
397 | cdk_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 | |
474 | static cairo_surface_t * |
475 | cdk_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 | |
488 | static cairo_surface_t * |
489 | cdk_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 | |
512 | static void |
513 | cdk_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 | |
548 | typedef struct { |
549 | CdkDisplay *display; |
550 | Pixmap pixmap; |
551 | } FreePixmapData; |
552 | |
553 | static void |
554 | free_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 | |
568 | static void |
569 | attach_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 | */ |
588 | cairo_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 */ |
609 | static cairo_surface_t * |
610 | cdk_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 | |
632 | static void |
633 | tmp_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 | |
645 | static void |
646 | tmp_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 | */ |
664 | void |
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 | |
690 | void |
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 | |
700 | void |
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 | |
727 | void |
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 | |
738 | void |
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 | |
784 | static void |
785 | set_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 | |
803 | static const gchar * |
804 | get_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 | |
817 | static void |
818 | check_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 | |
832 | static Window |
833 | create_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 | |
865 | static void |
866 | ensure_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 | |
904 | static void |
905 | setup_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 | |
981 | static void |
982 | on_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 | |
989 | static void |
990 | on_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 | |
997 | static void |
998 | connect_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 | |
1016 | static void |
1017 | clamp_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 | |
1035 | void |
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 | |
1193 | static CdkEventMask |
1194 | x_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 | */ |
1227 | CdkWindow * |
1228 | cdk_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 | |
1317 | static void |
1318 | cdk_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 | |
1351 | static void |
1352 | cdk_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 | |
1380 | static void |
1381 | cdk_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 | |
1412 | static CdkWindow * |
1413 | get_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 | */ |
1422 | static void |
1423 | cdk_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 | |
1446 | static CdkDragProtocol |
1447 | cdk_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 | |
1472 | static void |
1473 | update_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 | |
1524 | static void |
1525 | set_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 | |
1653 | static void |
1654 | cdk_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 | |
1701 | static void |
1702 | pre_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 | |
1718 | static void |
1719 | post_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 | |
1748 | static void |
1749 | cdk_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 | |
1780 | static void |
1781 | cdk_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 | |
1801 | static inline void |
1802 | window_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 | |
1830 | static inline void |
1831 | window_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 | |
1873 | static inline void |
1874 | window_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 | |
1922 | static void |
1923 | cdk_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 | |
1943 | static void |
1944 | set_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 | |
1961 | void |
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 | |
2027 | static gboolean |
2028 | cdk_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 | |
2104 | static void |
2105 | cdk_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 | |
2110 | static void |
2111 | cdk_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 | |
2132 | static void |
2133 | cdk_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 | |
2147 | static void |
2148 | cdk_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 | */ |
2164 | void |
2165 | cdk_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 | |
2180 | static void |
2181 | move_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 | |
2189 | static guint32 |
2190 | get_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 | */ |
2233 | guint32 |
2234 | cdk_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 | */ |
2252 | void |
2253 | cdk_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 | |
2286 | static void |
2287 | cdk_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 | |
2337 | static void |
2338 | cdk_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 | |
2405 | static CdkWindowTypeHint |
2406 | cdk_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 | |
2472 | static void |
2473 | cdk_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 | |
2501 | static void |
2502 | cdk_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 | |
2517 | static void |
2518 | cdk_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 | |
2538 | static void |
2539 | cdk_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 | |
2559 | static void |
2560 | cdk_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 | |
2577 | static void |
2578 | cdk_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) || |
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 )) |
2588 | return; |
2589 | |
2590 | toplevel = _cdk_x11_window_get_toplevel (window); |
2591 | if (toplevel) |
2592 | { |
2593 | if (geometry) |
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) |
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) |
2612 | { |
2613 | size_hints.flags |= USPosition(1L << 0); |
2614 | } |
2615 | |
2616 | if (geom_mask & CDK_HINT_USER_SIZE) |
2617 | { |
2618 | size_hints.flags |= USSize(1L << 1); |
2619 | } |
2620 | |
2621 | if (geom_mask & CDK_HINT_MIN_SIZE) |
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) |
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) |
2636 | { |
2637 | size_hints.flags |= PBaseSize(1L << 8); |
2638 | size_hints.base_width = geometry->base_width * impl->window_scale; |
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 | |
2694 | static void |
2695 | cdk_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 | |
2763 | static gboolean |
2764 | utf8_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 | */ |
2784 | static void |
2785 | set_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 | */ |
2833 | static void |
2834 | set_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 | |
2848 | static void |
2849 | cdk_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 | |
2881 | static void |
2882 | cdk_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 | |
2902 | static void |
2903 | cdk_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 | |
2926 | static void |
2927 | cdk_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 | |
2937 | static gboolean |
2938 | cdk_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 | |
2997 | static gboolean |
2998 | matrix_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 | |
3005 | static void |
3006 | cdk_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 | |
3025 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" |
3026 | parent_relative_pattern = cdk_x11_get_parent_relative_pattern (); |
3027 | G_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 | |
3113 | static void |
3114 | cdk_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 | |
3138 | CdkCursor * |
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 | |
3150 | static void |
3151 | cdk_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 | |
3186 | static void |
3187 | cdk_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 | |
3210 | static void |
3211 | cdk_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 | |
3381 | static gboolean |
3382 | cdk_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 | |
3401 | static CdkEventMask |
3402 | cdk_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 | } |
3423 | static void |
3424 | cdk_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 | |
3442 | static inline void |
3443 | do_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 | |
3516 | static void |
3517 | cdk_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 | |
3525 | static void |
3526 | cdk_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 | |
3537 | static void |
3538 | cdk_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 | |
3558 | static void |
3559 | cdk_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 | |
3574 | static void |
3575 | cdk_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 | **/ |
3611 | void |
3612 | cdk_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 *)×tamp_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 | */ |
3668 | void |
3669 | cdk_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 | */ |
3711 | void |
3712 | cdk_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 | |
3739 | static void |
3740 | cdk_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 | */ |
3779 | void |
3780 | cdk_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 | */ |
3806 | void |
3807 | cdk_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 | |
3820 | static void |
3821 | cdk_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 | |
3920 | static void |
3921 | cdk_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 | |
4024 | static gboolean |
4025 | cdk_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 | |
4031 | static void |
4032 | cdk_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 | |
4069 | static void |
4070 | cdk_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 | |
4094 | static void |
4095 | cdk_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 | |
4120 | static void |
4121 | cdk_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 | |
4168 | static void |
4169 | cdk_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 | |
4194 | static void |
4195 | cdk_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 | |
4211 | static void |
4212 | cdk_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 | |
4228 | static void |
4229 | cdk_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 | |
4320 | static void |
4321 | cdk_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 | |
4344 | static void |
4345 | cdk_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 | |
4354 | G_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); |
4357 | G_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 | |
4363 | static void |
4364 | cdk_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 | |
4381 | static void |
4382 | cdk_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 | |
4407 | static void |
4408 | cdk_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 | |
4432 | static CdkWindow * |
4433 | cdk_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 | |
4446 | static void |
4447 | cdk_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 | |
4477 | static MotifWmHints * |
4478 | cdk_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; |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
4504 | } |
4505 | |
4506 | static void |
4507 | cdk_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 | |
4557 | static void |
4558 | cdk_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 | |
4575 | static gboolean |
4576 | cdk_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 | |
4603 | static void |
4604 | cdk_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 | |
4623 | cairo_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 | |
4679 | static cairo_region_t * |
4680 | cdk_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 | |
4694 | static cairo_region_t * |
4695 | cdk_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 | |
4725 | static void |
4726 | wmspec_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 | |
4753 | static void |
4754 | handle_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 | |
4788 | static void |
4789 | wmspec_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 | |
4806 | static void |
4807 | wmspec_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 | |
4866 | typedef struct _MoveResizeData MoveResizeData; |
4867 | |
4868 | struct _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 | |
4890 | static MoveResizeData * |
4891 | get_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 | |
4913 | static void |
4914 | check_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 | |
4935 | static void |
4936 | check_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 | |
4958 | static void |
4959 | update_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 | |
5042 | static void |
5043 | finish_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 | |
5051 | static int |
5052 | lookahead_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 | |
5078 | static gboolean |
5079 | moveresize_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 | |
5102 | gboolean |
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 | |
5210 | gboolean |
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 | |
5232 | static void |
5233 | create_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 | */ |
5283 | static void |
5284 | calculate_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 | |
5348 | static void |
5349 | emulate_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 | |
5383 | static void |
5384 | emulate_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 | |
5409 | static 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 | |
5427 | static void |
5428 | cdk_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 | |
5447 | static void |
5448 | cdk_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 | |
5472 | static gboolean |
5473 | cdk_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 | |
5496 | static void |
5497 | cdk_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 | |
5531 | static void |
5532 | cdk_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 | |
5561 | void |
5562 | _cdk_x11_display_before_process_all_updates (CdkDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__))) |
5563 | { |
5564 | } |
5565 | |
5566 | void |
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 | |
5576 | static Boolint |
5577 | timestamp_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 | **/ |
5604 | guint32 |
5605 | cdk_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 | **/ |
5640 | XID |
5641 | cdk_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 | |
5664 | static gint |
5665 | cdk_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 | */ |
5689 | void |
5690 | cdk_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 | |
5706 | static void |
5707 | cdk_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 | |
5753 | static gboolean |
5754 | cdk_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 | |
5801 | static void |
5802 | cdk_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 | } |