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"
37 #include "gdkregion.h"
38 #include "gdkinternals.h"
47 #include <X11/extensions/shape.h>
50 const int gdk_event_mask_table[21] =
54 PointerMotionHintMask,
71 SubstructureNotifyMask,
72 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
74 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
76 /* Forward declarations */
77 static gboolean gdk_window_gravity_works (void);
78 static void gdk_window_set_static_win_gravity (GdkWindow *window,
80 static gboolean gdk_window_have_shape_ext (void);
82 GdkDrawableClass _gdk_windowing_window_class;
85 gdk_x11_window_destroy (GdkDrawable *drawable)
87 if (!GDK_DRAWABLE_DESTROYED (drawable))
89 if (GDK_DRAWABLE_TYPE (drawable) != GDK_WINDOW_FOREIGN)
91 g_warning ("losing last reference to undestroyed window\n");
92 _gdk_window_destroy (drawable, FALSE);
95 /* We use TRUE here, to keep us from actually calling
96 * XDestroyWindow() on the window
98 _gdk_window_destroy (drawable, TRUE);
100 gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable));
103 g_free (GDK_DRAWABLE_XDATA (drawable));
107 gdk_x11_window_alloc (void)
110 GdkWindowPrivate *private;
112 static gboolean initialized = FALSE;
118 _gdk_windowing_window_class = _gdk_x11_drawable_class;
119 _gdk_windowing_window_class.destroy = gdk_x11_window_destroy;
122 window = _gdk_window_alloc ();
123 private = (GdkWindowPrivate *)window;
125 private->drawable.klass = &_gdk_window_class;
126 private->drawable.klass_data = g_new (GdkWindowXData, 1);
132 gdk_window_init (void)
134 GdkWindowPrivate *private;
135 XWindowAttributes xattributes;
138 unsigned int border_width;
142 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
143 &x, &y, &width, &height, &border_width, &depth);
144 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
146 gdk_parent_root = gdk_x11_window_alloc ();
147 private = (GdkWindowPrivate *)gdk_parent_root;
149 GDK_DRAWABLE_XDATA (gdk_parent_root)->xdisplay = gdk_display;
150 GDK_DRAWABLE_XDATA (gdk_parent_root)->xid = gdk_root_window;
152 private->drawable.window_type = GDK_WINDOW_ROOT;
153 private->drawable.width = width;
154 private->drawable.height = height;
156 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
159 static GdkAtom wm_client_leader_atom = GDK_NONE;
162 gdk_window_new (GdkWindow *parent,
163 GdkWindowAttr *attributes,
164 gint attributes_mask)
167 GdkWindowPrivate *private;
168 GdkWindowPrivate *parent_private;
174 XSetWindowAttributes xattributes;
175 long xattributes_mask;
176 XSizeHints size_hints;
178 XClassHint *class_hint;
185 g_return_val_if_fail (attributes != NULL, NULL);
188 parent = gdk_parent_root;
190 parent_private = (GdkWindowPrivate*) parent;
191 if (GDK_DRAWABLE_DESTROYED (parent))
194 xparent = GDK_DRAWABLE_XID (parent);
196 window = gdk_x11_window_alloc ();
197 private = (GdkWindowPrivate *)window;
199 GDK_DRAWABLE_XDATA (window)->xdisplay = GDK_DRAWABLE_XDISPLAY (parent);
201 private->parent = parent;
203 xattributes_mask = 0;
205 if (attributes_mask & GDK_WA_X)
210 if (attributes_mask & GDK_WA_Y)
217 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
218 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
219 private->drawable.window_type = attributes->window_type;
221 _gdk_window_init_position (window);
222 if (GDK_WINDOW_XDATA (window)->position_info.big)
223 private->guffaw_gravity = TRUE;
225 if (attributes_mask & GDK_WA_VISUAL)
226 visual = attributes->visual;
228 visual = gdk_visual_get_system ();
229 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
231 xattributes.event_mask = StructureNotifyMask;
232 for (i = 0; i < gdk_nevent_masks; i++)
234 if (attributes->event_mask & (1 << (i + 1)))
235 xattributes.event_mask |= gdk_event_mask_table[i];
238 if (xattributes.event_mask)
239 xattributes_mask |= CWEventMask;
241 if (attributes_mask & GDK_WA_NOREDIR)
243 xattributes.override_redirect =
244 (attributes->override_redirect == FALSE)?False:True;
245 xattributes_mask |= CWOverrideRedirect;
248 xattributes.override_redirect = False;
250 if (parent_private && parent_private->guffaw_gravity)
252 xattributes.win_gravity = StaticGravity;
253 xattributes_mask |= CWWinGravity;
256 if (attributes->wclass == GDK_INPUT_OUTPUT)
259 depth = visual->depth;
261 private->input_only = FALSE;
262 private->drawable.depth = depth;
264 if (attributes_mask & GDK_WA_COLORMAP)
265 private->drawable.colormap = attributes->colormap;
268 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
269 private->drawable.colormap = gdk_colormap_get_system ();
271 private->drawable.colormap = gdk_colormap_new (visual, False);
274 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
275 xattributes.background_pixel = private->bg_color.pixel;
277 private->bg_pixmap = NULL;
279 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
280 xattributes_mask |= CWBorderPixel | CWBackPixel;
282 if (private->guffaw_gravity)
283 xattributes.bit_gravity = StaticGravity;
285 xattributes.bit_gravity = NorthWestGravity;
287 xattributes_mask |= CWBitGravity;
289 switch (private->drawable.window_type)
291 case GDK_WINDOW_TOPLEVEL:
292 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
293 xattributes_mask |= CWColormap;
295 xparent = gdk_root_window;
298 case GDK_WINDOW_CHILD:
299 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
300 xattributes_mask |= CWColormap;
303 case GDK_WINDOW_DIALOG:
304 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
305 xattributes_mask |= CWColormap;
307 xparent = gdk_root_window;
310 case GDK_WINDOW_TEMP:
311 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
312 xattributes_mask |= CWColormap;
314 xparent = gdk_root_window;
316 xattributes.save_under = True;
317 xattributes.override_redirect = True;
318 xattributes.cursor = None;
319 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
321 case GDK_WINDOW_ROOT:
322 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
324 case GDK_WINDOW_PIXMAP:
325 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
333 private->input_only = TRUE;
334 private->drawable.colormap = NULL;
337 GDK_DRAWABLE_XDATA (private)->xid = XCreateWindow (GDK_DRAWABLE_XDISPLAY (parent),
339 x, y, private->drawable.width, private->drawable.height,
340 0, depth, class, xvisual,
341 xattributes_mask, &xattributes);
342 gdk_drawable_ref (window);
343 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
345 if (private->drawable.colormap)
346 gdk_colormap_ref (private->drawable.colormap);
348 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
349 (attributes->cursor) :
353 parent_private->children = g_list_prepend (parent_private->children, window);
355 switch (private->drawable.window_type)
357 case GDK_WINDOW_DIALOG:
358 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
359 GDK_DRAWABLE_XID (window),
361 case GDK_WINDOW_TOPLEVEL:
362 case GDK_WINDOW_TEMP:
363 XSetWMProtocols (GDK_DRAWABLE_XDISPLAY (window),
364 GDK_DRAWABLE_XID (window),
365 gdk_wm_window_protocols, 2);
367 case GDK_WINDOW_CHILD:
368 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
369 (private->drawable.colormap != gdk_colormap_get_system ()) &&
370 (private->drawable.colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
372 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
373 gdk_window_add_colormap_windows (window);
382 size_hints.flags = PSize;
383 size_hints.width = private->drawable.width;
384 size_hints.height = private->drawable.height;
386 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
387 wm_hints.window_group = gdk_leader_window;
388 wm_hints.input = True;
389 wm_hints.initial_state = NormalState;
391 /* FIXME: Is there any point in doing this? Do any WM's pay
392 * attention to PSize, and even if they do, is this the
395 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
396 GDK_DRAWABLE_XID (window),
399 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
400 GDK_DRAWABLE_XID (window),
403 if (!wm_client_leader_atom)
404 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
406 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window),
407 GDK_DRAWABLE_XID (window),
408 wm_client_leader_atom,
409 XA_WINDOW, 32, PropModeReplace,
410 (guchar*) &gdk_leader_window, 1);
412 if (attributes_mask & GDK_WA_TITLE)
413 title = attributes->title;
415 title = g_get_prgname ();
417 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
418 GDK_DRAWABLE_XID (window),
423 if (attributes_mask & GDK_WA_WMCLASS)
425 class_hint = XAllocClassHint ();
426 class_hint->res_name = attributes->wmclass_name;
427 class_hint->res_class = attributes->wmclass_class;
428 XSetClassHint (GDK_DRAWABLE_XDISPLAY (window),
429 GDK_DRAWABLE_XID (window),
438 gdk_window_foreign_new (guint32 anid)
441 GdkWindowPrivate *private;
442 GdkWindowPrivate *parent_private;
443 XWindowAttributes attrs;
445 Window *children = NULL;
449 gdk_error_trap_push ();
450 result = XGetWindowAttributes (gdk_display, anid, &attrs);
451 if (gdk_error_trap_pop () || !result)
454 /* FIXME: This is pretty expensive. Maybe the caller should supply
456 gdk_error_trap_push ();
457 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
458 if (gdk_error_trap_pop () || !result)
464 window = gdk_x11_window_alloc ();
465 private = (GdkWindowPrivate *)window;
467 private->parent = gdk_xid_table_lookup (parent);
469 parent_private = (GdkWindowPrivate *)private->parent;
472 parent_private->children = g_list_prepend (parent_private->children, window);
474 GDK_DRAWABLE_XDATA (window)->xid = anid;
475 GDK_DRAWABLE_XDATA (window)->xdisplay = gdk_display;
477 private->x = attrs.x;
478 private->y = attrs.y;
479 private->drawable.width = attrs.width;
480 private->drawable.height = attrs.height;
481 private->drawable.window_type = GDK_WINDOW_FOREIGN;
482 private->drawable.destroyed = FALSE;
483 private->mapped = (attrs.map_state != IsUnmapped);
485 gdk_drawable_ref (window);
486 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
492 _gdk_windowing_window_destroy (GdkWindow *window,
494 gboolean foreign_destroy)
496 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
498 if (private->extension_events != 0)
499 gdk_input_window_destroy (window);
501 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
503 if (!foreign_destroy && (private->parent != NULL))
505 /* It's somebody else's window, but in our heirarchy,
506 * so reparent it to the root window, and then send
507 * it a delete event, as if we were a WM
509 XClientMessageEvent xevent;
511 gdk_error_trap_push ();
512 gdk_window_hide (window);
513 gdk_window_reparent (window, NULL, 0, 0);
515 xevent.type = ClientMessage;
516 xevent.window = GDK_DRAWABLE_XID (window);
517 xevent.message_type = gdk_wm_protocols;
519 xevent.data.l[0] = gdk_wm_delete_window;
520 xevent.data.l[1] = CurrentTime;
522 XSendEvent (GDK_DRAWABLE_XDISPLAY (window),
523 GDK_DRAWABLE_XID (window),
524 False, 0, (XEvent *)&xevent);
526 gdk_error_trap_pop ();
529 else if (!recursing && !foreign_destroy)
530 XDestroyWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
533 /* This function is called when the XWindow is really gone.
536 gdk_window_destroy_notify (GdkWindow *window)
538 g_return_if_fail (window != NULL);
540 if (!GDK_DRAWABLE_DESTROYED (window))
542 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
543 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_DRAWABLE_XID (window));
545 _gdk_window_destroy (window, TRUE);
548 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
549 gdk_drawable_unref (window);
553 gdk_window_show (GdkWindow *window)
555 GdkWindowPrivate *private;
557 g_return_if_fail (window != NULL);
559 private = (GdkWindowPrivate*) window;
560 if (!private->drawable.destroyed)
562 private->mapped = TRUE;
563 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window),
564 GDK_DRAWABLE_XID (window));
566 if (GDK_WINDOW_XDATA (window)->position_info.mapped)
567 XMapWindow (GDK_DRAWABLE_XDISPLAY (window),
568 GDK_DRAWABLE_XID (window));
573 gdk_window_hide (GdkWindow *window)
575 GdkWindowPrivate *private;
577 g_return_if_fail (window != NULL);
579 private = (GdkWindowPrivate*) window;
580 if (!private->drawable.destroyed)
582 private->mapped = FALSE;
584 _gdk_window_clear_update_area (window);
586 XUnmapWindow (GDK_DRAWABLE_XDISPLAY (window),
587 GDK_DRAWABLE_XID (window));
592 gdk_window_withdraw (GdkWindow *window)
594 GdkWindowPrivate *private;
596 g_return_if_fail (window != NULL);
598 private = (GdkWindowPrivate*) window;
599 if (!private->drawable.destroyed)
600 XWithdrawWindow (GDK_DRAWABLE_XDISPLAY (window),
601 GDK_DRAWABLE_XID (window), 0);
605 gdk_window_move (GdkWindow *window,
609 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
611 g_return_if_fail (window != NULL);
612 g_return_if_fail (GDK_IS_WINDOW (window));
614 gdk_window_move_resize (window, x, y,
615 private->drawable.width, private->drawable.height);
619 gdk_window_resize (GdkWindow *window,
623 GdkWindowPrivate *private;
625 g_return_if_fail (window != NULL);
626 g_return_if_fail (GDK_IS_WINDOW (window));
633 private = (GdkWindowPrivate*) window;
635 if (!GDK_DRAWABLE_DESTROYED (window))
637 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
638 _gdk_window_move_resize_child (window, private->x, private->y,
642 XResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
643 GDK_DRAWABLE_XID (window),
645 private->resize_count += 1;
651 gdk_window_move_resize (GdkWindow *window,
657 GdkWindowPrivate *private;
659 g_return_if_fail (window != NULL);
660 g_return_if_fail (GDK_IS_WINDOW (window));
667 private = (GdkWindowPrivate*) window;
669 if (!GDK_DRAWABLE_DESTROYED (window))
671 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
672 _gdk_window_move_resize_child (window, x, y, width, height);
675 XMoveResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
676 GDK_DRAWABLE_XID (window),
677 x, y, width, height);
683 gdk_window_reparent (GdkWindow *window,
684 GdkWindow *new_parent,
688 GdkWindowPrivate *window_private;
689 GdkWindowPrivate *parent_private;
690 GdkWindowPrivate *old_parent_private;
692 g_return_if_fail (window != NULL);
693 g_return_if_fail (GDK_IS_WINDOW (window));
694 g_return_if_fail (new_parent != NULL);
695 g_return_if_fail (GDK_IS_WINDOW (new_parent));
698 new_parent = gdk_parent_root;
700 window_private = (GdkWindowPrivate*) window;
701 old_parent_private = (GdkWindowPrivate*)window_private->parent;
702 parent_private = (GdkWindowPrivate*) new_parent;
704 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (new_parent))
705 XReparentWindow (GDK_DRAWABLE_XDISPLAY (window),
706 GDK_DRAWABLE_XID (window),
707 GDK_DRAWABLE_XID (new_parent),
710 window_private->parent = new_parent;
712 if (old_parent_private)
713 old_parent_private->children = g_list_remove (old_parent_private->children, window);
715 if ((old_parent_private &&
716 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
717 (!old_parent_private && parent_private->guffaw_gravity))
718 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
720 parent_private->children = g_list_prepend (parent_private->children, window);
724 _gdk_windowing_window_clear_area (GdkWindow *window,
730 g_return_if_fail (window != NULL);
731 g_return_if_fail (GDK_IS_WINDOW (window));
733 if (!GDK_DRAWABLE_DESTROYED (window))
734 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
735 x, y, width, height, False);
739 _gdk_windowing_window_clear_area_e (GdkWindow *window,
745 g_return_if_fail (window != NULL);
746 g_return_if_fail (GDK_IS_WINDOW (window));
748 if (!GDK_DRAWABLE_DESTROYED (window))
749 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
750 x, y, width, height, True);
754 gdk_window_raise (GdkWindow *window)
756 g_return_if_fail (window != NULL);
757 g_return_if_fail (GDK_IS_WINDOW (window));
759 if (!GDK_DRAWABLE_DESTROYED (window))
760 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
764 gdk_window_lower (GdkWindow *window)
766 g_return_if_fail (window != NULL);
767 g_return_if_fail (GDK_IS_WINDOW (window));
769 if (!GDK_DRAWABLE_DESTROYED (window))
770 XLowerWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
774 gdk_window_set_hints (GdkWindow *window,
783 XSizeHints size_hints;
785 g_return_if_fail (window != NULL);
786 g_return_if_fail (GDK_IS_WINDOW (window));
788 if (GDK_DRAWABLE_DESTROYED (window))
791 size_hints.flags = 0;
793 if (flags & GDK_HINT_POS)
795 size_hints.flags |= PPosition;
800 if (flags & GDK_HINT_MIN_SIZE)
802 size_hints.flags |= PMinSize;
803 size_hints.min_width = min_width;
804 size_hints.min_height = min_height;
807 if (flags & GDK_HINT_MAX_SIZE)
809 size_hints.flags |= PMaxSize;
810 size_hints.max_width = max_width;
811 size_hints.max_height = max_height;
814 /* FIXME: Would it be better to delete this property of
815 * flags == 0? It would save space on the server
817 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
818 GDK_DRAWABLE_XID (window),
823 gdk_window_set_geometry_hints (GdkWindow *window,
824 GdkGeometry *geometry,
825 GdkWindowHints geom_mask)
827 XSizeHints size_hints;
829 g_return_if_fail (window != NULL);
830 g_return_if_fail (GDK_IS_WINDOW (window));
832 if (GDK_DRAWABLE_DESTROYED (window))
835 size_hints.flags = 0;
837 if (geom_mask & GDK_HINT_POS)
839 size_hints.flags |= PPosition;
840 /* We need to initialize the following obsolete fields because KWM
841 * apparently uses these fields if they are non-zero.
848 if (geom_mask & GDK_HINT_MIN_SIZE)
850 size_hints.flags |= PMinSize;
851 size_hints.min_width = geometry->min_width;
852 size_hints.min_height = geometry->min_height;
855 if (geom_mask & GDK_HINT_MAX_SIZE)
857 size_hints.flags |= PMaxSize;
858 size_hints.max_width = MAX (geometry->max_width, 1);
859 size_hints.max_height = MAX (geometry->max_height, 1);
862 if (geom_mask & GDK_HINT_BASE_SIZE)
864 size_hints.flags |= PBaseSize;
865 size_hints.base_width = geometry->base_width;
866 size_hints.base_height = geometry->base_height;
869 if (geom_mask & GDK_HINT_RESIZE_INC)
871 size_hints.flags |= PResizeInc;
872 size_hints.width_inc = geometry->width_inc;
873 size_hints.height_inc = geometry->height_inc;
876 if (geom_mask & GDK_HINT_ASPECT)
878 size_hints.flags |= PAspect;
879 if (geometry->min_aspect <= 1)
881 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
882 size_hints.min_aspect.y = 65536;
886 size_hints.min_aspect.x = 65536;
887 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
889 if (geometry->max_aspect <= 1)
891 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
892 size_hints.max_aspect.y = 65536;
896 size_hints.max_aspect.x = 65536;
897 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
901 /* FIXME: Would it be better to delete this property of
902 * geom_mask == 0? It would save space on the server
904 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
905 GDK_DRAWABLE_XID (window),
910 gdk_window_set_title (GdkWindow *window,
913 g_return_if_fail (window != NULL);
914 g_return_if_fail (GDK_IS_WINDOW (window));
916 if (!GDK_DRAWABLE_DESTROYED (window))
917 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
918 GDK_DRAWABLE_XID (window),
919 title, title, NULL, 0, NULL, NULL, NULL);
923 gdk_window_set_role (GdkWindow *window,
926 g_return_if_fail (window != NULL);
927 g_return_if_fail (GDK_IS_WINDOW (window));
929 if (!GDK_DRAWABLE_DESTROYED (window))
932 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
933 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
934 8, PropModeReplace, role, strlen (role));
936 XDeleteProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
937 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
942 gdk_window_set_transient_for (GdkWindow *window,
945 GdkWindowPrivate *private;
946 GdkWindowPrivate *parent_private;
948 g_return_if_fail (window != NULL);
949 g_return_if_fail (GDK_IS_WINDOW (window));
951 private = (GdkWindowPrivate*) window;
952 parent_private = (GdkWindowPrivate*) parent;
954 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (parent))
955 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
956 GDK_DRAWABLE_XID (window),
957 GDK_DRAWABLE_XID (parent));
961 gdk_window_set_background (GdkWindow *window,
964 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
966 g_return_if_fail (window != NULL);
967 g_return_if_fail (GDK_IS_WINDOW (window));
969 if (!GDK_DRAWABLE_DESTROYED (window))
970 XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
971 GDK_DRAWABLE_XID (window), color->pixel);
973 private->bg_color = *color;
975 if (private->bg_pixmap &&
976 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
977 private->bg_pixmap != GDK_NO_BG)
979 gdk_pixmap_unref (private->bg_pixmap);
980 private->bg_pixmap = NULL;
985 gdk_window_set_back_pixmap (GdkWindow *window,
987 gboolean parent_relative)
989 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
992 g_return_if_fail (window != NULL);
993 g_return_if_fail (GDK_IS_WINDOW (window));
994 g_return_if_fail (pixmap == NULL || !parent_relative);
996 if (private->bg_pixmap &&
997 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
998 private->bg_pixmap != GDK_NO_BG)
999 gdk_pixmap_unref (private->bg_pixmap);
1001 if (parent_relative)
1003 xpixmap = ParentRelative;
1004 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1010 gdk_pixmap_ref (pixmap);
1011 private->bg_pixmap = pixmap;
1012 xpixmap = GDK_DRAWABLE_XID (pixmap);
1017 private->bg_pixmap = GDK_NO_BG;
1021 if (!GDK_DRAWABLE_DESTROYED (window))
1022 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
1023 GDK_DRAWABLE_XID (window), xpixmap);
1027 gdk_window_set_cursor (GdkWindow *window,
1030 GdkCursorPrivate *cursor_private;
1033 g_return_if_fail (window != NULL);
1034 g_return_if_fail (GDK_IS_WINDOW (window));
1036 cursor_private = (GdkCursorPrivate*) cursor;
1041 xcursor = cursor_private->xcursor;
1043 if (!GDK_DRAWABLE_DESTROYED (window))
1044 XDefineCursor (GDK_DRAWABLE_XDISPLAY (window),
1045 GDK_DRAWABLE_XID (window),
1050 gdk_window_get_geometry (GdkWindow *window,
1062 guint tborder_width;
1065 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1068 window = gdk_parent_root;
1070 if (!GDK_DRAWABLE_DESTROYED (window))
1072 XGetGeometry (GDK_DRAWABLE_XDISPLAY (window),
1073 GDK_DRAWABLE_XID (window),
1074 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1090 gdk_window_get_origin (GdkWindow *window,
1099 g_return_val_if_fail (window != NULL, 0);
1101 if (!GDK_DRAWABLE_DESTROYED (window))
1103 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1104 GDK_DRAWABLE_XID (window),
1122 gdk_window_get_deskrelative_origin (GdkWindow *window,
1126 gboolean return_val = FALSE;
1127 gint num_children, format_return;
1128 Window win, *child, parent, root;
1132 static Atom atom = 0;
1133 gulong number_return, bytes_after_return;
1134 guchar *data_return;
1136 g_return_val_if_fail (window != NULL, 0);
1137 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1139 if (!GDK_DRAWABLE_DESTROYED (window))
1142 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1143 win = GDK_DRAWABLE_XID (window);
1145 while (XQueryTree (GDK_DRAWABLE_XDISPLAY (window), win, &root, &parent,
1146 &child, (unsigned int *)&num_children))
1148 if ((child) && (num_children > 0))
1160 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), win, atom, 0, 0,
1161 False, XA_CARDINAL, &type_return, &format_return,
1162 &number_return, &bytes_after_return, &data_return);
1163 if (type_return == XA_CARDINAL)
1165 XFree (data_return);
1170 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1171 GDK_DRAWABLE_XID (window),
1186 gdk_window_get_root_origin (GdkWindow *window,
1190 GdkWindowPrivate *private;
1195 unsigned int nchildren;
1197 g_return_if_fail (window != NULL);
1198 g_return_if_fail (GDK_IS_WINDOW (window));
1200 private = (GdkWindowPrivate*) window;
1206 if (GDK_DRAWABLE_DESTROYED (window))
1209 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1210 private = (GdkWindowPrivate*) private->parent;
1211 if (GDK_DRAWABLE_DESTROYED (window))
1214 xparent = GDK_DRAWABLE_XID (window);
1218 if (!XQueryTree (GDK_DRAWABLE_XDISPLAY (window), xwindow,
1220 &children, &nchildren))
1226 while (xparent != root);
1228 if (xparent == root)
1230 unsigned int ww, wh, wb, wd;
1233 if (XGetGeometry (GDK_DRAWABLE_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1244 gdk_window_get_pointer (GdkWindow *window,
1247 GdkModifierType *mask)
1249 GdkWindow *return_val;
1255 unsigned int xmask = 0;
1256 gint xoffset, yoffset;
1258 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1261 window = gdk_parent_root;
1263 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1266 if (!GDK_DRAWABLE_DESTROYED (window) &&
1267 XQueryPointer (GDK_DRAWABLE_XDISPLAY (window),
1268 GDK_DRAWABLE_XID (window),
1269 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1272 return_val = gdk_window_lookup (child);
1276 *x = winx + xoffset;
1278 *y = winy + yoffset;
1286 gdk_window_at_pointer (gint *win_x,
1292 Window xwindow_last = 0;
1294 int rootx = -1, rooty = -1;
1298 xwindow = GDK_ROOT_WINDOW ();
1299 xdisplay = GDK_DISPLAY ();
1301 XGrabServer (xdisplay);
1304 xwindow_last = xwindow;
1305 XQueryPointer (xdisplay, xwindow,
1311 XUngrabServer (xdisplay);
1313 window = gdk_window_lookup (xwindow_last);
1316 *win_x = window ? winx : -1;
1318 *win_y = window ? winy : -1;
1324 gdk_window_get_children (GdkWindow *window)
1331 unsigned int nchildren;
1334 g_return_val_if_fail (window != NULL, NULL);
1335 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1337 if (GDK_DRAWABLE_DESTROYED (window))
1340 XQueryTree (GDK_DRAWABLE_XDISPLAY (window),
1341 GDK_DRAWABLE_XID (window),
1342 &root, &parent, &xchildren, &nchildren);
1348 for (i = 0; i < nchildren; i++)
1350 child = gdk_window_lookup (xchildren[i]);
1352 children = g_list_prepend (children, child);
1363 gdk_window_get_events (GdkWindow *window)
1365 XWindowAttributes attrs;
1366 GdkEventMask event_mask;
1369 g_return_val_if_fail (window != NULL, 0);
1370 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1372 if (GDK_DRAWABLE_DESTROYED (window))
1376 XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1377 GDK_DRAWABLE_XID (window),
1381 for (i = 0; i < gdk_nevent_masks; i++)
1383 if (attrs.your_event_mask & gdk_event_mask_table[i])
1384 event_mask |= 1 << (i + 1);
1392 gdk_window_set_events (GdkWindow *window,
1393 GdkEventMask event_mask)
1398 g_return_if_fail (window != NULL);
1399 g_return_if_fail (GDK_IS_WINDOW (window));
1401 if (!GDK_DRAWABLE_DESTROYED (window))
1403 xevent_mask = StructureNotifyMask;
1404 for (i = 0; i < gdk_nevent_masks; i++)
1406 if (event_mask & (1 << (i + 1)))
1407 xevent_mask |= gdk_event_mask_table[i];
1410 XSelectInput (GDK_DRAWABLE_XDISPLAY (window),
1411 GDK_DRAWABLE_XID (window),
1417 gdk_window_add_colormap_windows (GdkWindow *window)
1419 GdkWindow *toplevel;
1420 Window *old_windows;
1421 Window *new_windows;
1424 g_return_if_fail (window != NULL);
1425 g_return_if_fail (GDK_IS_WINDOW (window));
1427 toplevel = gdk_window_get_toplevel (window);
1428 if (GDK_DRAWABLE_DESTROYED (toplevel))
1432 if (!XGetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1433 GDK_DRAWABLE_XID (toplevel),
1434 &old_windows, &count))
1439 for (i = 0; i < count; i++)
1440 if (old_windows[i] == GDK_DRAWABLE_XID (window))
1442 XFree (old_windows);
1446 new_windows = g_new (Window, count + 1);
1448 for (i = 0; i < count; i++)
1449 new_windows[i] = old_windows[i];
1450 new_windows[count] = GDK_DRAWABLE_XID (window);
1452 XSetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1453 GDK_DRAWABLE_XID (toplevel),
1454 new_windows, count + 1);
1456 g_free (new_windows);
1458 XFree (old_windows);
1462 gdk_window_have_shape_ext (void)
1464 enum { UNKNOWN, NO, YES };
1465 static gint have_shape = UNKNOWN;
1467 if (have_shape == UNKNOWN)
1470 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1476 return (have_shape == YES);
1480 * This needs the X11 shape extension.
1481 * If not available, shaped windows will look
1482 * ugly, but programs still work. Stefan Wille
1485 gdk_window_shape_combine_mask (GdkWindow *window,
1491 g_return_if_fail (window != NULL);
1492 g_return_if_fail (GDK_IS_WINDOW (window));
1494 #ifdef HAVE_SHAPE_EXT
1495 if (GDK_DRAWABLE_DESTROYED (window))
1498 if (gdk_window_have_shape_ext ())
1502 pixmap = GDK_DRAWABLE_XID (mask);
1511 XShapeCombineMask (GDK_DRAWABLE_XDISPLAY (window),
1512 GDK_DRAWABLE_XID (window),
1518 #endif /* HAVE_SHAPE_EXT */
1522 gdk_window_set_override_redirect (GdkWindow *window,
1523 gboolean override_redirect)
1525 XSetWindowAttributes attr;
1527 g_return_if_fail (window != NULL);
1528 g_return_if_fail (GDK_IS_WINDOW (window));
1530 if (GDK_DRAWABLE_DESTROYED (window))
1532 attr.override_redirect = (override_redirect == FALSE)?False:True;
1533 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1534 GDK_DRAWABLE_XID (window),
1541 gdk_window_set_icon (GdkWindow *window,
1542 GdkWindow *icon_window,
1548 g_return_if_fail (window != NULL);
1549 g_return_if_fail (GDK_IS_WINDOW (window));
1551 if (GDK_DRAWABLE_DESTROYED (window))
1554 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1555 GDK_DRAWABLE_XID (window));
1557 wm_hints = XAllocWMHints ();
1559 if (icon_window != NULL)
1561 wm_hints->flags |= IconWindowHint;
1562 wm_hints->icon_window = GDK_DRAWABLE_XID (icon_window);
1567 wm_hints->flags |= IconPixmapHint;
1568 wm_hints->icon_pixmap = GDK_DRAWABLE_XID (pixmap);
1573 wm_hints->flags |= IconMaskHint;
1574 wm_hints->icon_mask = GDK_DRAWABLE_XID (mask);
1577 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1578 GDK_DRAWABLE_XID (window), wm_hints);
1583 gdk_window_set_icon_name (GdkWindow *window,
1586 XTextProperty property;
1589 g_return_if_fail (window != NULL);
1590 g_return_if_fail (GDK_IS_WINDOW (window));
1592 if (GDK_DRAWABLE_DESTROYED (window))
1595 res = XmbTextListToTextProperty (GDK_DRAWABLE_XDISPLAY (window),
1596 &name, 1, XStdICCTextStyle,
1600 g_warning ("Error converting icon name to text property: %d\n", res);
1604 XSetWMIconName (GDK_DRAWABLE_XDISPLAY (window),
1605 GDK_DRAWABLE_XID (window),
1609 XFree (property.value);
1613 gdk_window_set_group (GdkWindow *window,
1618 g_return_if_fail (window != NULL);
1619 g_return_if_fail (GDK_IS_WINDOW (window));
1620 g_return_if_fail (leader != NULL);
1621 g_return_if_fail (GDK_IS_WINDOW (leader));
1623 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
1626 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1627 GDK_DRAWABLE_XID (window));
1629 wm_hints = XAllocWMHints ();
1631 wm_hints->flags |= WindowGroupHint;
1632 wm_hints->window_group = GDK_DRAWABLE_XID (leader);
1634 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1635 GDK_DRAWABLE_XID (window), wm_hints);
1640 gdk_window_set_mwm_hints (GdkWindow *window,
1641 MotifWmHints *new_hints)
1643 static Atom hints_atom = None;
1644 MotifWmHints *hints;
1650 if (GDK_DRAWABLE_DESTROYED (window))
1654 hints_atom = XInternAtom (GDK_DRAWABLE_XDISPLAY (window),
1655 _XA_MOTIF_WM_HINTS, FALSE);
1657 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1658 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1659 False, AnyPropertyType, &type, &format, &nitems,
1660 &bytes_after, (guchar **)&hints);
1666 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1668 hints->flags |= MWM_HINTS_FUNCTIONS;
1669 hints->functions = new_hints->functions;
1671 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1673 hints->flags |= MWM_HINTS_DECORATIONS;
1674 hints->decorations = new_hints->decorations;
1678 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1679 hints_atom, hints_atom, 32, PropModeReplace,
1680 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1682 if (hints != new_hints)
1687 gdk_window_set_decorations (GdkWindow *window,
1688 GdkWMDecoration decorations)
1692 g_return_if_fail (window != NULL);
1693 g_return_if_fail (GDK_IS_WINDOW (window));
1695 hints.flags = MWM_HINTS_DECORATIONS;
1696 hints.decorations = decorations;
1698 gdk_window_set_mwm_hints (window, &hints);
1702 gdk_window_set_functions (GdkWindow *window,
1703 GdkWMFunction functions)
1707 g_return_if_fail (window != NULL);
1708 g_return_if_fail (GDK_IS_WINDOW (window));
1710 hints.flags = MWM_HINTS_FUNCTIONS;
1711 hints.functions = functions;
1713 gdk_window_set_mwm_hints (window, &hints);
1717 * propagate the shapes from all child windows of a GDK window to the parent
1718 * window. Shamelessly ripped from Enlightenment's code
1726 struct _gdk_span *next;
1730 gdk_add_to_span (struct _gdk_span **s,
1734 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1741 /* scan the spans for this line */
1744 /* -- -> new span */
1745 /* == -> existing span */
1746 /* ## -> spans intersect */
1747 /* if we are in the middle of spanning the span into the line */
1750 /* case: ---- ==== */
1751 if (xx < ptr1->start - 1)
1753 /* ends before next span - extend to here */
1757 /* case: ----##=== */
1758 else if (xx <= ptr1->end)
1760 /* crosses into next span - delete next span and append */
1761 ss->end = ptr1->end;
1762 ss->next = ptr1->next;
1766 /* case: ---###--- */
1769 /* overlaps next span - delete and keep checking */
1770 ss->next = ptr1->next;
1775 /* otherwise havent started spanning it in yet */
1778 /* case: ---- ==== */
1779 if (xx < ptr1->start - 1)
1781 /* insert span here in list */
1782 noo = g_malloc (sizeof (struct _gdk_span));
1796 /* case: ----##=== */
1797 else if ((x < ptr1->start) && (xx <= ptr1->end))
1799 /* expand this span to the left point of the new one */
1803 /* case: ===###=== */
1804 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1806 /* throw the span away */
1809 /* case: ---###--- */
1810 else if ((x < ptr1->start) && (xx > ptr1->end))
1817 /* case: ===##---- */
1818 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
1824 /* case: ==== ---- */
1825 /* case handled by next loop iteration - first case */
1830 /* it started in the middle but spans beyond your current list */
1836 /* it does not start inside a span or in the middle, so add it to the end */
1837 noo = g_malloc (sizeof (struct _gdk_span));
1845 noo->next = ptr2->next;
1858 gdk_add_rectangles (Display *disp,
1860 struct _gdk_span **spans,
1867 gint x1, y1, x2, y2;
1871 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
1874 /* go through all clip rects in this window's shape */
1875 for (k = 0; k < rn; k++)
1877 /* for each clip rect, add it to each line's spans */
1879 x2 = x + rl[k].x + (rl[k].width - 1);
1881 y2 = y + rl[k].y + (rl[k].height - 1);
1890 for (a = y1; a <= y2; a++)
1893 gdk_add_to_span (&spans[a], x1, x2);
1901 gdk_propagate_shapes (Display *disp,
1905 Window rt, par, *list = NULL;
1906 gint i, j, num = 0, num_rects = 0;
1910 XRectangle *rects = NULL;
1911 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
1912 XWindowAttributes xatt;
1914 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
1919 spans = g_malloc (sizeof (struct _gdk_span *) * h);
1921 for (i = 0; i < h; i++)
1923 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
1926 /* go through all child windows and create/insert spans */
1927 for (i = 0; i < num; i++)
1929 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
1930 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
1931 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
1934 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
1936 /* go through the spans list and build a list of rects */
1937 rects = g_malloc (sizeof (XRectangle) * 256);
1939 for (i = 0; i < baseh; i++)
1942 /* go through the line for all spans */
1945 rects[num_rects].x = ptr1->start;
1946 rects[num_rects].y = i;
1947 rects[num_rects].width = ptr1->end - ptr1->start + 1;
1948 rects[num_rects].height = 1;
1950 /* if there are more lines */
1952 /* while contigous rects (same start/end coords) exist */
1953 while ((contig) && (j < baseh))
1955 /* search next line for spans matching this one */
1961 /* if we have an exact span match set contig */
1962 if ((ptr2->start == ptr1->start) &&
1963 (ptr2->end == ptr1->end))
1966 /* remove the span - not needed */
1969 ptr3->next = ptr2->next;
1975 spans[j] = ptr2->next;
1981 /* gone past the span point no point looking */
1982 else if (ptr2->start < ptr1->start)
1990 /* if a contiguous span was found increase the rect h */
1993 rects[num_rects].height++;
1997 /* up the rect count */
1999 /* every 256 new rects increase the rect array */
2000 if ((num_rects % 256) == 0)
2001 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2005 /* set the rects as the shape mask */
2008 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2009 ShapeSet, YXSorted);
2014 /* free up all the spans we made */
2015 for (i = 0; i < baseh; i++)
2029 gdk_window_set_child_shapes (GdkWindow *window)
2031 g_return_if_fail (window != NULL);
2032 g_return_if_fail (GDK_IS_WINDOW (window));
2034 #ifdef HAVE_SHAPE_EXT
2035 if (!GDK_DRAWABLE_DESTROYED (window) &&
2036 gdk_window_have_shape_ext ())
2037 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2038 GDK_DRAWABLE_XID (window), FALSE);
2043 gdk_window_merge_child_shapes (GdkWindow *window)
2045 g_return_if_fail (window != NULL);
2046 g_return_if_fail (GDK_IS_WINDOW (window));
2048 #ifdef HAVE_SHAPE_EXT
2049 if (!GDK_DRAWABLE_DESTROYED (window) &&
2050 gdk_window_have_shape_ext ())
2051 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2052 GDK_DRAWABLE_XID (window), TRUE);
2056 /* Support for windows that can be guffaw-scrolled
2057 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2061 gdk_window_gravity_works (void)
2063 enum { UNKNOWN, NO, YES };
2064 static gint gravity_works = UNKNOWN;
2066 if (gravity_works == UNKNOWN)
2073 /* This particular server apparently has a bug so that the test
2074 * works but the actual code crashes it
2076 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2077 (VendorRelease (gdk_display) == 3400))
2083 attr.window_type = GDK_WINDOW_TEMP;
2084 attr.wclass = GDK_INPUT_OUTPUT;
2089 attr.event_mask = 0;
2091 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2093 attr.window_type = GDK_WINDOW_CHILD;
2094 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2096 gdk_window_set_static_win_gravity (child, TRUE);
2098 gdk_window_resize (parent, 100, 110);
2099 gdk_window_move (parent, 0, -10);
2100 gdk_window_move_resize (parent, 0, 0, 100, 100);
2102 gdk_window_resize (parent, 100, 110);
2103 gdk_window_move (parent, 0, -10);
2104 gdk_window_move_resize (parent, 0, 0, 100, 100);
2106 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2108 gdk_window_destroy (parent);
2109 gdk_window_destroy (child);
2111 gravity_works = ((y == -20) ? YES : NO);
2114 return (gravity_works == YES);
2118 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2120 XSetWindowAttributes xattributes;
2121 guint xattributes_mask = 0;
2123 g_return_if_fail (window != NULL);
2125 xattributes.bit_gravity = StaticGravity;
2126 xattributes_mask |= CWBitGravity;
2127 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2128 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2129 GDK_DRAWABLE_XID (window),
2130 CWBitGravity, &xattributes);
2134 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2136 XSetWindowAttributes xattributes;
2138 g_return_if_fail (window != NULL);
2140 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2142 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2143 GDK_DRAWABLE_XID (window),
2144 CWWinGravity, &xattributes);
2147 /*************************************************************
2148 * gdk_window_set_static_gravities:
2149 * Set the bit gravity of the given window to static,
2150 * and flag it so all children get static subwindow
2153 * window: window for which to set static gravity
2154 * use_static: Whether to turn static gravity on or off.
2156 * Does the XServer support static gravity?
2157 *************************************************************/
2160 gdk_window_set_static_gravities (GdkWindow *window,
2161 gboolean use_static)
2163 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2166 g_return_val_if_fail (window != NULL, FALSE);
2167 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2169 if (!use_static == !private->guffaw_gravity)
2172 if (use_static && !gdk_window_gravity_works ())
2175 private->guffaw_gravity = use_static;
2177 if (!GDK_DRAWABLE_DESTROYED (window))
2179 gdk_window_set_static_bit_gravity (window, use_static);
2181 tmp_list = private->children;
2184 gdk_window_set_static_win_gravity (window, use_static);
2186 tmp_list = tmp_list->next;
2193 /* internal function created for and used by gdk_window_xid_at_coords */
2195 gdk_window_xid_at (Window base,
2201 gboolean excl_child)
2204 Window *list = NULL;
2205 Window child = 0, parent_win = 0, root_win = 0;
2207 unsigned int ww, wh, wb, wd, num;
2210 xdisplay = GDK_DISPLAY ();
2211 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2218 (x < (int) (wx + ww)) &&
2219 (y < (int) (wy + wh))))
2222 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2227 for (i = num - 1; ; i--)
2229 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2231 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2246 * The following fucntion by The Rasterman <raster@redhat.com>
2247 * This function returns the X Window ID in which the x y location is in
2248 * (x and y being relative to the root window), excluding any windows listed
2249 * in the GList excludes (this is a list of X Window ID's - gpointer being
2252 * This is primarily designed for internal gdk use - for DND for example
2253 * when using a shaped icon window as the drag object - you exclude the
2254 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2255 * You can get back an X Window ID as to what X Window ID is infact under
2256 * those X,Y co-ordinates.
2259 gdk_window_xid_at_coords (gint x,
2262 gboolean excl_child)
2265 GdkDrawablePrivate *private;
2267 Window *list = NULL;
2268 Window root, child = 0, parent_win = 0, root_win = 0;
2272 window = gdk_parent_root;
2273 private = (GdkDrawablePrivate*) window;
2274 xdisplay = GDK_DRAWABLE_XDISPLAY (private);
2275 root = GDK_DRAWABLE_XID (private);
2276 num = g_list_length (excludes);
2278 XGrabServer (xdisplay);
2279 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2281 XUngrabServer (xdisplay);
2289 XWindowAttributes xwa;
2291 XGetWindowAttributes (xdisplay, list [i], &xwa);
2293 if (xwa.map_state != IsViewable)
2296 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2299 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2304 if (!g_list_find (excludes, (gpointer *) child))
2307 XUngrabServer (xdisplay);
2314 XUngrabServer (xdisplay);
2320 XUngrabServer (xdisplay);