1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
34 #include "gdkwindow.h"
35 #include "gdkinputprivate.h"
36 #include "gdkprivate-x11.h"
46 #include <X11/extensions/shape.h>
49 const int gdk_event_mask_table[21] =
53 PointerMotionHintMask,
70 SubstructureNotifyMask,
71 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
73 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
75 /* Forward declarations */
76 static gboolean gdk_window_gravity_works (void);
77 static void gdk_window_set_static_win_gravity (GdkWindow *window,
79 static gboolean gdk_window_have_shape_ext (void);
82 gdk_x11_window_destroy (GdkDrawable *drawable)
84 if (!GDK_DRAWABLE_DESTROYED (drawable))
86 if (GDK_DRAWABLE_TYPE (drawable) == GDK_WINDOW_FOREIGN)
87 gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable));
89 g_warning ("losing last reference to undestroyed window\n");
92 g_free (GDK_DRAWABLE_XDATA (drawable));
96 gdk_x11_window_alloc (void)
99 GdkWindowPrivate *private;
101 static GdkDrawableClass klass;
102 static gboolean initialized = FALSE;
108 klass = _gdk_x11_drawable_class;
109 klass.destroy = gdk_x11_window_destroy;
112 window = _gdk_window_alloc ();
113 private = (GdkWindowPrivate *)window;
115 private->drawable.klass = &klass;
116 private->drawable.klass_data = g_new (GdkDrawableXData, 1);
122 gdk_window_init (void)
124 GdkWindowPrivate *private;
125 XWindowAttributes xattributes;
128 unsigned int border_width;
132 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
133 &x, &y, &width, &height, &border_width, &depth);
134 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
136 gdk_parent_root = gdk_x11_window_alloc ();
137 private = (GdkWindowPrivate *)gdk_parent_root;
139 GDK_DRAWABLE_XDATA (gdk_parent_root)->xdisplay = gdk_display;
140 GDK_DRAWABLE_XDATA (gdk_parent_root)->xid = gdk_root_window;
142 private->drawable.window_type = GDK_WINDOW_ROOT;
143 private->drawable.width = width;
144 private->drawable.height = height;
146 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
149 static GdkAtom wm_client_leader_atom = GDK_NONE;
152 gdk_window_new (GdkWindow *parent,
153 GdkWindowAttr *attributes,
154 gint attributes_mask)
157 GdkWindowPrivate *private;
158 GdkWindowPrivate *parent_private;
164 XSetWindowAttributes xattributes;
165 long xattributes_mask;
166 XSizeHints size_hints;
168 XClassHint *class_hint;
175 g_return_val_if_fail (attributes != NULL, NULL);
178 parent = gdk_parent_root;
180 parent_private = (GdkWindowPrivate*) parent;
181 if (GDK_DRAWABLE_DESTROYED (parent))
184 xparent = GDK_DRAWABLE_XID (parent);
186 window = gdk_x11_window_alloc ();
187 private = (GdkWindowPrivate *)window;
189 GDK_DRAWABLE_XDATA (window)->xdisplay = GDK_DRAWABLE_XDISPLAY (parent);
191 private->parent = parent;
193 xattributes_mask = 0;
195 if (attributes_mask & GDK_WA_X)
200 if (attributes_mask & GDK_WA_Y)
207 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
208 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
209 private->drawable.window_type = attributes->window_type;
211 if (attributes_mask & GDK_WA_VISUAL)
212 visual = attributes->visual;
214 visual = gdk_visual_get_system ();
215 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
217 xattributes.event_mask = StructureNotifyMask;
218 for (i = 0; i < gdk_nevent_masks; i++)
220 if (attributes->event_mask & (1 << (i + 1)))
221 xattributes.event_mask |= gdk_event_mask_table[i];
224 if (xattributes.event_mask)
225 xattributes_mask |= CWEventMask;
227 if (attributes_mask & GDK_WA_NOREDIR)
229 xattributes.override_redirect =
230 (attributes->override_redirect == FALSE)?False:True;
231 xattributes_mask |= CWOverrideRedirect;
234 xattributes.override_redirect = False;
236 if (parent_private && parent_private->guffaw_gravity)
238 xattributes.win_gravity = StaticGravity;
239 xattributes_mask |= CWWinGravity;
242 if (attributes->wclass == GDK_INPUT_OUTPUT)
245 depth = visual->depth;
247 if (attributes_mask & GDK_WA_COLORMAP)
248 private->drawable.colormap = attributes->colormap;
251 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
252 private->drawable.colormap = gdk_colormap_get_system ();
254 private->drawable.colormap = gdk_colormap_new (visual, False);
257 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
258 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
259 xattributes_mask |= CWBorderPixel | CWBackPixel;
261 switch (private->drawable.window_type)
263 case GDK_WINDOW_TOPLEVEL:
264 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
265 xattributes_mask |= CWColormap;
267 xparent = gdk_root_window;
270 case GDK_WINDOW_CHILD:
271 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
272 xattributes_mask |= CWColormap;
275 case GDK_WINDOW_DIALOG:
276 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
277 xattributes_mask |= CWColormap;
279 xparent = gdk_root_window;
282 case GDK_WINDOW_TEMP:
283 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
284 xattributes_mask |= CWColormap;
286 xparent = gdk_root_window;
288 xattributes.save_under = True;
289 xattributes.override_redirect = True;
290 xattributes.cursor = None;
291 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
293 case GDK_WINDOW_ROOT:
294 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
296 case GDK_WINDOW_PIXMAP:
297 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
305 private->drawable.colormap = NULL;
308 GDK_DRAWABLE_XDATA (private)->xid = XCreateWindow (GDK_DRAWABLE_XDISPLAY (parent),
310 x, y, private->drawable.width, private->drawable.height,
311 0, depth, class, xvisual,
312 xattributes_mask, &xattributes);
313 gdk_drawable_ref (window);
314 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
316 if (private->drawable.colormap)
317 gdk_colormap_ref (private->drawable.colormap);
319 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
320 (attributes->cursor) :
324 parent_private->children = g_list_prepend (parent_private->children, window);
326 switch (private->drawable.window_type)
328 case GDK_WINDOW_DIALOG:
329 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
330 GDK_DRAWABLE_XID (window),
332 case GDK_WINDOW_TOPLEVEL:
333 case GDK_WINDOW_TEMP:
334 XSetWMProtocols (GDK_DRAWABLE_XDISPLAY (window),
335 GDK_DRAWABLE_XID (window),
336 gdk_wm_window_protocols, 2);
338 case GDK_WINDOW_CHILD:
339 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
340 (private->drawable.colormap != gdk_colormap_get_system ()) &&
341 (private->drawable.colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
343 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
344 gdk_window_add_colormap_windows (window);
353 size_hints.flags = PSize;
354 size_hints.width = private->drawable.width;
355 size_hints.height = private->drawable.height;
357 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
358 wm_hints.window_group = gdk_leader_window;
359 wm_hints.input = True;
360 wm_hints.initial_state = NormalState;
362 /* FIXME: Is there any point in doing this? Do any WM's pay
363 * attention to PSize, and even if they do, is this the
366 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
367 GDK_DRAWABLE_XID (window),
370 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
371 GDK_DRAWABLE_XID (window),
374 if (!wm_client_leader_atom)
375 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
377 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window),
378 GDK_DRAWABLE_XID (window),
379 wm_client_leader_atom,
380 XA_WINDOW, 32, PropModeReplace,
381 (guchar*) &gdk_leader_window, 1);
383 if (attributes_mask & GDK_WA_TITLE)
384 title = attributes->title;
386 title = g_get_prgname ();
388 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
389 GDK_DRAWABLE_XID (window),
394 if (attributes_mask & GDK_WA_WMCLASS)
396 class_hint = XAllocClassHint ();
397 class_hint->res_name = attributes->wmclass_name;
398 class_hint->res_class = attributes->wmclass_class;
399 XSetClassHint (GDK_DRAWABLE_XDISPLAY (window),
400 GDK_DRAWABLE_XID (window),
409 gdk_window_foreign_new (guint32 anid)
412 GdkWindowPrivate *private;
413 GdkWindowPrivate *parent_private;
414 XWindowAttributes attrs;
416 Window *children = NULL;
420 gdk_error_trap_push ();
421 result = XGetWindowAttributes (gdk_display, anid, &attrs);
422 if (gdk_error_trap_pop () || !result)
425 /* FIXME: This is pretty expensive. Maybe the caller should supply
427 gdk_error_trap_push ();
428 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
429 if (gdk_error_trap_pop () || !result)
435 window = gdk_x11_window_alloc ();
436 private = (GdkWindowPrivate *)window;
438 private->parent = gdk_xid_table_lookup (parent);
440 parent_private = (GdkWindowPrivate *)private->parent;
443 parent_private->children = g_list_prepend (parent_private->children, window);
445 GDK_DRAWABLE_XDATA (window)->xid = anid;
446 GDK_DRAWABLE_XDATA (window)->xdisplay = GDK_DRAWABLE_XDISPLAY (parent);
448 private->x = attrs.x;
449 private->y = attrs.y;
450 private->drawable.width = attrs.width;
451 private->drawable.height = attrs.height;
452 private->drawable.window_type = GDK_WINDOW_FOREIGN;
453 private->drawable.destroyed = FALSE;
454 private->mapped = (attrs.map_state != IsUnmapped);
456 gdk_drawable_ref (window);
457 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
462 /* Call this function when you want a window and all its children to
463 * disappear. When xdestroy is true, a request to destroy the XWindow
464 * is sent out. When it is false, it is assumed that the XWindow has
465 * been or will be destroyed by destroying some ancestor of this
469 gdk_window_internal_destroy (GdkWindow *window,
471 gboolean our_destroy)
473 GdkWindowPrivate *private;
474 GdkWindowPrivate *temp_private;
475 GdkWindow *temp_window;
479 g_return_if_fail (window != NULL);
481 private = (GdkWindowPrivate*) window;
483 switch (private->drawable.window_type)
485 case GDK_WINDOW_TOPLEVEL:
486 case GDK_WINDOW_CHILD:
487 case GDK_WINDOW_DIALOG:
488 case GDK_WINDOW_TEMP:
489 case GDK_WINDOW_FOREIGN:
490 if (!private->drawable.destroyed)
494 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
495 if (parent_private->children)
496 parent_private->children = g_list_remove (parent_private->children, window);
499 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
501 children = tmp = private->children;
502 private->children = NULL;
506 temp_window = tmp->data;
509 temp_private = (GdkWindowPrivate*) temp_window;
511 gdk_window_internal_destroy (temp_window, FALSE,
515 g_list_free (children);
518 if (private->extension_events != 0)
519 gdk_input_window_destroy (window);
521 if (private->filters)
523 tmp = private->filters;
531 g_list_free (private->filters);
532 private->filters = NULL;
535 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
537 if (our_destroy && (private->parent != NULL))
539 /* It's somebody elses window, but in our heirarchy,
540 * so reparent it to the root window, and then send
541 * it a delete event, as if we were a WM
543 XClientMessageEvent xevent;
545 gdk_error_trap_push ();
546 gdk_window_hide (window);
547 gdk_window_reparent (window, NULL, 0, 0);
549 xevent.type = ClientMessage;
550 xevent.window = GDK_DRAWABLE_XID (window);
551 xevent.message_type = gdk_wm_protocols;
553 xevent.data.l[0] = gdk_wm_delete_window;
554 xevent.data.l[1] = CurrentTime;
556 XSendEvent (GDK_DRAWABLE_XDISPLAY (window),
557 GDK_DRAWABLE_XID (window),
558 False, 0, (XEvent *)&xevent);
560 gdk_error_trap_pop ();
564 XDestroyWindow (GDK_DRAWABLE_XDISPLAY (window),
565 GDK_DRAWABLE_XID (window));
567 if (private->drawable.colormap)
568 gdk_colormap_unref (private->drawable.colormap);
570 private->mapped = FALSE;
571 private->drawable.destroyed = TRUE;
575 case GDK_WINDOW_ROOT:
576 g_error ("attempted to destroy root window");
579 case GDK_WINDOW_PIXMAP:
580 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
585 /* Like internal_destroy, but also destroys the reference created by
589 gdk_window_destroy (GdkWindow *window)
591 gdk_window_internal_destroy (window, TRUE, TRUE);
592 gdk_drawable_unref (window);
595 /* This function is called when the XWindow is really gone. */
598 gdk_window_destroy_notify (GdkWindow *window)
600 g_return_if_fail (window != NULL);
602 if (!GDK_DRAWABLE_DESTROYED (window))
604 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
605 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_DRAWABLE_XID (window));
607 gdk_window_internal_destroy (window, FALSE, FALSE);
610 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
611 gdk_drawable_unref (window);
615 gdk_window_show (GdkWindow *window)
617 GdkWindowPrivate *private;
619 g_return_if_fail (window != NULL);
621 private = (GdkWindowPrivate*) window;
622 if (!private->drawable.destroyed)
624 private->mapped = TRUE;
625 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window),
626 GDK_DRAWABLE_XID (window));
627 XMapWindow (GDK_DRAWABLE_XDISPLAY (window),
628 GDK_DRAWABLE_XID (window));
633 gdk_window_hide (GdkWindow *window)
635 GdkWindowPrivate *private;
637 g_return_if_fail (window != NULL);
639 private = (GdkWindowPrivate*) window;
640 if (!private->drawable.destroyed)
642 private->mapped = FALSE;
643 XUnmapWindow (GDK_DRAWABLE_XDISPLAY (window),
644 GDK_DRAWABLE_XID (window));
649 gdk_window_withdraw (GdkWindow *window)
651 GdkWindowPrivate *private;
653 g_return_if_fail (window != NULL);
655 private = (GdkWindowPrivate*) window;
656 if (!private->drawable.destroyed)
657 XWithdrawWindow (GDK_DRAWABLE_XDISPLAY (window),
658 GDK_DRAWABLE_XID (window), 0);
662 gdk_window_move (GdkWindow *window,
666 GdkWindowPrivate *private;
668 g_return_if_fail (window != NULL);
670 private = (GdkWindowPrivate*) window;
671 if (!private->drawable.destroyed)
673 XMoveWindow (GDK_DRAWABLE_XDISPLAY (window),
674 GDK_DRAWABLE_XID (window),
677 if (private->drawable.window_type == GDK_WINDOW_CHILD)
686 gdk_window_resize (GdkWindow *window,
690 GdkWindowPrivate *private;
692 g_return_if_fail (window != NULL);
693 g_return_if_fail (GDK_IS_WINDOW (window));
700 private = (GdkWindowPrivate*) window;
702 if (!private->drawable.destroyed &&
703 ((private->resize_count > 0) ||
704 (private->drawable.width != (guint16) width) ||
705 (private->drawable.height != (guint16) height)))
707 XResizeWindow (GDK_DRAWABLE_XDISPLAY (private),
708 GDK_DRAWABLE_XID (private),
710 private->resize_count += 1;
712 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
714 private->drawable.width = width;
715 private->drawable.height = height;
721 gdk_window_move_resize (GdkWindow *window,
727 GdkWindowPrivate *private;
729 g_return_if_fail (window != NULL);
730 g_return_if_fail (GDK_IS_WINDOW (window));
737 private = (GdkWindowPrivate*) window;
739 if (!GDK_DRAWABLE_DESTROYED (window))
741 XMoveResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
742 GDK_DRAWABLE_XID (window),
743 x, y, width, height);
745 if (private->guffaw_gravity)
747 GList *tmp_list = private->children;
750 GdkWindowPrivate *child_private = tmp_list->data;
752 child_private->x -= x - private->x;
753 child_private->y -= y - private->y;
755 tmp_list = tmp_list->next;
759 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
763 private->drawable.width = width;
764 private->drawable.height = height;
770 gdk_window_reparent (GdkWindow *window,
771 GdkWindow *new_parent,
775 GdkWindowPrivate *window_private;
776 GdkWindowPrivate *parent_private;
777 GdkWindowPrivate *old_parent_private;
779 g_return_if_fail (window != NULL);
780 g_return_if_fail (GDK_IS_WINDOW (window));
781 g_return_if_fail (new_parent != NULL);
782 g_return_if_fail (GDK_IS_WINDOW (new_parent));
785 new_parent = gdk_parent_root;
787 window_private = (GdkWindowPrivate*) window;
788 old_parent_private = (GdkWindowPrivate*)window_private->parent;
789 parent_private = (GdkWindowPrivate*) new_parent;
791 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (new_parent))
792 XReparentWindow (GDK_DRAWABLE_XDISPLAY (window),
793 GDK_DRAWABLE_XID (window),
794 GDK_DRAWABLE_XID (new_parent),
797 window_private->parent = new_parent;
799 if (old_parent_private)
800 old_parent_private->children = g_list_remove (old_parent_private->children, window);
802 if ((old_parent_private &&
803 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
804 (!old_parent_private && parent_private->guffaw_gravity))
805 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
807 parent_private->children = g_list_prepend (parent_private->children, window);
811 gdk_window_clear (GdkWindow *window)
813 g_return_if_fail (window != NULL);
814 g_return_if_fail (GDK_IS_WINDOW (window));
816 if (!GDK_DRAWABLE_DESTROYED (window))
817 XClearWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
821 gdk_window_clear_area (GdkWindow *window,
827 g_return_if_fail (window != NULL);
828 g_return_if_fail (GDK_IS_WINDOW (window));
830 if (!GDK_DRAWABLE_DESTROYED (window))
831 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
832 x, y, width, height, False);
836 gdk_window_clear_area_e (GdkWindow *window,
842 g_return_if_fail (window != NULL);
843 g_return_if_fail (GDK_IS_WINDOW (window));
845 if (!GDK_DRAWABLE_DESTROYED (window))
846 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
847 x, y, width, height, True);
851 gdk_window_raise (GdkWindow *window)
853 g_return_if_fail (window != NULL);
854 g_return_if_fail (GDK_IS_WINDOW (window));
856 if (!GDK_DRAWABLE_DESTROYED (window))
857 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
861 gdk_window_lower (GdkWindow *window)
863 g_return_if_fail (window != NULL);
864 g_return_if_fail (GDK_IS_WINDOW (window));
866 if (!GDK_DRAWABLE_DESTROYED (window))
867 XLowerWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
871 gdk_window_set_hints (GdkWindow *window,
880 XSizeHints size_hints;
882 g_return_if_fail (window != NULL);
883 g_return_if_fail (GDK_IS_WINDOW (window));
885 if (GDK_DRAWABLE_DESTROYED (window))
888 size_hints.flags = 0;
890 if (flags & GDK_HINT_POS)
892 size_hints.flags |= PPosition;
897 if (flags & GDK_HINT_MIN_SIZE)
899 size_hints.flags |= PMinSize;
900 size_hints.min_width = min_width;
901 size_hints.min_height = min_height;
904 if (flags & GDK_HINT_MAX_SIZE)
906 size_hints.flags |= PMaxSize;
907 size_hints.max_width = max_width;
908 size_hints.max_height = max_height;
911 /* FIXME: Would it be better to delete this property of
912 * flags == 0? It would save space on the server
914 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
915 GDK_DRAWABLE_XID (window),
920 gdk_window_set_geometry_hints (GdkWindow *window,
921 GdkGeometry *geometry,
922 GdkWindowHints geom_mask)
924 XSizeHints size_hints;
926 g_return_if_fail (window != NULL);
927 g_return_if_fail (GDK_IS_WINDOW (window));
929 if (GDK_DRAWABLE_DESTROYED (window))
932 size_hints.flags = 0;
934 if (geom_mask & GDK_HINT_POS)
936 size_hints.flags |= PPosition;
937 /* We need to initialize the following obsolete fields because KWM
938 * apparently uses these fields if they are non-zero.
945 if (geom_mask & GDK_HINT_MIN_SIZE)
947 size_hints.flags |= PMinSize;
948 size_hints.min_width = geometry->min_width;
949 size_hints.min_height = geometry->min_height;
952 if (geom_mask & GDK_HINT_MAX_SIZE)
954 size_hints.flags |= PMaxSize;
955 size_hints.max_width = MAX (geometry->max_width, 1);
956 size_hints.max_height = MAX (geometry->max_height, 1);
959 if (geom_mask & GDK_HINT_BASE_SIZE)
961 size_hints.flags |= PBaseSize;
962 size_hints.base_width = geometry->base_width;
963 size_hints.base_height = geometry->base_height;
966 if (geom_mask & GDK_HINT_RESIZE_INC)
968 size_hints.flags |= PResizeInc;
969 size_hints.width_inc = geometry->width_inc;
970 size_hints.height_inc = geometry->height_inc;
973 if (geom_mask & GDK_HINT_ASPECT)
975 size_hints.flags |= PAspect;
976 if (geometry->min_aspect <= 1)
978 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
979 size_hints.min_aspect.y = 65536;
983 size_hints.min_aspect.x = 65536;
984 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
986 if (geometry->max_aspect <= 1)
988 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
989 size_hints.max_aspect.y = 65536;
993 size_hints.max_aspect.x = 65536;
994 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
998 /* FIXME: Would it be better to delete this property of
999 * geom_mask == 0? It would save space on the server
1001 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
1002 GDK_DRAWABLE_XID (window),
1007 gdk_window_set_title (GdkWindow *window,
1010 g_return_if_fail (window != NULL);
1011 g_return_if_fail (GDK_IS_WINDOW (window));
1013 if (!GDK_DRAWABLE_DESTROYED (window))
1014 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
1015 GDK_DRAWABLE_XID (window),
1016 title, title, NULL, 0, NULL, NULL, NULL);
1020 gdk_window_set_role (GdkWindow *window,
1023 g_return_if_fail (window != NULL);
1024 g_return_if_fail (GDK_IS_WINDOW (window));
1026 if (!GDK_DRAWABLE_DESTROYED (window))
1029 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1030 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1031 8, PropModeReplace, role, strlen (role));
1033 XDeleteProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1034 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1039 gdk_window_set_transient_for (GdkWindow *window,
1042 GdkWindowPrivate *private;
1043 GdkWindowPrivate *parent_private;
1045 g_return_if_fail (window != NULL);
1046 g_return_if_fail (GDK_IS_WINDOW (window));
1048 private = (GdkWindowPrivate*) window;
1049 parent_private = (GdkWindowPrivate*) parent;
1051 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (parent))
1052 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
1053 GDK_DRAWABLE_XID (window),
1054 GDK_DRAWABLE_XID (parent));
1058 gdk_window_set_background (GdkWindow *window,
1061 g_return_if_fail (window != NULL);
1062 g_return_if_fail (GDK_IS_WINDOW (window));
1064 if (!GDK_DRAWABLE_DESTROYED (window))
1065 XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
1066 GDK_DRAWABLE_XID (window), color->pixel);
1070 gdk_window_set_back_pixmap (GdkWindow *window,
1072 gboolean parent_relative)
1076 g_return_if_fail (window != NULL);
1077 g_return_if_fail (GDK_IS_WINDOW (window));
1080 xpixmap = GDK_DRAWABLE_XID (pixmap);
1084 if (parent_relative)
1085 xpixmap = ParentRelative;
1087 if (!GDK_DRAWABLE_DESTROYED (window))
1088 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
1089 GDK_DRAWABLE_XID (window), xpixmap);
1093 gdk_window_set_cursor (GdkWindow *window,
1096 GdkCursorPrivate *cursor_private;
1099 g_return_if_fail (window != NULL);
1100 g_return_if_fail (GDK_IS_WINDOW (window));
1102 cursor_private = (GdkCursorPrivate*) cursor;
1107 xcursor = cursor_private->xcursor;
1109 if (!GDK_DRAWABLE_DESTROYED (window))
1110 XDefineCursor (GDK_DRAWABLE_XDISPLAY (window),
1111 GDK_DRAWABLE_XID (window),
1116 gdk_window_get_geometry (GdkWindow *window,
1128 guint tborder_width;
1131 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1134 window = gdk_parent_root;
1136 if (!GDK_DRAWABLE_DESTROYED (window))
1138 XGetGeometry (GDK_DRAWABLE_XDISPLAY (window),
1139 GDK_DRAWABLE_XID (window),
1140 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1156 gdk_window_get_origin (GdkWindow *window,
1165 g_return_val_if_fail (window != NULL, 0);
1167 if (!GDK_DRAWABLE_DESTROYED (window))
1169 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1170 GDK_DRAWABLE_XID (window),
1188 gdk_window_get_deskrelative_origin (GdkWindow *window,
1192 gboolean return_val = FALSE;
1193 gint num_children, format_return;
1194 Window win, *child, parent, root;
1198 static Atom atom = 0;
1199 gulong number_return, bytes_after_return;
1200 guchar *data_return;
1202 g_return_val_if_fail (window != NULL, 0);
1203 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1205 if (!GDK_DRAWABLE_DESTROYED (window))
1208 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1209 win = GDK_DRAWABLE_XID (window);
1211 while (XQueryTree (GDK_DRAWABLE_XDISPLAY (window), win, &root, &parent,
1212 &child, (unsigned int *)&num_children))
1214 if ((child) && (num_children > 0))
1226 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), win, atom, 0, 0,
1227 False, XA_CARDINAL, &type_return, &format_return,
1228 &number_return, &bytes_after_return, &data_return);
1229 if (type_return == XA_CARDINAL)
1231 XFree (data_return);
1236 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1237 GDK_DRAWABLE_XID (window),
1252 gdk_window_get_root_origin (GdkWindow *window,
1256 GdkWindowPrivate *private;
1261 unsigned int nchildren;
1263 g_return_if_fail (window != NULL);
1264 g_return_if_fail (GDK_IS_WINDOW (window));
1266 private = (GdkWindowPrivate*) window;
1272 if (GDK_DRAWABLE_DESTROYED (window))
1275 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1276 private = (GdkWindowPrivate*) private->parent;
1277 if (GDK_DRAWABLE_DESTROYED (window))
1280 xparent = GDK_DRAWABLE_XID (window);
1284 if (!XQueryTree (GDK_DRAWABLE_XDISPLAY (window), xwindow,
1286 &children, &nchildren))
1292 while (xparent != root);
1294 if (xparent == root)
1296 unsigned int ww, wh, wb, wd;
1299 if (XGetGeometry (GDK_DRAWABLE_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1310 gdk_window_get_pointer (GdkWindow *window,
1313 GdkModifierType *mask)
1315 GdkWindow *return_val;
1321 unsigned int xmask = 0;
1323 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1326 window = gdk_parent_root;
1329 if (!GDK_DRAWABLE_DESTROYED (window) &&
1330 XQueryPointer (GDK_DRAWABLE_XDISPLAY (window),
1331 GDK_DRAWABLE_XID (window),
1332 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1335 return_val = gdk_window_lookup (child);
1349 gdk_window_at_pointer (gint *win_x,
1355 Window xwindow_last = 0;
1357 int rootx = -1, rooty = -1;
1361 xwindow = GDK_ROOT_WINDOW ();
1362 xdisplay = GDK_DISPLAY ();
1364 XGrabServer (xdisplay);
1367 xwindow_last = xwindow;
1368 XQueryPointer (xdisplay, xwindow,
1374 XUngrabServer (xdisplay);
1376 window = gdk_window_lookup (xwindow_last);
1379 *win_x = window ? winx : -1;
1381 *win_y = window ? winy : -1;
1387 gdk_window_get_children (GdkWindow *window)
1394 unsigned int nchildren;
1397 g_return_val_if_fail (window != NULL, NULL);
1398 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1400 if (GDK_DRAWABLE_DESTROYED (window))
1403 XQueryTree (GDK_DRAWABLE_XDISPLAY (window),
1404 GDK_DRAWABLE_XID (window),
1405 &root, &parent, &xchildren, &nchildren);
1411 for (i = 0; i < nchildren; i++)
1413 child = gdk_window_lookup (xchildren[i]);
1415 children = g_list_prepend (children, child);
1426 gdk_window_get_events (GdkWindow *window)
1428 XWindowAttributes attrs;
1429 GdkEventMask event_mask;
1432 g_return_val_if_fail (window != NULL, 0);
1433 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1435 if (GDK_DRAWABLE_DESTROYED (window))
1439 XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1440 GDK_DRAWABLE_XID (window),
1444 for (i = 0; i < gdk_nevent_masks; i++)
1446 if (attrs.your_event_mask & gdk_event_mask_table[i])
1447 event_mask |= 1 << (i + 1);
1455 gdk_window_set_events (GdkWindow *window,
1456 GdkEventMask event_mask)
1461 g_return_if_fail (window != NULL);
1462 g_return_if_fail (GDK_IS_WINDOW (window));
1464 if (!GDK_DRAWABLE_DESTROYED (window))
1466 xevent_mask = StructureNotifyMask;
1467 for (i = 0; i < gdk_nevent_masks; i++)
1469 if (event_mask & (1 << (i + 1)))
1470 xevent_mask |= gdk_event_mask_table[i];
1473 XSelectInput (GDK_DRAWABLE_XDISPLAY (window),
1474 GDK_DRAWABLE_XID (window),
1480 gdk_window_add_colormap_windows (GdkWindow *window)
1482 GdkWindow *toplevel;
1483 Window *old_windows;
1484 Window *new_windows;
1487 g_return_if_fail (window != NULL);
1488 g_return_if_fail (GDK_IS_WINDOW (window));
1490 toplevel = gdk_window_get_toplevel (window);
1491 if (GDK_DRAWABLE_DESTROYED (toplevel))
1495 if (!XGetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1496 GDK_DRAWABLE_XID (toplevel),
1497 &old_windows, &count))
1502 for (i = 0; i < count; i++)
1503 if (old_windows[i] == GDK_DRAWABLE_XID (window))
1505 XFree (old_windows);
1509 new_windows = g_new (Window, count + 1);
1511 for (i = 0; i < count; i++)
1512 new_windows[i] = old_windows[i];
1513 new_windows[count] = GDK_DRAWABLE_XID (window);
1515 XSetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1516 GDK_DRAWABLE_XID (toplevel),
1517 new_windows, count + 1);
1519 g_free (new_windows);
1521 XFree (old_windows);
1525 gdk_window_have_shape_ext (void)
1527 enum { UNKNOWN, NO, YES };
1528 static gint have_shape = UNKNOWN;
1530 if (have_shape == UNKNOWN)
1533 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1539 return (have_shape == YES);
1543 * This needs the X11 shape extension.
1544 * If not available, shaped windows will look
1545 * ugly, but programs still work. Stefan Wille
1548 gdk_window_shape_combine_mask (GdkWindow *window,
1554 g_return_if_fail (window != NULL);
1555 g_return_if_fail (GDK_IS_WINDOW (window));
1557 #ifdef HAVE_SHAPE_EXT
1558 if (GDK_DRAWABLE_DESTROYED (window))
1561 if (gdk_window_have_shape_ext ())
1565 pixmap = GDK_DRAWABLE_XID (mask);
1574 XShapeCombineMask (GDK_DRAWABLE_XDISPLAY (window),
1575 GDK_DRAWABLE_XID (window),
1581 #endif /* HAVE_SHAPE_EXT */
1585 gdk_window_set_override_redirect (GdkWindow *window,
1586 gboolean override_redirect)
1588 XSetWindowAttributes attr;
1590 g_return_if_fail (window != NULL);
1591 g_return_if_fail (GDK_IS_WINDOW (window));
1593 if (GDK_DRAWABLE_DESTROYED (window))
1595 attr.override_redirect = (override_redirect == FALSE)?False:True;
1596 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1597 GDK_DRAWABLE_XID (window),
1604 gdk_window_set_icon (GdkWindow *window,
1605 GdkWindow *icon_window,
1611 g_return_if_fail (window != NULL);
1612 g_return_if_fail (GDK_IS_WINDOW (window));
1614 if (GDK_DRAWABLE_DESTROYED (window))
1617 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1618 GDK_DRAWABLE_XID (window));
1620 wm_hints = XAllocWMHints ();
1622 if (icon_window != NULL)
1624 wm_hints->flags |= IconWindowHint;
1625 wm_hints->icon_window = GDK_DRAWABLE_XID (icon_window);
1630 wm_hints->flags |= IconPixmapHint;
1631 wm_hints->icon_pixmap = GDK_DRAWABLE_XID (pixmap);
1636 wm_hints->flags |= IconMaskHint;
1637 wm_hints->icon_mask = GDK_DRAWABLE_XID (mask);
1640 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1641 GDK_DRAWABLE_XID (window), wm_hints);
1646 gdk_window_set_icon_name (GdkWindow *window,
1649 XTextProperty property;
1652 g_return_if_fail (window != NULL);
1653 g_return_if_fail (GDK_IS_WINDOW (window));
1655 if (GDK_DRAWABLE_DESTROYED (window))
1658 res = XmbTextListToTextProperty (GDK_DRAWABLE_XDISPLAY (window),
1659 &name, 1, XStdICCTextStyle,
1663 g_warning ("Error converting icon name to text property: %d\n", res);
1667 XSetWMIconName (GDK_DRAWABLE_XDISPLAY (window),
1668 GDK_DRAWABLE_XID (window),
1672 XFree (property.value);
1676 gdk_window_set_group (GdkWindow *window,
1681 g_return_if_fail (window != NULL);
1682 g_return_if_fail (GDK_IS_WINDOW (window));
1683 g_return_if_fail (leader != NULL);
1684 g_return_if_fail (GDK_IS_WINDOW (leader));
1686 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
1689 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1690 GDK_DRAWABLE_XID (window));
1692 wm_hints = XAllocWMHints ();
1694 wm_hints->flags |= WindowGroupHint;
1695 wm_hints->window_group = GDK_DRAWABLE_XID (leader);
1697 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1698 GDK_DRAWABLE_XID (window), wm_hints);
1703 gdk_window_set_mwm_hints (GdkWindow *window,
1704 MotifWmHints *new_hints)
1706 static Atom hints_atom = None;
1707 MotifWmHints *hints;
1713 if (GDK_DRAWABLE_DESTROYED (window))
1717 hints_atom = XInternAtom (GDK_DRAWABLE_XDISPLAY (window),
1718 _XA_MOTIF_WM_HINTS, FALSE);
1720 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1721 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1722 False, AnyPropertyType, &type, &format, &nitems,
1723 &bytes_after, (guchar **)&hints);
1729 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1731 hints->flags |= MWM_HINTS_FUNCTIONS;
1732 hints->functions = new_hints->functions;
1734 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1736 hints->flags |= MWM_HINTS_DECORATIONS;
1737 hints->decorations = new_hints->decorations;
1741 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1742 hints_atom, hints_atom, 32, PropModeReplace,
1743 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1745 if (hints != new_hints)
1750 gdk_window_set_decorations (GdkWindow *window,
1751 GdkWMDecoration decorations)
1755 g_return_if_fail (window != NULL);
1756 g_return_if_fail (GDK_IS_WINDOW (window));
1758 hints.flags = MWM_HINTS_DECORATIONS;
1759 hints.decorations = decorations;
1761 gdk_window_set_mwm_hints (window, &hints);
1765 gdk_window_set_functions (GdkWindow *window,
1766 GdkWMFunction functions)
1770 g_return_if_fail (window != NULL);
1771 g_return_if_fail (GDK_IS_WINDOW (window));
1773 hints.flags = MWM_HINTS_FUNCTIONS;
1774 hints.functions = functions;
1776 gdk_window_set_mwm_hints (window, &hints);
1780 * propagate the shapes from all child windows of a GDK window to the parent
1781 * window. Shamelessly ripped from Enlightenment's code
1789 struct _gdk_span *next;
1793 gdk_add_to_span (struct _gdk_span **s,
1797 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1804 /* scan the spans for this line */
1807 /* -- -> new span */
1808 /* == -> existing span */
1809 /* ## -> spans intersect */
1810 /* if we are in the middle of spanning the span into the line */
1813 /* case: ---- ==== */
1814 if (xx < ptr1->start - 1)
1816 /* ends before next span - extend to here */
1820 /* case: ----##=== */
1821 else if (xx <= ptr1->end)
1823 /* crosses into next span - delete next span and append */
1824 ss->end = ptr1->end;
1825 ss->next = ptr1->next;
1829 /* case: ---###--- */
1832 /* overlaps next span - delete and keep checking */
1833 ss->next = ptr1->next;
1838 /* otherwise havent started spanning it in yet */
1841 /* case: ---- ==== */
1842 if (xx < ptr1->start - 1)
1844 /* insert span here in list */
1845 noo = g_malloc (sizeof (struct _gdk_span));
1859 /* case: ----##=== */
1860 else if ((x < ptr1->start) && (xx <= ptr1->end))
1862 /* expand this span to the left point of the new one */
1866 /* case: ===###=== */
1867 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1869 /* throw the span away */
1872 /* case: ---###--- */
1873 else if ((x < ptr1->start) && (xx > ptr1->end))
1880 /* case: ===##---- */
1881 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
1887 /* case: ==== ---- */
1888 /* case handled by next loop iteration - first case */
1893 /* it started in the middle but spans beyond your current list */
1899 /* it does not start inside a span or in the middle, so add it to the end */
1900 noo = g_malloc (sizeof (struct _gdk_span));
1908 noo->next = ptr2->next;
1921 gdk_add_rectangles (Display *disp,
1923 struct _gdk_span **spans,
1930 gint x1, y1, x2, y2;
1934 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
1937 /* go through all clip rects in this window's shape */
1938 for (k = 0; k < rn; k++)
1940 /* for each clip rect, add it to each line's spans */
1942 x2 = x + rl[k].x + (rl[k].width - 1);
1944 y2 = y + rl[k].y + (rl[k].height - 1);
1953 for (a = y1; a <= y2; a++)
1956 gdk_add_to_span (&spans[a], x1, x2);
1964 gdk_propagate_shapes (Display *disp,
1968 Window rt, par, *list = NULL;
1969 gint i, j, num = 0, num_rects = 0;
1973 XRectangle *rects = NULL;
1974 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
1975 XWindowAttributes xatt;
1977 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
1982 spans = g_malloc (sizeof (struct _gdk_span *) * h);
1984 for (i = 0; i < h; i++)
1986 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
1989 /* go through all child windows and create/insert spans */
1990 for (i = 0; i < num; i++)
1992 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
1993 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
1994 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
1997 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
1999 /* go through the spans list and build a list of rects */
2000 rects = g_malloc (sizeof (XRectangle) * 256);
2002 for (i = 0; i < baseh; i++)
2005 /* go through the line for all spans */
2008 rects[num_rects].x = ptr1->start;
2009 rects[num_rects].y = i;
2010 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2011 rects[num_rects].height = 1;
2013 /* if there are more lines */
2015 /* while contigous rects (same start/end coords) exist */
2016 while ((contig) && (j < baseh))
2018 /* search next line for spans matching this one */
2024 /* if we have an exact span match set contig */
2025 if ((ptr2->start == ptr1->start) &&
2026 (ptr2->end == ptr1->end))
2029 /* remove the span - not needed */
2032 ptr3->next = ptr2->next;
2038 spans[j] = ptr2->next;
2044 /* gone past the span point no point looking */
2045 else if (ptr2->start < ptr1->start)
2053 /* if a contiguous span was found increase the rect h */
2056 rects[num_rects].height++;
2060 /* up the rect count */
2062 /* every 256 new rects increase the rect array */
2063 if ((num_rects % 256) == 0)
2064 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2068 /* set the rects as the shape mask */
2071 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2072 ShapeSet, YXSorted);
2077 /* free up all the spans we made */
2078 for (i = 0; i < baseh; i++)
2092 gdk_window_set_child_shapes (GdkWindow *window)
2094 g_return_if_fail (window != NULL);
2095 g_return_if_fail (GDK_IS_WINDOW (window));
2097 #ifdef HAVE_SHAPE_EXT
2098 if (!GDK_DRAWABLE_DESTROYED (window) &&
2099 gdk_window_have_shape_ext ())
2100 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2101 GDK_DRAWABLE_XID (window), FALSE);
2106 gdk_window_merge_child_shapes (GdkWindow *window)
2108 g_return_if_fail (window != NULL);
2109 g_return_if_fail (GDK_IS_WINDOW (window));
2111 #ifdef HAVE_SHAPE_EXT
2112 if (!GDK_DRAWABLE_DESTROYED (window) &&
2113 gdk_window_have_shape_ext ())
2114 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2115 GDK_DRAWABLE_XID (window), TRUE);
2119 /* Support for windows that can be guffaw-scrolled
2120 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2124 gdk_window_gravity_works (void)
2126 enum { UNKNOWN, NO, YES };
2127 static gint gravity_works = UNKNOWN;
2129 if (gravity_works == UNKNOWN)
2136 /* This particular server apparently has a bug so that the test
2137 * works but the actual code crashes it
2139 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2140 (VendorRelease (gdk_display) == 3400))
2146 attr.window_type = GDK_WINDOW_TEMP;
2147 attr.wclass = GDK_INPUT_OUTPUT;
2152 attr.event_mask = 0;
2154 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2156 attr.window_type = GDK_WINDOW_CHILD;
2157 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2159 gdk_window_set_static_win_gravity (child, TRUE);
2161 gdk_window_resize (parent, 100, 110);
2162 gdk_window_move (parent, 0, -10);
2163 gdk_window_move_resize (parent, 0, 0, 100, 100);
2165 gdk_window_resize (parent, 100, 110);
2166 gdk_window_move (parent, 0, -10);
2167 gdk_window_move_resize (parent, 0, 0, 100, 100);
2169 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2171 gdk_window_destroy (parent);
2172 gdk_window_destroy (child);
2174 gravity_works = ((y == -20) ? YES : NO);
2177 return (gravity_works == YES);
2181 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2183 XSetWindowAttributes xattributes;
2185 g_return_if_fail (window != NULL);
2187 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2188 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2189 GDK_DRAWABLE_XID (window),
2190 CWBitGravity, &xattributes);
2194 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2196 XSetWindowAttributes xattributes;
2198 g_return_if_fail (window != NULL);
2200 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2202 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2203 GDK_DRAWABLE_XID (window),
2204 CWWinGravity, &xattributes);
2207 /*************************************************************
2208 * gdk_window_set_static_gravities:
2209 * Set the bit gravity of the given window to static,
2210 * and flag it so all children get static subwindow
2213 * window: window for which to set static gravity
2214 * use_static: Whether to turn static gravity on or off.
2216 * Does the XServer support static gravity?
2217 *************************************************************/
2220 gdk_window_set_static_gravities (GdkWindow *window,
2221 gboolean use_static)
2223 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2226 g_return_val_if_fail (window != NULL, FALSE);
2227 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2229 if (!use_static == !private->guffaw_gravity)
2232 if (use_static && !gdk_window_gravity_works ())
2235 private->guffaw_gravity = use_static;
2237 if (!GDK_DRAWABLE_DESTROYED (window))
2239 gdk_window_set_static_bit_gravity (window, use_static);
2241 tmp_list = private->children;
2244 gdk_window_set_static_win_gravity (window, use_static);
2246 tmp_list = tmp_list->next;
2253 /* internal function created for and used by gdk_window_xid_at_coords */
2255 gdk_window_xid_at (Window base,
2261 gboolean excl_child)
2264 Window *list = NULL;
2265 Window child = 0, parent_win = 0, root_win = 0;
2267 unsigned int ww, wh, wb, wd, num;
2270 xdisplay = GDK_DISPLAY ();
2271 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2278 (x < (int) (wx + ww)) &&
2279 (y < (int) (wy + wh))))
2282 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2287 for (i = num - 1; ; i--)
2289 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2291 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2306 * The following fucntion by The Rasterman <raster@redhat.com>
2307 * This function returns the X Window ID in which the x y location is in
2308 * (x and y being relative to the root window), excluding any windows listed
2309 * in the GList excludes (this is a list of X Window ID's - gpointer being
2312 * This is primarily designed for internal gdk use - for DND for example
2313 * when using a shaped icon window as the drag object - you exclude the
2314 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2315 * You can get back an X Window ID as to what X Window ID is infact under
2316 * those X,Y co-ordinates.
2319 gdk_window_xid_at_coords (gint x,
2322 gboolean excl_child)
2325 GdkDrawablePrivate *private;
2327 Window *list = NULL;
2328 Window root, child = 0, parent_win = 0, root_win = 0;
2332 window = gdk_parent_root;
2333 private = (GdkDrawablePrivate*) window;
2334 xdisplay = GDK_DRAWABLE_XDISPLAY (private);
2335 root = GDK_DRAWABLE_XID (private);
2336 num = g_list_length (excludes);
2338 XGrabServer (xdisplay);
2339 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2341 XUngrabServer (xdisplay);
2349 XWindowAttributes xwa;
2351 XGetWindowAttributes (xdisplay, list [i], &xwa);
2353 if (xwa.map_state != IsViewable)
2356 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2359 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2364 if (!g_list_find (excludes, (gpointer *) child))
2367 XUngrabServer (xdisplay);
2374 XUngrabServer (xdisplay);
2380 XUngrabServer (xdisplay);