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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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-2000. 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"
40 #include "gdkwindow-x11.h"
48 #include <X11/extensions/shape.h>
51 const int gdk_event_mask_table[21] =
55 PointerMotionHintMask,
72 SubstructureNotifyMask,
73 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
75 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
77 /* Forward declarations */
78 static gboolean gdk_window_gravity_works (void);
79 static void gdk_window_set_static_win_gravity (GdkWindow *window,
81 static gboolean gdk_window_have_shape_ext (void);
82 static gboolean gdk_window_icon_name_set (GdkWindow *window);
84 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
85 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
87 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
90 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
91 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
92 static void gdk_window_impl_x11_finalize (GObject *object);
94 static gpointer parent_class = NULL;
97 gdk_window_impl_x11_get_type (void)
99 static GType object_type = 0;
103 static const GTypeInfo object_info =
105 sizeof (GdkWindowImplX11Class),
106 (GBaseInitFunc) NULL,
107 (GBaseFinalizeFunc) NULL,
108 (GClassInitFunc) gdk_window_impl_x11_class_init,
109 NULL, /* class_finalize */
110 NULL, /* class_data */
111 sizeof (GdkWindowImplX11),
113 (GInstanceInitFunc) gdk_window_impl_x11_init,
116 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
125 _gdk_window_impl_get_type (void)
127 return gdk_window_impl_x11_get_type ();
131 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
138 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
140 GObjectClass *object_class = G_OBJECT_CLASS (klass);
141 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
143 parent_class = g_type_class_peek_parent (klass);
145 object_class->finalize = gdk_window_impl_x11_finalize;
147 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
148 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
149 drawable_class->get_size = gdk_window_impl_x11_get_size;
153 gdk_window_impl_x11_finalize (GObject *object)
155 GdkWindowObject *wrapper;
156 GdkDrawableImplX11 *draw_impl;
157 GdkWindowImplX11 *window_impl;
159 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
161 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
162 window_impl = GDK_WINDOW_IMPL_X11 (object);
164 wrapper = (GdkWindowObject*) draw_impl->wrapper;
166 if (!GDK_WINDOW_DESTROYED (wrapper))
168 gdk_xid_table_remove (draw_impl->xid);
171 G_OBJECT_CLASS (parent_class)->finalize (object);
175 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
177 GdkDrawableImplX11 *drawable_impl;
178 GdkWindowImplX11 *window_impl;
180 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
182 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
183 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
185 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
186 drawable_impl->colormap == NULL)
188 XWindowAttributes window_attributes;
190 XGetWindowAttributes (drawable_impl->xdisplay,
193 drawable_impl->colormap =
194 gdk_colormap_lookup (window_attributes.colormap);
197 return drawable_impl->colormap;
201 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
204 GdkWindowImplX11 *impl;
205 GdkDrawableImplX11 *draw_impl;
207 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
208 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
210 impl = GDK_WINDOW_IMPL_X11 (drawable);
211 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
213 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
215 XSetWindowColormap (draw_impl->xdisplay,
217 GDK_COLORMAP_XCOLORMAP (cmap));
219 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
221 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
226 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
230 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
233 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
235 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
239 _gdk_windowing_window_init (void)
241 GdkWindowObject *private;
242 GdkWindowImplX11 *impl;
243 GdkDrawableImplX11 *draw_impl;
244 XWindowAttributes xattributes;
247 unsigned int border_width;
251 g_assert (gdk_parent_root == NULL);
253 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
254 &x, &y, &width, &height, &border_width, &depth);
255 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
257 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
258 private = (GdkWindowObject *)gdk_parent_root;
259 impl = GDK_WINDOW_IMPL_X11 (private->impl);
260 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
262 draw_impl->xdisplay = gdk_display;
263 draw_impl->xid = gdk_root_window;
264 draw_impl->wrapper = GDK_DRAWABLE (private);
266 private->window_type = GDK_WINDOW_ROOT;
267 private->depth = depth;
269 impl->height = height;
271 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
274 static GdkAtom wm_client_leader_atom = GDK_NONE;
277 gdk_window_new (GdkWindow *parent,
278 GdkWindowAttr *attributes,
279 gint attributes_mask)
282 GdkWindowObject *private;
283 GdkWindowObject *parent_private;
284 GdkWindowImplX11 *impl;
285 GdkDrawableImplX11 *draw_impl;
291 XSetWindowAttributes xattributes;
292 long xattributes_mask;
293 XSizeHints size_hints;
295 XClassHint *class_hint;
302 g_return_val_if_fail (attributes != NULL, NULL);
305 parent = gdk_parent_root;
307 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
309 parent_private = (GdkWindowObject*) parent;
310 if (GDK_WINDOW_DESTROYED (parent))
313 xparent = GDK_WINDOW_XID (parent);
315 window = g_object_new (GDK_TYPE_WINDOW, NULL);
316 private = (GdkWindowObject *)window;
317 impl = GDK_WINDOW_IMPL_X11 (private->impl);
318 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
319 draw_impl->wrapper = GDK_DRAWABLE (window);
321 draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
323 private->parent = (GdkWindowObject *)parent;
325 xattributes_mask = 0;
327 if (attributes_mask & GDK_WA_X)
332 if (attributes_mask & GDK_WA_Y)
339 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
340 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
341 private->window_type = attributes->window_type;
343 _gdk_window_init_position (GDK_WINDOW (private));
344 if (impl->position_info.big)
345 private->guffaw_gravity = TRUE;
347 if (attributes_mask & GDK_WA_VISUAL)
348 visual = attributes->visual;
350 visual = gdk_visual_get_system ();
351 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
353 xattributes.event_mask = StructureNotifyMask;
354 for (i = 0; i < gdk_nevent_masks; i++)
356 if (attributes->event_mask & (1 << (i + 1)))
357 xattributes.event_mask |= gdk_event_mask_table[i];
360 if (xattributes.event_mask)
361 xattributes_mask |= CWEventMask;
363 if (attributes_mask & GDK_WA_NOREDIR)
365 xattributes.override_redirect =
366 (attributes->override_redirect == FALSE)?False:True;
367 xattributes_mask |= CWOverrideRedirect;
370 xattributes.override_redirect = False;
372 if (parent_private && parent_private->guffaw_gravity)
374 xattributes.win_gravity = StaticGravity;
375 xattributes_mask |= CWWinGravity;
378 if (attributes->wclass == GDK_INPUT_OUTPUT)
381 depth = visual->depth;
383 private->input_only = FALSE;
384 private->depth = depth;
386 if (attributes_mask & GDK_WA_COLORMAP)
388 draw_impl->colormap = attributes->colormap;
389 gdk_colormap_ref (attributes->colormap);
393 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
395 draw_impl->colormap =
396 gdk_colormap_get_system ();
397 gdk_colormap_ref (draw_impl->colormap);
401 draw_impl->colormap =
402 gdk_colormap_new (visual, FALSE);
406 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
407 xattributes.background_pixel = private->bg_color.pixel;
409 private->bg_pixmap = NULL;
411 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
412 xattributes_mask |= CWBorderPixel | CWBackPixel;
414 if (private->guffaw_gravity)
415 xattributes.bit_gravity = StaticGravity;
417 xattributes.bit_gravity = NorthWestGravity;
419 xattributes_mask |= CWBitGravity;
421 switch (private->window_type)
423 case GDK_WINDOW_TOPLEVEL:
424 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
425 xattributes_mask |= CWColormap;
427 xparent = gdk_root_window;
430 case GDK_WINDOW_CHILD:
431 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
432 xattributes_mask |= CWColormap;
435 case GDK_WINDOW_DIALOG:
436 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
437 xattributes_mask |= CWColormap;
439 xparent = gdk_root_window;
442 case GDK_WINDOW_TEMP:
443 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
444 xattributes_mask |= CWColormap;
446 xparent = gdk_root_window;
448 xattributes.save_under = True;
449 xattributes.override_redirect = True;
450 xattributes.cursor = None;
451 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
453 case GDK_WINDOW_ROOT:
454 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
463 private->input_only = TRUE;
464 draw_impl->colormap = NULL;
467 draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
469 impl->position_info.x, impl->position_info.y,
470 impl->position_info.width, impl->position_info.height,
471 0, depth, class, xvisual,
472 xattributes_mask, &xattributes);
474 gdk_drawable_ref (window);
475 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
477 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
478 (attributes->cursor) :
482 parent_private->children = g_list_prepend (parent_private->children, window);
484 switch (GDK_WINDOW_TYPE (private))
486 case GDK_WINDOW_DIALOG:
487 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
488 GDK_WINDOW_XID (window),
490 case GDK_WINDOW_TOPLEVEL:
491 case GDK_WINDOW_TEMP:
492 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
493 GDK_WINDOW_XID (window),
494 gdk_wm_window_protocols, 3);
496 case GDK_WINDOW_CHILD:
497 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
498 (draw_impl->colormap != gdk_colormap_get_system ()) &&
499 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
501 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
502 gdk_window_add_colormap_windows (window);
511 size_hints.flags = PSize;
512 size_hints.width = impl->width;
513 size_hints.height = impl->height;
515 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
516 wm_hints.window_group = gdk_leader_window;
517 wm_hints.input = True;
518 wm_hints.initial_state = NormalState;
520 /* FIXME: Is there any point in doing this? Do any WM's pay
521 * attention to PSize, and even if they do, is this the
524 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
525 GDK_WINDOW_XID (window),
528 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
529 GDK_WINDOW_XID (window),
532 if (!wm_client_leader_atom)
533 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
535 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
536 GDK_WINDOW_XID (window),
537 wm_client_leader_atom,
538 XA_WINDOW, 32, PropModeReplace,
539 (guchar*) &gdk_leader_window, 1);
541 if (attributes_mask & GDK_WA_TITLE)
542 title = attributes->title;
544 title = g_get_prgname ();
546 gdk_window_set_title (window, title);
548 if (attributes_mask & GDK_WA_WMCLASS)
550 class_hint = XAllocClassHint ();
551 class_hint->res_name = attributes->wmclass_name;
552 class_hint->res_class = attributes->wmclass_class;
553 XSetClassHint (GDK_WINDOW_XDISPLAY (window),
554 GDK_WINDOW_XID (window),
563 gdk_window_foreign_new (GdkNativeWindow anid)
566 GdkWindowObject *private;
567 GdkWindowObject *parent_private;
568 GdkWindowImplX11 *impl;
569 GdkDrawableImplX11 *draw_impl;
570 XWindowAttributes attrs;
572 Window *children = NULL;
576 gdk_error_trap_push ();
577 result = XGetWindowAttributes (gdk_display, anid, &attrs);
578 if (gdk_error_trap_pop () || !result)
581 /* FIXME: This is pretty expensive. Maybe the caller should supply
583 gdk_error_trap_push ();
584 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
585 if (gdk_error_trap_pop () || !result)
591 window = g_object_new (GDK_TYPE_WINDOW, NULL);
592 private = (GdkWindowObject *)window;
593 impl = GDK_WINDOW_IMPL_X11 (private->impl);
594 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
595 draw_impl->wrapper = GDK_DRAWABLE (window);
597 private->parent = gdk_xid_table_lookup (parent);
599 parent_private = (GdkWindowObject *)private->parent;
602 parent_private->children = g_list_prepend (parent_private->children, window);
604 draw_impl->xid = anid;
605 draw_impl->xdisplay = gdk_display;
607 private->x = attrs.x;
608 private->y = attrs.y;
609 impl->width = attrs.width;
610 impl->height = attrs.height;
611 private->window_type = GDK_WINDOW_FOREIGN;
612 private->destroyed = FALSE;
613 private->mapped = (attrs.map_state != IsUnmapped);
614 private->depth = attrs.depth;
616 gdk_drawable_ref (window);
617 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
623 _gdk_windowing_window_destroy (GdkWindow *window,
625 gboolean foreign_destroy)
627 GdkWindowObject *private = (GdkWindowObject *)window;
629 g_return_if_fail (GDK_IS_WINDOW (window));
631 _gdk_selection_window_destroyed (window);
633 if (private->extension_events != 0)
634 gdk_input_window_destroy (window);
636 if (private->window_type == GDK_WINDOW_FOREIGN)
638 if (!foreign_destroy && (private->parent != NULL))
640 /* It's somebody else's window, but in our heirarchy,
641 * so reparent it to the root window, and then send
642 * it a delete event, as if we were a WM
644 XClientMessageEvent xevent;
646 gdk_error_trap_push ();
647 gdk_window_hide (window);
648 gdk_window_reparent (window, NULL, 0, 0);
650 xevent.type = ClientMessage;
651 xevent.window = GDK_WINDOW_XID (window);
652 xevent.message_type = gdk_wm_protocols;
654 xevent.data.l[0] = gdk_wm_delete_window;
655 xevent.data.l[1] = CurrentTime;
657 XSendEvent (GDK_WINDOW_XDISPLAY (window),
658 GDK_WINDOW_XID (window),
659 False, 0, (XEvent *)&xevent);
661 gdk_error_trap_pop ();
664 else if (!recursing && !foreign_destroy)
665 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
668 /* This function is called when the XWindow is really gone.
671 gdk_window_destroy_notify (GdkWindow *window)
673 g_return_if_fail (window != NULL);
675 if (!GDK_WINDOW_DESTROYED (window))
677 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
678 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
680 _gdk_window_destroy (window, TRUE);
683 gdk_xid_table_remove (GDK_WINDOW_XID (window));
684 gdk_drawable_unref (window);
688 gdk_window_show (GdkWindow *window)
690 GdkWindowObject *private;
692 g_return_if_fail (GDK_IS_WINDOW (window));
694 private = (GdkWindowObject*) window;
695 if (!private->destroyed)
697 private->mapped = TRUE;
698 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
699 GDK_WINDOW_XID (window));
701 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
702 XMapWindow (GDK_WINDOW_XDISPLAY (window),
703 GDK_WINDOW_XID (window));
708 gdk_window_hide (GdkWindow *window)
710 GdkWindowObject *private;
712 g_return_if_fail (window != NULL);
714 private = (GdkWindowObject*) window;
715 if (!private->destroyed)
717 private->mapped = FALSE;
719 _gdk_window_clear_update_area (window);
721 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
722 GDK_WINDOW_XID (window));
727 gdk_window_withdraw (GdkWindow *window)
729 GdkWindowObject *private;
731 g_return_if_fail (window != NULL);
733 private = (GdkWindowObject*) window;
734 if (!private->destroyed)
735 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
736 GDK_WINDOW_XID (window), 0);
740 gdk_window_move (GdkWindow *window,
744 GdkWindowObject *private = (GdkWindowObject *)window;
745 GdkWindowImplX11 *impl;
747 g_return_if_fail (window != NULL);
748 g_return_if_fail (GDK_IS_WINDOW (window));
750 impl = GDK_WINDOW_IMPL_X11 (private->impl);
752 if (!GDK_WINDOW_DESTROYED (window))
754 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
755 _gdk_window_move_resize_child (window, x, y,
756 impl->width, impl->height);
759 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
760 GDK_WINDOW_XID (window),
767 gdk_window_resize (GdkWindow *window,
771 GdkWindowObject *private;
773 g_return_if_fail (window != NULL);
774 g_return_if_fail (GDK_IS_WINDOW (window));
781 private = (GdkWindowObject*) window;
783 if (!GDK_WINDOW_DESTROYED (window))
785 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
786 _gdk_window_move_resize_child (window, private->x, private->y,
790 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
791 GDK_WINDOW_XID (window),
793 private->resize_count += 1;
799 gdk_window_move_resize (GdkWindow *window,
805 GdkWindowObject *private;
807 g_return_if_fail (window != NULL);
808 g_return_if_fail (GDK_IS_WINDOW (window));
815 private = (GdkWindowObject*) window;
817 if (!GDK_WINDOW_DESTROYED (window))
819 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
820 _gdk_window_move_resize_child (window, x, y, width, height);
823 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
824 GDK_WINDOW_XID (window),
825 x, y, width, height);
826 private->resize_count += 1;
832 gdk_window_reparent (GdkWindow *window,
833 GdkWindow *new_parent,
837 GdkWindowObject *window_private;
838 GdkWindowObject *parent_private;
839 GdkWindowObject *old_parent_private;
841 g_return_if_fail (window != NULL);
842 g_return_if_fail (GDK_IS_WINDOW (window));
843 g_return_if_fail (new_parent != NULL);
844 g_return_if_fail (GDK_IS_WINDOW (new_parent));
847 new_parent = gdk_parent_root;
849 window_private = (GdkWindowObject*) window;
850 old_parent_private = (GdkWindowObject*)window_private->parent;
851 parent_private = (GdkWindowObject*) new_parent;
853 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
854 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
855 GDK_WINDOW_XID (window),
856 GDK_WINDOW_XID (new_parent),
859 window_private->parent = (GdkWindowObject *)new_parent;
861 if (old_parent_private)
862 old_parent_private->children = g_list_remove (old_parent_private->children, window);
864 if ((old_parent_private &&
865 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
866 (!old_parent_private && parent_private->guffaw_gravity))
867 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
869 parent_private->children = g_list_prepend (parent_private->children, window);
873 _gdk_windowing_window_clear_area (GdkWindow *window,
879 g_return_if_fail (window != NULL);
880 g_return_if_fail (GDK_IS_WINDOW (window));
882 if (!GDK_WINDOW_DESTROYED (window))
883 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
884 x, y, width, height, False);
888 _gdk_windowing_window_clear_area_e (GdkWindow *window,
894 g_return_if_fail (window != NULL);
895 g_return_if_fail (GDK_IS_WINDOW (window));
897 if (!GDK_WINDOW_DESTROYED (window))
898 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
899 x, y, width, height, True);
903 gdk_window_raise (GdkWindow *window)
905 g_return_if_fail (window != NULL);
906 g_return_if_fail (GDK_IS_WINDOW (window));
908 if (!GDK_WINDOW_DESTROYED (window))
909 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
913 gdk_window_lower (GdkWindow *window)
915 g_return_if_fail (window != NULL);
916 g_return_if_fail (GDK_IS_WINDOW (window));
918 if (!GDK_WINDOW_DESTROYED (window))
919 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
923 gdk_window_set_hints (GdkWindow *window,
932 XSizeHints size_hints;
934 g_return_if_fail (window != NULL);
935 g_return_if_fail (GDK_IS_WINDOW (window));
937 if (GDK_WINDOW_DESTROYED (window))
940 size_hints.flags = 0;
942 if (flags & GDK_HINT_POS)
944 size_hints.flags |= PPosition;
949 if (flags & GDK_HINT_MIN_SIZE)
951 size_hints.flags |= PMinSize;
952 size_hints.min_width = min_width;
953 size_hints.min_height = min_height;
956 if (flags & GDK_HINT_MAX_SIZE)
958 size_hints.flags |= PMaxSize;
959 size_hints.max_width = max_width;
960 size_hints.max_height = max_height;
963 /* FIXME: Would it be better to delete this property of
964 * flags == 0? It would save space on the server
966 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
967 GDK_WINDOW_XID (window),
972 gdk_window_set_geometry_hints (GdkWindow *window,
973 GdkGeometry *geometry,
974 GdkWindowHints geom_mask)
976 XSizeHints size_hints;
978 g_return_if_fail (window != NULL);
979 g_return_if_fail (GDK_IS_WINDOW (window));
981 if (GDK_WINDOW_DESTROYED (window))
984 size_hints.flags = 0;
986 if (geom_mask & GDK_HINT_POS)
988 size_hints.flags |= PPosition;
989 /* We need to initialize the following obsolete fields because KWM
990 * apparently uses these fields if they are non-zero.
997 if (geom_mask & GDK_HINT_MIN_SIZE)
999 size_hints.flags |= PMinSize;
1000 size_hints.min_width = geometry->min_width;
1001 size_hints.min_height = geometry->min_height;
1004 if (geom_mask & GDK_HINT_MAX_SIZE)
1006 size_hints.flags |= PMaxSize;
1007 size_hints.max_width = MAX (geometry->max_width, 1);
1008 size_hints.max_height = MAX (geometry->max_height, 1);
1011 if (geom_mask & GDK_HINT_BASE_SIZE)
1013 size_hints.flags |= PBaseSize;
1014 size_hints.base_width = geometry->base_width;
1015 size_hints.base_height = geometry->base_height;
1018 if (geom_mask & GDK_HINT_RESIZE_INC)
1020 size_hints.flags |= PResizeInc;
1021 size_hints.width_inc = geometry->width_inc;
1022 size_hints.height_inc = geometry->height_inc;
1025 if (geom_mask & GDK_HINT_ASPECT)
1027 size_hints.flags |= PAspect;
1028 if (geometry->min_aspect <= 1)
1030 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1031 size_hints.min_aspect.y = 65536;
1035 size_hints.min_aspect.x = 65536;
1036 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1038 if (geometry->max_aspect <= 1)
1040 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1041 size_hints.max_aspect.y = 65536;
1045 size_hints.max_aspect.x = 65536;
1046 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1050 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1052 size_hints.flags |= PWinGravity;
1053 size_hints.width_inc = geometry->win_gravity;
1056 /* FIXME: Would it be better to delete this property of
1057 * geom_mask == 0? It would save space on the server
1059 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1060 GDK_WINDOW_XID (window),
1065 utf8_is_latin1 (const gchar *str)
1067 const char *p = str;
1071 gunichar ch = g_utf8_get_char (p);
1076 p = g_utf8_next_char (p);
1082 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1083 * convertable to STRING, otherwise, set it as compound text
1086 set_text_property (GdkWindow *window,
1088 const gchar *utf8_str)
1090 guchar *prop_text = NULL;
1095 if (utf8_is_latin1 (utf8_str))
1097 prop_type = GDK_TARGET_STRING;
1098 prop_text = gdk_utf8_to_string_target (utf8_str);
1099 prop_length = strlen (prop_text);
1104 gdk_utf8_to_compound_text (utf8_str, &prop_type, &prop_format,
1105 &prop_text, &prop_length);
1110 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1111 GDK_WINDOW_XID (window),
1113 prop_type, prop_format,
1114 PropModeReplace, prop_text,
1122 gdk_window_set_title (GdkWindow *window,
1125 g_return_if_fail (window != NULL);
1126 g_return_if_fail (GDK_IS_WINDOW (window));
1128 if (GDK_WINDOW_DESTROYED (window))
1131 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1132 GDK_WINDOW_XID (window),
1133 gdk_atom_intern ("_NET_WM_NAME", FALSE),
1134 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1135 PropModeReplace, title,
1138 set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
1139 if (!gdk_window_icon_name_set (window))
1140 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
1144 gdk_window_set_role (GdkWindow *window,
1147 g_return_if_fail (window != NULL);
1148 g_return_if_fail (GDK_IS_WINDOW (window));
1150 if (!GDK_WINDOW_DESTROYED (window))
1153 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1154 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1155 8, PropModeReplace, role, strlen (role));
1157 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1158 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1163 gdk_window_set_transient_for (GdkWindow *window,
1166 GdkWindowObject *private;
1167 GdkWindowObject *parent_private;
1169 g_return_if_fail (window != NULL);
1170 g_return_if_fail (GDK_IS_WINDOW (window));
1172 private = (GdkWindowObject*) window;
1173 parent_private = (GdkWindowObject*) parent;
1175 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1176 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1177 GDK_WINDOW_XID (window),
1178 GDK_WINDOW_XID (parent));
1182 gdk_window_set_background (GdkWindow *window,
1185 GdkWindowObject *private = (GdkWindowObject *)window;
1187 g_return_if_fail (window != NULL);
1188 g_return_if_fail (GDK_IS_WINDOW (window));
1190 if (!GDK_WINDOW_DESTROYED (window))
1191 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1192 GDK_WINDOW_XID (window), color->pixel);
1194 private->bg_color = *color;
1196 if (private->bg_pixmap &&
1197 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1198 private->bg_pixmap != GDK_NO_BG)
1200 gdk_pixmap_unref (private->bg_pixmap);
1201 private->bg_pixmap = NULL;
1206 gdk_window_set_back_pixmap (GdkWindow *window,
1208 gboolean parent_relative)
1210 GdkWindowObject *private = (GdkWindowObject *)window;
1213 g_return_if_fail (window != NULL);
1214 g_return_if_fail (GDK_IS_WINDOW (window));
1215 g_return_if_fail (pixmap == NULL || !parent_relative);
1217 if (private->bg_pixmap &&
1218 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1219 private->bg_pixmap != GDK_NO_BG)
1220 gdk_pixmap_unref (private->bg_pixmap);
1222 if (parent_relative)
1224 xpixmap = ParentRelative;
1225 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1231 gdk_pixmap_ref (pixmap);
1232 private->bg_pixmap = pixmap;
1233 xpixmap = GDK_PIXMAP_XID (pixmap);
1238 private->bg_pixmap = GDK_NO_BG;
1242 if (!GDK_WINDOW_DESTROYED (window))
1243 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1244 GDK_WINDOW_XID (window), xpixmap);
1248 gdk_window_set_cursor (GdkWindow *window,
1251 GdkCursorPrivate *cursor_private;
1254 g_return_if_fail (window != NULL);
1255 g_return_if_fail (GDK_IS_WINDOW (window));
1257 cursor_private = (GdkCursorPrivate*) cursor;
1262 xcursor = cursor_private->xcursor;
1264 if (!GDK_WINDOW_DESTROYED (window))
1265 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1266 GDK_WINDOW_XID (window),
1271 gdk_window_get_geometry (GdkWindow *window,
1283 guint tborder_width;
1286 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1289 window = gdk_parent_root;
1291 if (!GDK_WINDOW_DESTROYED (window))
1293 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1294 GDK_WINDOW_XID (window),
1295 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1311 gdk_window_get_origin (GdkWindow *window,
1320 g_return_val_if_fail (window != NULL, 0);
1322 if (!GDK_WINDOW_DESTROYED (window))
1324 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1325 GDK_WINDOW_XID (window),
1343 gdk_window_get_deskrelative_origin (GdkWindow *window,
1347 gboolean return_val = FALSE;
1348 gint num_children, format_return;
1349 Window win, *child, parent, root;
1353 static Atom atom = 0;
1354 gulong number_return, bytes_after_return;
1355 guchar *data_return;
1357 g_return_val_if_fail (window != NULL, 0);
1358 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1360 if (!GDK_WINDOW_DESTROYED (window))
1363 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1364 win = GDK_WINDOW_XID (window);
1366 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1367 &child, (unsigned int *)&num_children))
1369 if ((child) && (num_children > 0))
1381 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1382 False, XA_CARDINAL, &type_return, &format_return,
1383 &number_return, &bytes_after_return, &data_return);
1384 if (type_return == XA_CARDINAL)
1386 XFree (data_return);
1391 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1392 GDK_WINDOW_XID (window),
1407 gdk_window_get_root_origin (GdkWindow *window,
1411 GdkWindowObject *private;
1416 unsigned int nchildren;
1418 g_return_if_fail (window != NULL);
1419 g_return_if_fail (GDK_IS_WINDOW (window));
1421 private = (GdkWindowObject*) window;
1427 if (GDK_WINDOW_DESTROYED (window))
1430 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1431 private = (GdkWindowObject*) private->parent;
1432 if (GDK_WINDOW_DESTROYED (window))
1435 xparent = GDK_WINDOW_XID (window);
1439 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1441 &children, &nchildren))
1447 while (xparent != root);
1449 if (xparent == root)
1451 unsigned int ww, wh, wb, wd;
1454 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1465 gdk_window_get_pointer (GdkWindow *window,
1468 GdkModifierType *mask)
1470 GdkWindow *return_val;
1476 unsigned int xmask = 0;
1477 gint xoffset, yoffset;
1479 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1482 window = gdk_parent_root;
1484 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1487 if (!GDK_WINDOW_DESTROYED (window) &&
1488 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1489 GDK_WINDOW_XID (window),
1490 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1493 return_val = gdk_window_lookup (child);
1497 *x = winx + xoffset;
1499 *y = winy + yoffset;
1507 gdk_window_at_pointer (gint *win_x,
1513 Window xwindow_last = 0;
1515 int rootx = -1, rooty = -1;
1519 xwindow = GDK_ROOT_WINDOW ();
1520 xdisplay = GDK_DISPLAY ();
1522 XGrabServer (xdisplay);
1525 xwindow_last = xwindow;
1526 XQueryPointer (xdisplay, xwindow,
1532 XUngrabServer (xdisplay);
1534 window = gdk_window_lookup (xwindow_last);
1537 *win_x = window ? winx : -1;
1539 *win_y = window ? winy : -1;
1545 gdk_window_get_events (GdkWindow *window)
1547 XWindowAttributes attrs;
1548 GdkEventMask event_mask;
1551 g_return_val_if_fail (window != NULL, 0);
1552 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1554 if (GDK_WINDOW_DESTROYED (window))
1558 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1559 GDK_WINDOW_XID (window),
1563 for (i = 0; i < gdk_nevent_masks; i++)
1565 if (attrs.your_event_mask & gdk_event_mask_table[i])
1566 event_mask |= 1 << (i + 1);
1574 gdk_window_set_events (GdkWindow *window,
1575 GdkEventMask event_mask)
1580 g_return_if_fail (window != NULL);
1581 g_return_if_fail (GDK_IS_WINDOW (window));
1583 if (!GDK_WINDOW_DESTROYED (window))
1585 xevent_mask = StructureNotifyMask;
1586 for (i = 0; i < gdk_nevent_masks; i++)
1588 if (event_mask & (1 << (i + 1)))
1589 xevent_mask |= gdk_event_mask_table[i];
1592 XSelectInput (GDK_WINDOW_XDISPLAY (window),
1593 GDK_WINDOW_XID (window),
1599 gdk_window_add_colormap_windows (GdkWindow *window)
1601 GdkWindow *toplevel;
1602 Window *old_windows;
1603 Window *new_windows;
1606 g_return_if_fail (window != NULL);
1607 g_return_if_fail (GDK_IS_WINDOW (window));
1609 toplevel = gdk_window_get_toplevel (window);
1610 if (GDK_WINDOW_DESTROYED (toplevel))
1614 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1615 GDK_WINDOW_XID (toplevel),
1616 &old_windows, &count))
1621 for (i = 0; i < count; i++)
1622 if (old_windows[i] == GDK_WINDOW_XID (window))
1624 XFree (old_windows);
1628 new_windows = g_new (Window, count + 1);
1630 for (i = 0; i < count; i++)
1631 new_windows[i] = old_windows[i];
1632 new_windows[count] = GDK_WINDOW_XID (window);
1634 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1635 GDK_WINDOW_XID (toplevel),
1636 new_windows, count + 1);
1638 g_free (new_windows);
1640 XFree (old_windows);
1644 gdk_window_have_shape_ext (void)
1646 enum { UNKNOWN, NO, YES };
1647 static gint have_shape = UNKNOWN;
1649 if (have_shape == UNKNOWN)
1652 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1658 return (have_shape == YES);
1662 * This needs the X11 shape extension.
1663 * If not available, shaped windows will look
1664 * ugly, but programs still work. Stefan Wille
1667 gdk_window_shape_combine_mask (GdkWindow *window,
1673 g_return_if_fail (window != NULL);
1674 g_return_if_fail (GDK_IS_WINDOW (window));
1676 #ifdef HAVE_SHAPE_EXT
1677 if (GDK_WINDOW_DESTROYED (window))
1680 if (gdk_window_have_shape_ext ())
1684 pixmap = GDK_PIXMAP_XID (mask);
1693 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
1694 GDK_WINDOW_XID (window),
1700 #endif /* HAVE_SHAPE_EXT */
1704 gdk_window_set_override_redirect (GdkWindow *window,
1705 gboolean override_redirect)
1707 XSetWindowAttributes attr;
1709 g_return_if_fail (window != NULL);
1710 g_return_if_fail (GDK_IS_WINDOW (window));
1712 if (GDK_WINDOW_DESTROYED (window))
1714 attr.override_redirect = (override_redirect == FALSE)?False:True;
1715 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1716 GDK_WINDOW_XID (window),
1723 gdk_window_set_icon (GdkWindow *window,
1724 GdkWindow *icon_window,
1730 g_return_if_fail (window != NULL);
1731 g_return_if_fail (GDK_IS_WINDOW (window));
1733 if (GDK_WINDOW_DESTROYED (window))
1736 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1737 GDK_WINDOW_XID (window));
1739 wm_hints = XAllocWMHints ();
1741 if (icon_window != NULL)
1743 wm_hints->flags |= IconWindowHint;
1744 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
1749 wm_hints->flags |= IconPixmapHint;
1750 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
1755 wm_hints->flags |= IconMaskHint;
1756 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
1759 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1760 GDK_WINDOW_XID (window), wm_hints);
1765 gdk_window_icon_name_set (GdkWindow *window)
1767 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
1768 g_quark_from_static_string ("gdk-icon-name-set")));
1772 gdk_window_set_icon_name (GdkWindow *window,
1775 g_return_if_fail (window != NULL);
1776 g_return_if_fail (GDK_IS_WINDOW (window));
1778 if (GDK_WINDOW_DESTROYED (window))
1781 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
1782 GUINT_TO_POINTER (TRUE));
1784 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
1788 gdk_window_iconify (GdkWindow *window)
1792 g_return_if_fail (window != NULL);
1793 g_return_if_fail (GDK_IS_WINDOW (window));
1795 if (GDK_WINDOW_DESTROYED (window))
1798 display = GDK_WINDOW_XDISPLAY (window);
1799 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
1803 gdk_window_set_group (GdkWindow *window,
1808 g_return_if_fail (window != NULL);
1809 g_return_if_fail (GDK_IS_WINDOW (window));
1810 g_return_if_fail (leader != NULL);
1811 g_return_if_fail (GDK_IS_WINDOW (leader));
1813 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1816 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1817 GDK_WINDOW_XID (window));
1819 wm_hints = XAllocWMHints ();
1821 wm_hints->flags |= WindowGroupHint;
1822 wm_hints->window_group = GDK_WINDOW_XID (leader);
1824 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1825 GDK_WINDOW_XID (window), wm_hints);
1830 gdk_window_set_mwm_hints (GdkWindow *window,
1831 MotifWmHints *new_hints)
1833 static Atom hints_atom = None;
1834 MotifWmHints *hints;
1840 if (GDK_WINDOW_DESTROYED (window))
1844 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
1845 _XA_MOTIF_WM_HINTS, FALSE);
1847 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1848 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1849 False, AnyPropertyType, &type, &format, &nitems,
1850 &bytes_after, (guchar **)&hints);
1856 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1858 hints->flags |= MWM_HINTS_FUNCTIONS;
1859 hints->functions = new_hints->functions;
1861 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1863 hints->flags |= MWM_HINTS_DECORATIONS;
1864 hints->decorations = new_hints->decorations;
1868 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1869 hints_atom, hints_atom, 32, PropModeReplace,
1870 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1872 if (hints != new_hints)
1877 gdk_window_set_decorations (GdkWindow *window,
1878 GdkWMDecoration decorations)
1882 g_return_if_fail (window != NULL);
1883 g_return_if_fail (GDK_IS_WINDOW (window));
1885 hints.flags = MWM_HINTS_DECORATIONS;
1886 hints.decorations = decorations;
1888 gdk_window_set_mwm_hints (window, &hints);
1892 gdk_window_set_functions (GdkWindow *window,
1893 GdkWMFunction functions)
1897 g_return_if_fail (window != NULL);
1898 g_return_if_fail (GDK_IS_WINDOW (window));
1900 hints.flags = MWM_HINTS_FUNCTIONS;
1901 hints.functions = functions;
1903 gdk_window_set_mwm_hints (window, &hints);
1907 * propagate the shapes from all child windows of a GDK window to the parent
1908 * window. Shamelessly ripped from Enlightenment's code
1916 struct _gdk_span *next;
1920 gdk_add_to_span (struct _gdk_span **s,
1924 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1931 /* scan the spans for this line */
1934 /* -- -> new span */
1935 /* == -> existing span */
1936 /* ## -> spans intersect */
1937 /* if we are in the middle of spanning the span into the line */
1940 /* case: ---- ==== */
1941 if (xx < ptr1->start - 1)
1943 /* ends before next span - extend to here */
1947 /* case: ----##=== */
1948 else if (xx <= ptr1->end)
1950 /* crosses into next span - delete next span and append */
1951 ss->end = ptr1->end;
1952 ss->next = ptr1->next;
1956 /* case: ---###--- */
1959 /* overlaps next span - delete and keep checking */
1960 ss->next = ptr1->next;
1965 /* otherwise havent started spanning it in yet */
1968 /* case: ---- ==== */
1969 if (xx < ptr1->start - 1)
1971 /* insert span here in list */
1972 noo = g_malloc (sizeof (struct _gdk_span));
1986 /* case: ----##=== */
1987 else if ((x < ptr1->start) && (xx <= ptr1->end))
1989 /* expand this span to the left point of the new one */
1993 /* case: ===###=== */
1994 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1996 /* throw the span away */
1999 /* case: ---###--- */
2000 else if ((x < ptr1->start) && (xx > ptr1->end))
2007 /* case: ===##---- */
2008 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2014 /* case: ==== ---- */
2015 /* case handled by next loop iteration - first case */
2020 /* it started in the middle but spans beyond your current list */
2026 /* it does not start inside a span or in the middle, so add it to the end */
2027 noo = g_malloc (sizeof (struct _gdk_span));
2035 noo->next = ptr2->next;
2048 gdk_add_rectangles (Display *disp,
2050 struct _gdk_span **spans,
2057 gint x1, y1, x2, y2;
2061 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2064 /* go through all clip rects in this window's shape */
2065 for (k = 0; k < rn; k++)
2067 /* for each clip rect, add it to each line's spans */
2069 x2 = x + rl[k].x + (rl[k].width - 1);
2071 y2 = y + rl[k].y + (rl[k].height - 1);
2080 for (a = y1; a <= y2; a++)
2083 gdk_add_to_span (&spans[a], x1, x2);
2091 gdk_propagate_shapes (Display *disp,
2095 Window rt, par, *list = NULL;
2096 gint i, j, num = 0, num_rects = 0;
2100 XRectangle *rects = NULL;
2101 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2102 XWindowAttributes xatt;
2104 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2109 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2111 for (i = 0; i < h; i++)
2113 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2116 /* go through all child windows and create/insert spans */
2117 for (i = 0; i < num; i++)
2119 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2120 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2121 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2124 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2126 /* go through the spans list and build a list of rects */
2127 rects = g_malloc (sizeof (XRectangle) * 256);
2129 for (i = 0; i < baseh; i++)
2132 /* go through the line for all spans */
2135 rects[num_rects].x = ptr1->start;
2136 rects[num_rects].y = i;
2137 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2138 rects[num_rects].height = 1;
2140 /* if there are more lines */
2142 /* while contigous rects (same start/end coords) exist */
2143 while ((contig) && (j < baseh))
2145 /* search next line for spans matching this one */
2151 /* if we have an exact span match set contig */
2152 if ((ptr2->start == ptr1->start) &&
2153 (ptr2->end == ptr1->end))
2156 /* remove the span - not needed */
2159 ptr3->next = ptr2->next;
2165 spans[j] = ptr2->next;
2171 /* gone past the span point no point looking */
2172 else if (ptr2->start < ptr1->start)
2180 /* if a contiguous span was found increase the rect h */
2183 rects[num_rects].height++;
2187 /* up the rect count */
2189 /* every 256 new rects increase the rect array */
2190 if ((num_rects % 256) == 0)
2191 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2195 /* set the rects as the shape mask */
2198 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2199 ShapeSet, YXSorted);
2204 /* free up all the spans we made */
2205 for (i = 0; i < baseh; i++)
2219 gdk_window_set_child_shapes (GdkWindow *window)
2221 g_return_if_fail (window != NULL);
2222 g_return_if_fail (GDK_IS_WINDOW (window));
2224 #ifdef HAVE_SHAPE_EXT
2225 if (!GDK_WINDOW_DESTROYED (window) &&
2226 gdk_window_have_shape_ext ())
2227 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2228 GDK_WINDOW_XID (window), FALSE);
2233 gdk_window_merge_child_shapes (GdkWindow *window)
2235 g_return_if_fail (window != NULL);
2236 g_return_if_fail (GDK_IS_WINDOW (window));
2238 #ifdef HAVE_SHAPE_EXT
2239 if (!GDK_WINDOW_DESTROYED (window) &&
2240 gdk_window_have_shape_ext ())
2241 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2242 GDK_WINDOW_XID (window), TRUE);
2246 /* Support for windows that can be guffaw-scrolled
2247 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2251 gdk_window_gravity_works (void)
2253 enum { UNKNOWN, NO, YES };
2254 static gint gravity_works = UNKNOWN;
2256 if (gravity_works == UNKNOWN)
2263 /* This particular server apparently has a bug so that the test
2264 * works but the actual code crashes it
2266 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2267 (VendorRelease (gdk_display) == 3400))
2273 attr.window_type = GDK_WINDOW_TEMP;
2274 attr.wclass = GDK_INPUT_OUTPUT;
2279 attr.event_mask = 0;
2281 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2283 attr.window_type = GDK_WINDOW_CHILD;
2284 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2286 gdk_window_set_static_win_gravity (child, TRUE);
2288 gdk_window_resize (parent, 100, 110);
2289 gdk_window_move (parent, 0, -10);
2290 gdk_window_move_resize (parent, 0, 0, 100, 100);
2292 gdk_window_resize (parent, 100, 110);
2293 gdk_window_move (parent, 0, -10);
2294 gdk_window_move_resize (parent, 0, 0, 100, 100);
2296 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2298 gdk_window_destroy (parent);
2299 gdk_window_destroy (child);
2301 gravity_works = ((y == -20) ? YES : NO);
2304 return (gravity_works == YES);
2308 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2310 XSetWindowAttributes xattributes;
2311 guint xattributes_mask = 0;
2313 g_return_if_fail (window != NULL);
2315 xattributes.bit_gravity = StaticGravity;
2316 xattributes_mask |= CWBitGravity;
2317 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2318 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2319 GDK_WINDOW_XID (window),
2320 CWBitGravity, &xattributes);
2324 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2326 XSetWindowAttributes xattributes;
2328 g_return_if_fail (window != NULL);
2330 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2332 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2333 GDK_WINDOW_XID (window),
2334 CWWinGravity, &xattributes);
2337 /*************************************************************
2338 * gdk_window_set_static_gravities:
2339 * Set the bit gravity of the given window to static,
2340 * and flag it so all children get static subwindow
2343 * window: window for which to set static gravity
2344 * use_static: Whether to turn static gravity on or off.
2346 * Does the XServer support static gravity?
2347 *************************************************************/
2350 gdk_window_set_static_gravities (GdkWindow *window,
2351 gboolean use_static)
2353 GdkWindowObject *private = (GdkWindowObject *)window;
2356 g_return_val_if_fail (window != NULL, FALSE);
2357 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2359 if (!use_static == !private->guffaw_gravity)
2362 if (use_static && !gdk_window_gravity_works ())
2365 private->guffaw_gravity = use_static;
2367 if (!GDK_WINDOW_DESTROYED (window))
2369 gdk_window_set_static_bit_gravity (window, use_static);
2371 tmp_list = private->children;
2374 gdk_window_set_static_win_gravity (window, use_static);
2376 tmp_list = tmp_list->next;
2383 /* internal function created for and used by gdk_window_xid_at_coords */
2385 gdk_window_xid_at (Window base,
2391 gboolean excl_child)
2394 Window *list = NULL;
2395 Window child = 0, parent_win = 0, root_win = 0;
2397 unsigned int ww, wh, wb, wd, num;
2400 xdisplay = GDK_DISPLAY ();
2401 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2408 (x < (int) (wx + ww)) &&
2409 (y < (int) (wy + wh))))
2412 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2417 for (i = num - 1; ; i--)
2419 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2421 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2436 * The following fucntion by The Rasterman <raster@redhat.com>
2437 * This function returns the X Window ID in which the x y location is in
2438 * (x and y being relative to the root window), excluding any windows listed
2439 * in the GList excludes (this is a list of X Window ID's - gpointer being
2442 * This is primarily designed for internal gdk use - for DND for example
2443 * when using a shaped icon window as the drag object - you exclude the
2444 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2445 * You can get back an X Window ID as to what X Window ID is infact under
2446 * those X,Y co-ordinates.
2449 gdk_window_xid_at_coords (gint x,
2452 gboolean excl_child)
2456 Window *list = NULL;
2457 Window root, child = 0, parent_win = 0, root_win = 0;
2461 window = gdk_parent_root;
2462 xdisplay = GDK_WINDOW_XDISPLAY (window);
2463 root = GDK_WINDOW_XID (window);
2464 num = g_list_length (excludes);
2466 XGrabServer (xdisplay);
2467 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2469 XUngrabServer (xdisplay);
2477 XWindowAttributes xwa;
2479 XGetWindowAttributes (xdisplay, list [i], &xwa);
2481 if (xwa.map_state != IsViewable)
2484 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2487 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2492 if (!g_list_find (excludes, (gpointer *) child))
2495 XUngrabServer (xdisplay);
2502 XUngrabServer (xdisplay);
2508 XUngrabServer (xdisplay);