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 GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
91 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
92 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
93 static void gdk_window_impl_x11_finalize (GObject *object);
95 static gpointer parent_class = NULL;
98 gdk_window_impl_x11_get_type (void)
100 static GType object_type = 0;
104 static const GTypeInfo object_info =
106 sizeof (GdkWindowImplX11Class),
107 (GBaseInitFunc) NULL,
108 (GBaseFinalizeFunc) NULL,
109 (GClassInitFunc) gdk_window_impl_x11_class_init,
110 NULL, /* class_finalize */
111 NULL, /* class_data */
112 sizeof (GdkWindowImplX11),
114 (GInstanceInitFunc) gdk_window_impl_x11_init,
117 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
126 _gdk_window_impl_get_type (void)
128 return gdk_window_impl_x11_get_type ();
132 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
139 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
141 GObjectClass *object_class = G_OBJECT_CLASS (klass);
142 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
144 parent_class = g_type_class_peek_parent (klass);
146 object_class->finalize = gdk_window_impl_x11_finalize;
148 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
149 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
150 drawable_class->get_size = gdk_window_impl_x11_get_size;
152 /* Visible and clip regions are the same */
153 drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
154 drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
158 gdk_window_impl_x11_finalize (GObject *object)
160 GdkWindowObject *wrapper;
161 GdkDrawableImplX11 *draw_impl;
162 GdkWindowImplX11 *window_impl;
164 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
166 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
167 window_impl = GDK_WINDOW_IMPL_X11 (object);
169 wrapper = (GdkWindowObject*) draw_impl->wrapper;
171 if (!GDK_WINDOW_DESTROYED (wrapper))
173 gdk_xid_table_remove (draw_impl->xid);
176 G_OBJECT_CLASS (parent_class)->finalize (object);
180 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
182 GdkDrawableImplX11 *drawable_impl;
183 GdkWindowImplX11 *window_impl;
185 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
187 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
188 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
190 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
191 drawable_impl->colormap == NULL)
193 XWindowAttributes window_attributes;
195 XGetWindowAttributes (drawable_impl->xdisplay,
198 drawable_impl->colormap =
199 gdk_colormap_lookup (window_attributes.colormap);
202 return drawable_impl->colormap;
206 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
209 GdkWindowImplX11 *impl;
210 GdkDrawableImplX11 *draw_impl;
212 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
213 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
215 impl = GDK_WINDOW_IMPL_X11 (drawable);
216 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
218 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
220 XSetWindowColormap (draw_impl->xdisplay,
222 GDK_COLORMAP_XCOLORMAP (cmap));
224 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
226 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
231 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
235 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
238 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
240 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
244 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
246 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
247 GdkRectangle result_rect;
251 result_rect.width = impl->width;
252 result_rect.height = impl->height;
254 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
256 return gdk_region_rectangle (&result_rect);
260 _gdk_windowing_window_init (void)
262 GdkWindowObject *private;
263 GdkWindowImplX11 *impl;
264 GdkDrawableImplX11 *draw_impl;
265 XWindowAttributes xattributes;
268 unsigned int border_width;
272 g_assert (gdk_parent_root == NULL);
274 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
275 &x, &y, &width, &height, &border_width, &depth);
276 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
278 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
279 private = (GdkWindowObject *)gdk_parent_root;
280 impl = GDK_WINDOW_IMPL_X11 (private->impl);
281 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
283 draw_impl->xdisplay = gdk_display;
284 draw_impl->xid = gdk_root_window;
285 draw_impl->wrapper = GDK_DRAWABLE (private);
287 private->window_type = GDK_WINDOW_ROOT;
288 private->depth = depth;
290 impl->height = height;
292 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
295 static GdkAtom wm_client_leader_atom = GDK_NONE;
298 gdk_window_new (GdkWindow *parent,
299 GdkWindowAttr *attributes,
300 gint attributes_mask)
303 GdkWindowObject *private;
304 GdkWindowObject *parent_private;
305 GdkWindowImplX11 *impl;
306 GdkDrawableImplX11 *draw_impl;
312 XSetWindowAttributes xattributes;
313 long xattributes_mask;
314 XSizeHints size_hints;
316 XClassHint *class_hint;
323 g_return_val_if_fail (attributes != NULL, NULL);
326 parent = gdk_parent_root;
328 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
330 parent_private = (GdkWindowObject*) parent;
331 if (GDK_WINDOW_DESTROYED (parent))
334 xparent = GDK_WINDOW_XID (parent);
336 window = g_object_new (GDK_TYPE_WINDOW, NULL);
337 private = (GdkWindowObject *)window;
338 impl = GDK_WINDOW_IMPL_X11 (private->impl);
339 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
340 draw_impl->wrapper = GDK_DRAWABLE (window);
342 draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
344 private->parent = (GdkWindowObject *)parent;
346 xattributes_mask = 0;
348 if (attributes_mask & GDK_WA_X)
353 if (attributes_mask & GDK_WA_Y)
360 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
361 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
362 private->window_type = attributes->window_type;
364 _gdk_window_init_position (GDK_WINDOW (private));
365 if (impl->position_info.big)
366 private->guffaw_gravity = TRUE;
368 if (attributes_mask & GDK_WA_VISUAL)
369 visual = attributes->visual;
371 visual = gdk_visual_get_system ();
372 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
374 xattributes.event_mask = StructureNotifyMask;
375 for (i = 0; i < gdk_nevent_masks; i++)
377 if (attributes->event_mask & (1 << (i + 1)))
378 xattributes.event_mask |= gdk_event_mask_table[i];
381 if (xattributes.event_mask)
382 xattributes_mask |= CWEventMask;
384 if (attributes_mask & GDK_WA_NOREDIR)
386 xattributes.override_redirect =
387 (attributes->override_redirect == FALSE)?False:True;
388 xattributes_mask |= CWOverrideRedirect;
391 xattributes.override_redirect = False;
393 if (parent_private && parent_private->guffaw_gravity)
395 xattributes.win_gravity = StaticGravity;
396 xattributes_mask |= CWWinGravity;
399 if (attributes->wclass == GDK_INPUT_OUTPUT)
402 depth = visual->depth;
404 private->input_only = FALSE;
405 private->depth = depth;
407 if (attributes_mask & GDK_WA_COLORMAP)
409 draw_impl->colormap = attributes->colormap;
410 gdk_colormap_ref (attributes->colormap);
414 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
416 draw_impl->colormap =
417 gdk_colormap_get_system ();
418 gdk_colormap_ref (draw_impl->colormap);
422 draw_impl->colormap =
423 gdk_colormap_new (visual, FALSE);
427 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
428 xattributes.background_pixel = private->bg_color.pixel;
430 private->bg_pixmap = NULL;
432 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
433 xattributes_mask |= CWBorderPixel | CWBackPixel;
435 if (private->guffaw_gravity)
436 xattributes.bit_gravity = StaticGravity;
438 xattributes.bit_gravity = NorthWestGravity;
440 xattributes_mask |= CWBitGravity;
442 switch (private->window_type)
444 case GDK_WINDOW_TOPLEVEL:
445 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
446 xattributes_mask |= CWColormap;
448 xparent = gdk_root_window;
451 case GDK_WINDOW_CHILD:
452 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
453 xattributes_mask |= CWColormap;
456 case GDK_WINDOW_DIALOG:
457 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
458 xattributes_mask |= CWColormap;
460 xparent = gdk_root_window;
463 case GDK_WINDOW_TEMP:
464 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
465 xattributes_mask |= CWColormap;
467 xparent = gdk_root_window;
469 xattributes.save_under = True;
470 xattributes.override_redirect = True;
471 xattributes.cursor = None;
472 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
474 case GDK_WINDOW_ROOT:
475 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
484 private->input_only = TRUE;
485 draw_impl->colormap = NULL;
488 draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
490 impl->position_info.x, impl->position_info.y,
491 impl->position_info.width, impl->position_info.height,
492 0, depth, class, xvisual,
493 xattributes_mask, &xattributes);
495 gdk_drawable_ref (window);
496 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
498 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
499 (attributes->cursor) :
503 parent_private->children = g_list_prepend (parent_private->children, window);
505 switch (GDK_WINDOW_TYPE (private))
507 case GDK_WINDOW_DIALOG:
508 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
509 GDK_WINDOW_XID (window),
511 case GDK_WINDOW_TOPLEVEL:
512 case GDK_WINDOW_TEMP:
513 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
514 GDK_WINDOW_XID (window),
515 gdk_wm_window_protocols, 3);
517 case GDK_WINDOW_CHILD:
518 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
519 (draw_impl->colormap != gdk_colormap_get_system ()) &&
520 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
522 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
523 gdk_window_add_colormap_windows (window);
532 size_hints.flags = PSize;
533 size_hints.width = impl->width;
534 size_hints.height = impl->height;
536 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
537 wm_hints.window_group = gdk_leader_window;
538 wm_hints.input = True;
539 wm_hints.initial_state = NormalState;
541 /* FIXME: Is there any point in doing this? Do any WM's pay
542 * attention to PSize, and even if they do, is this the
545 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
546 GDK_WINDOW_XID (window),
549 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
550 GDK_WINDOW_XID (window),
553 if (!wm_client_leader_atom)
554 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
556 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
557 GDK_WINDOW_XID (window),
558 wm_client_leader_atom,
559 XA_WINDOW, 32, PropModeReplace,
560 (guchar*) &gdk_leader_window, 1);
562 if (attributes_mask & GDK_WA_TITLE)
563 title = attributes->title;
565 title = g_get_prgname ();
567 gdk_window_set_title (window, title);
569 if (attributes_mask & GDK_WA_WMCLASS)
571 class_hint = XAllocClassHint ();
572 class_hint->res_name = attributes->wmclass_name;
573 class_hint->res_class = attributes->wmclass_class;
574 XSetClassHint (GDK_WINDOW_XDISPLAY (window),
575 GDK_WINDOW_XID (window),
584 gdk_window_foreign_new (GdkNativeWindow anid)
587 GdkWindowObject *private;
588 GdkWindowObject *parent_private;
589 GdkWindowImplX11 *impl;
590 GdkDrawableImplX11 *draw_impl;
591 XWindowAttributes attrs;
593 Window *children = NULL;
597 gdk_error_trap_push ();
598 result = XGetWindowAttributes (gdk_display, anid, &attrs);
599 if (gdk_error_trap_pop () || !result)
602 /* FIXME: This is pretty expensive. Maybe the caller should supply
604 gdk_error_trap_push ();
605 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
606 if (gdk_error_trap_pop () || !result)
612 window = g_object_new (GDK_TYPE_WINDOW, NULL);
613 private = (GdkWindowObject *)window;
614 impl = GDK_WINDOW_IMPL_X11 (private->impl);
615 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
616 draw_impl->wrapper = GDK_DRAWABLE (window);
618 private->parent = gdk_xid_table_lookup (parent);
620 parent_private = (GdkWindowObject *)private->parent;
623 parent_private->children = g_list_prepend (parent_private->children, window);
625 draw_impl->xid = anid;
626 draw_impl->xdisplay = gdk_display;
628 private->x = attrs.x;
629 private->y = attrs.y;
630 impl->width = attrs.width;
631 impl->height = attrs.height;
632 private->window_type = GDK_WINDOW_FOREIGN;
633 private->destroyed = FALSE;
634 private->mapped = (attrs.map_state != IsUnmapped);
635 private->depth = attrs.depth;
637 gdk_drawable_ref (window);
638 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
644 _gdk_windowing_window_destroy (GdkWindow *window,
646 gboolean foreign_destroy)
648 GdkWindowObject *private = (GdkWindowObject *)window;
650 g_return_if_fail (GDK_IS_WINDOW (window));
652 _gdk_selection_window_destroyed (window);
654 if (private->extension_events != 0)
655 gdk_input_window_destroy (window);
657 if (private->window_type == GDK_WINDOW_FOREIGN)
659 if (!foreign_destroy && (private->parent != NULL))
661 /* It's somebody else's window, but in our heirarchy,
662 * so reparent it to the root window, and then send
663 * it a delete event, as if we were a WM
665 XClientMessageEvent xevent;
667 gdk_error_trap_push ();
668 gdk_window_hide (window);
669 gdk_window_reparent (window, NULL, 0, 0);
671 xevent.type = ClientMessage;
672 xevent.window = GDK_WINDOW_XID (window);
673 xevent.message_type = gdk_wm_protocols;
675 xevent.data.l[0] = gdk_wm_delete_window;
676 xevent.data.l[1] = CurrentTime;
678 XSendEvent (GDK_WINDOW_XDISPLAY (window),
679 GDK_WINDOW_XID (window),
680 False, 0, (XEvent *)&xevent);
682 gdk_error_trap_pop ();
685 else if (!recursing && !foreign_destroy)
686 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
689 /* This function is called when the XWindow is really gone.
692 gdk_window_destroy_notify (GdkWindow *window)
694 g_return_if_fail (window != NULL);
696 if (!GDK_WINDOW_DESTROYED (window))
698 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
699 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
701 _gdk_window_destroy (window, TRUE);
704 gdk_xid_table_remove (GDK_WINDOW_XID (window));
705 gdk_drawable_unref (window);
709 gdk_window_show (GdkWindow *window)
711 GdkWindowObject *private;
713 g_return_if_fail (GDK_IS_WINDOW (window));
715 private = (GdkWindowObject*) window;
716 if (!private->destroyed)
718 private->mapped = TRUE;
719 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
720 GDK_WINDOW_XID (window));
722 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
723 XMapWindow (GDK_WINDOW_XDISPLAY (window),
724 GDK_WINDOW_XID (window));
729 gdk_window_hide (GdkWindow *window)
731 GdkWindowObject *private;
733 g_return_if_fail (window != NULL);
735 private = (GdkWindowObject*) window;
736 if (!private->destroyed)
738 private->mapped = FALSE;
740 _gdk_window_clear_update_area (window);
742 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
743 GDK_WINDOW_XID (window));
748 gdk_window_withdraw (GdkWindow *window)
750 GdkWindowObject *private;
752 g_return_if_fail (window != NULL);
754 private = (GdkWindowObject*) window;
755 if (!private->destroyed)
756 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
757 GDK_WINDOW_XID (window), 0);
761 gdk_window_move (GdkWindow *window,
765 GdkWindowObject *private = (GdkWindowObject *)window;
766 GdkWindowImplX11 *impl;
768 g_return_if_fail (window != NULL);
769 g_return_if_fail (GDK_IS_WINDOW (window));
771 impl = GDK_WINDOW_IMPL_X11 (private->impl);
773 if (!GDK_WINDOW_DESTROYED (window))
775 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
776 _gdk_window_move_resize_child (window, x, y,
777 impl->width, impl->height);
780 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
781 GDK_WINDOW_XID (window),
788 gdk_window_resize (GdkWindow *window,
792 GdkWindowObject *private;
794 g_return_if_fail (window != NULL);
795 g_return_if_fail (GDK_IS_WINDOW (window));
802 private = (GdkWindowObject*) window;
804 if (!GDK_WINDOW_DESTROYED (window))
806 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
807 _gdk_window_move_resize_child (window, private->x, private->y,
811 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
812 GDK_WINDOW_XID (window),
814 private->resize_count += 1;
820 gdk_window_move_resize (GdkWindow *window,
826 GdkWindowObject *private;
828 g_return_if_fail (window != NULL);
829 g_return_if_fail (GDK_IS_WINDOW (window));
836 private = (GdkWindowObject*) window;
838 if (!GDK_WINDOW_DESTROYED (window))
840 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
841 _gdk_window_move_resize_child (window, x, y, width, height);
844 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
845 GDK_WINDOW_XID (window),
846 x, y, width, height);
847 private->resize_count += 1;
853 gdk_window_reparent (GdkWindow *window,
854 GdkWindow *new_parent,
858 GdkWindowObject *window_private;
859 GdkWindowObject *parent_private;
860 GdkWindowObject *old_parent_private;
862 g_return_if_fail (window != NULL);
863 g_return_if_fail (GDK_IS_WINDOW (window));
864 g_return_if_fail (new_parent != NULL);
865 g_return_if_fail (GDK_IS_WINDOW (new_parent));
868 new_parent = gdk_parent_root;
870 window_private = (GdkWindowObject*) window;
871 old_parent_private = (GdkWindowObject*)window_private->parent;
872 parent_private = (GdkWindowObject*) new_parent;
874 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
875 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
876 GDK_WINDOW_XID (window),
877 GDK_WINDOW_XID (new_parent),
880 window_private->parent = (GdkWindowObject *)new_parent;
882 if (old_parent_private)
883 old_parent_private->children = g_list_remove (old_parent_private->children, window);
885 if ((old_parent_private &&
886 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
887 (!old_parent_private && parent_private->guffaw_gravity))
888 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
890 parent_private->children = g_list_prepend (parent_private->children, window);
894 _gdk_windowing_window_clear_area (GdkWindow *window,
900 g_return_if_fail (window != NULL);
901 g_return_if_fail (GDK_IS_WINDOW (window));
903 if (!GDK_WINDOW_DESTROYED (window))
904 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
905 x, y, width, height, False);
909 _gdk_windowing_window_clear_area_e (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 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
920 x, y, width, height, True);
924 gdk_window_raise (GdkWindow *window)
926 g_return_if_fail (window != NULL);
927 g_return_if_fail (GDK_IS_WINDOW (window));
929 if (!GDK_WINDOW_DESTROYED (window))
930 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
934 gdk_window_lower (GdkWindow *window)
936 g_return_if_fail (window != NULL);
937 g_return_if_fail (GDK_IS_WINDOW (window));
939 if (!GDK_WINDOW_DESTROYED (window))
940 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
944 gdk_window_set_hints (GdkWindow *window,
953 XSizeHints size_hints;
955 g_return_if_fail (window != NULL);
956 g_return_if_fail (GDK_IS_WINDOW (window));
958 if (GDK_WINDOW_DESTROYED (window))
961 size_hints.flags = 0;
963 if (flags & GDK_HINT_POS)
965 size_hints.flags |= PPosition;
970 if (flags & GDK_HINT_MIN_SIZE)
972 size_hints.flags |= PMinSize;
973 size_hints.min_width = min_width;
974 size_hints.min_height = min_height;
977 if (flags & GDK_HINT_MAX_SIZE)
979 size_hints.flags |= PMaxSize;
980 size_hints.max_width = max_width;
981 size_hints.max_height = max_height;
984 /* FIXME: Would it be better to delete this property of
985 * flags == 0? It would save space on the server
987 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
988 GDK_WINDOW_XID (window),
993 gdk_window_set_geometry_hints (GdkWindow *window,
994 GdkGeometry *geometry,
995 GdkWindowHints geom_mask)
997 XSizeHints size_hints;
999 g_return_if_fail (window != NULL);
1000 g_return_if_fail (GDK_IS_WINDOW (window));
1002 if (GDK_WINDOW_DESTROYED (window))
1005 size_hints.flags = 0;
1007 if (geom_mask & GDK_HINT_POS)
1009 size_hints.flags |= PPosition;
1010 /* We need to initialize the following obsolete fields because KWM
1011 * apparently uses these fields if they are non-zero.
1018 if (geom_mask & GDK_HINT_MIN_SIZE)
1020 size_hints.flags |= PMinSize;
1021 size_hints.min_width = geometry->min_width;
1022 size_hints.min_height = geometry->min_height;
1025 if (geom_mask & GDK_HINT_MAX_SIZE)
1027 size_hints.flags |= PMaxSize;
1028 size_hints.max_width = MAX (geometry->max_width, 1);
1029 size_hints.max_height = MAX (geometry->max_height, 1);
1032 if (geom_mask & GDK_HINT_BASE_SIZE)
1034 size_hints.flags |= PBaseSize;
1035 size_hints.base_width = geometry->base_width;
1036 size_hints.base_height = geometry->base_height;
1039 if (geom_mask & GDK_HINT_RESIZE_INC)
1041 size_hints.flags |= PResizeInc;
1042 size_hints.width_inc = geometry->width_inc;
1043 size_hints.height_inc = geometry->height_inc;
1046 if (geom_mask & GDK_HINT_ASPECT)
1048 size_hints.flags |= PAspect;
1049 if (geometry->min_aspect <= 1)
1051 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1052 size_hints.min_aspect.y = 65536;
1056 size_hints.min_aspect.x = 65536;
1057 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1059 if (geometry->max_aspect <= 1)
1061 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1062 size_hints.max_aspect.y = 65536;
1066 size_hints.max_aspect.x = 65536;
1067 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1071 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1073 size_hints.flags |= PWinGravity;
1074 size_hints.width_inc = geometry->win_gravity;
1077 /* FIXME: Would it be better to delete this property of
1078 * geom_mask == 0? It would save space on the server
1080 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1081 GDK_WINDOW_XID (window),
1086 utf8_is_latin1 (const gchar *str)
1088 const char *p = str;
1092 gunichar ch = g_utf8_get_char (p);
1097 p = g_utf8_next_char (p);
1103 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1104 * convertable to STRING, otherwise, set it as compound text
1107 set_text_property (GdkWindow *window,
1109 const gchar *utf8_str)
1111 guchar *prop_text = NULL;
1116 if (utf8_is_latin1 (utf8_str))
1118 prop_type = GDK_TARGET_STRING;
1119 prop_text = gdk_utf8_to_string_target (utf8_str);
1120 prop_length = strlen (prop_text);
1125 gdk_utf8_to_compound_text (utf8_str, &prop_type, &prop_format,
1126 &prop_text, &prop_length);
1131 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1132 GDK_WINDOW_XID (window),
1134 prop_type, prop_format,
1135 PropModeReplace, prop_text,
1143 gdk_window_set_title (GdkWindow *window,
1146 g_return_if_fail (window != NULL);
1147 g_return_if_fail (GDK_IS_WINDOW (window));
1149 if (GDK_WINDOW_DESTROYED (window))
1152 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1153 GDK_WINDOW_XID (window),
1154 gdk_atom_intern ("_NET_WM_NAME", FALSE),
1155 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1156 PropModeReplace, title,
1159 set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
1160 if (!gdk_window_icon_name_set (window))
1161 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
1165 gdk_window_set_role (GdkWindow *window,
1168 g_return_if_fail (window != NULL);
1169 g_return_if_fail (GDK_IS_WINDOW (window));
1171 if (!GDK_WINDOW_DESTROYED (window))
1174 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1175 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1176 8, PropModeReplace, role, strlen (role));
1178 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1179 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1184 gdk_window_set_transient_for (GdkWindow *window,
1187 GdkWindowObject *private;
1188 GdkWindowObject *parent_private;
1190 g_return_if_fail (window != NULL);
1191 g_return_if_fail (GDK_IS_WINDOW (window));
1193 private = (GdkWindowObject*) window;
1194 parent_private = (GdkWindowObject*) parent;
1196 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1197 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1198 GDK_WINDOW_XID (window),
1199 GDK_WINDOW_XID (parent));
1203 gdk_window_set_background (GdkWindow *window,
1206 GdkWindowObject *private = (GdkWindowObject *)window;
1208 g_return_if_fail (window != NULL);
1209 g_return_if_fail (GDK_IS_WINDOW (window));
1211 if (!GDK_WINDOW_DESTROYED (window))
1212 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1213 GDK_WINDOW_XID (window), color->pixel);
1215 private->bg_color = *color;
1217 if (private->bg_pixmap &&
1218 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1219 private->bg_pixmap != GDK_NO_BG)
1221 gdk_pixmap_unref (private->bg_pixmap);
1222 private->bg_pixmap = NULL;
1227 gdk_window_set_back_pixmap (GdkWindow *window,
1229 gboolean parent_relative)
1231 GdkWindowObject *private = (GdkWindowObject *)window;
1234 g_return_if_fail (window != NULL);
1235 g_return_if_fail (GDK_IS_WINDOW (window));
1236 g_return_if_fail (pixmap == NULL || !parent_relative);
1238 if (private->bg_pixmap &&
1239 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1240 private->bg_pixmap != GDK_NO_BG)
1241 gdk_pixmap_unref (private->bg_pixmap);
1243 if (parent_relative)
1245 xpixmap = ParentRelative;
1246 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1252 gdk_pixmap_ref (pixmap);
1253 private->bg_pixmap = pixmap;
1254 xpixmap = GDK_PIXMAP_XID (pixmap);
1259 private->bg_pixmap = GDK_NO_BG;
1263 if (!GDK_WINDOW_DESTROYED (window))
1264 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1265 GDK_WINDOW_XID (window), xpixmap);
1269 gdk_window_set_cursor (GdkWindow *window,
1272 GdkCursorPrivate *cursor_private;
1275 g_return_if_fail (window != NULL);
1276 g_return_if_fail (GDK_IS_WINDOW (window));
1278 cursor_private = (GdkCursorPrivate*) cursor;
1283 xcursor = cursor_private->xcursor;
1285 if (!GDK_WINDOW_DESTROYED (window))
1286 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1287 GDK_WINDOW_XID (window),
1292 gdk_window_get_geometry (GdkWindow *window,
1304 guint tborder_width;
1307 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1310 window = gdk_parent_root;
1312 if (!GDK_WINDOW_DESTROYED (window))
1314 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1315 GDK_WINDOW_XID (window),
1316 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1332 gdk_window_get_origin (GdkWindow *window,
1341 g_return_val_if_fail (window != NULL, 0);
1343 if (!GDK_WINDOW_DESTROYED (window))
1345 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1346 GDK_WINDOW_XID (window),
1364 gdk_window_get_deskrelative_origin (GdkWindow *window,
1368 gboolean return_val = FALSE;
1369 gint num_children, format_return;
1370 Window win, *child, parent, root;
1374 static Atom atom = 0;
1375 gulong number_return, bytes_after_return;
1376 guchar *data_return;
1378 g_return_val_if_fail (window != NULL, 0);
1379 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1381 if (!GDK_WINDOW_DESTROYED (window))
1384 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1385 win = GDK_WINDOW_XID (window);
1387 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1388 &child, (unsigned int *)&num_children))
1390 if ((child) && (num_children > 0))
1402 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1403 False, XA_CARDINAL, &type_return, &format_return,
1404 &number_return, &bytes_after_return, &data_return);
1405 if (type_return == XA_CARDINAL)
1407 XFree (data_return);
1412 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1413 GDK_WINDOW_XID (window),
1428 gdk_window_get_root_origin (GdkWindow *window,
1432 GdkWindowObject *private;
1437 unsigned int nchildren;
1439 g_return_if_fail (window != NULL);
1440 g_return_if_fail (GDK_IS_WINDOW (window));
1442 private = (GdkWindowObject*) window;
1448 if (GDK_WINDOW_DESTROYED (window))
1451 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1452 private = (GdkWindowObject*) private->parent;
1453 if (GDK_WINDOW_DESTROYED (window))
1456 xparent = GDK_WINDOW_XID (window);
1460 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1462 &children, &nchildren))
1468 while (xparent != root);
1470 if (xparent == root)
1472 unsigned int ww, wh, wb, wd;
1475 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1486 gdk_window_get_pointer (GdkWindow *window,
1489 GdkModifierType *mask)
1491 GdkWindow *return_val;
1497 unsigned int xmask = 0;
1498 gint xoffset, yoffset;
1500 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1503 window = gdk_parent_root;
1505 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1508 if (!GDK_WINDOW_DESTROYED (window) &&
1509 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1510 GDK_WINDOW_XID (window),
1511 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1514 return_val = gdk_window_lookup (child);
1518 *x = winx + xoffset;
1520 *y = winy + yoffset;
1528 gdk_window_at_pointer (gint *win_x,
1534 Window xwindow_last = 0;
1536 int rootx = -1, rooty = -1;
1540 xwindow = GDK_ROOT_WINDOW ();
1541 xdisplay = GDK_DISPLAY ();
1543 XGrabServer (xdisplay);
1546 xwindow_last = xwindow;
1547 XQueryPointer (xdisplay, xwindow,
1553 XUngrabServer (xdisplay);
1555 window = gdk_window_lookup (xwindow_last);
1558 *win_x = window ? winx : -1;
1560 *win_y = window ? winy : -1;
1566 gdk_window_get_events (GdkWindow *window)
1568 XWindowAttributes attrs;
1569 GdkEventMask event_mask;
1572 g_return_val_if_fail (window != NULL, 0);
1573 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1575 if (GDK_WINDOW_DESTROYED (window))
1579 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1580 GDK_WINDOW_XID (window),
1584 for (i = 0; i < gdk_nevent_masks; i++)
1586 if (attrs.your_event_mask & gdk_event_mask_table[i])
1587 event_mask |= 1 << (i + 1);
1595 gdk_window_set_events (GdkWindow *window,
1596 GdkEventMask event_mask)
1601 g_return_if_fail (window != NULL);
1602 g_return_if_fail (GDK_IS_WINDOW (window));
1604 if (!GDK_WINDOW_DESTROYED (window))
1606 xevent_mask = StructureNotifyMask;
1607 for (i = 0; i < gdk_nevent_masks; i++)
1609 if (event_mask & (1 << (i + 1)))
1610 xevent_mask |= gdk_event_mask_table[i];
1613 XSelectInput (GDK_WINDOW_XDISPLAY (window),
1614 GDK_WINDOW_XID (window),
1620 gdk_window_add_colormap_windows (GdkWindow *window)
1622 GdkWindow *toplevel;
1623 Window *old_windows;
1624 Window *new_windows;
1627 g_return_if_fail (window != NULL);
1628 g_return_if_fail (GDK_IS_WINDOW (window));
1630 toplevel = gdk_window_get_toplevel (window);
1631 if (GDK_WINDOW_DESTROYED (toplevel))
1635 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1636 GDK_WINDOW_XID (toplevel),
1637 &old_windows, &count))
1642 for (i = 0; i < count; i++)
1643 if (old_windows[i] == GDK_WINDOW_XID (window))
1645 XFree (old_windows);
1649 new_windows = g_new (Window, count + 1);
1651 for (i = 0; i < count; i++)
1652 new_windows[i] = old_windows[i];
1653 new_windows[count] = GDK_WINDOW_XID (window);
1655 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1656 GDK_WINDOW_XID (toplevel),
1657 new_windows, count + 1);
1659 g_free (new_windows);
1661 XFree (old_windows);
1665 gdk_window_have_shape_ext (void)
1667 enum { UNKNOWN, NO, YES };
1668 static gint have_shape = UNKNOWN;
1670 if (have_shape == UNKNOWN)
1673 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1679 return (have_shape == YES);
1683 * This needs the X11 shape extension.
1684 * If not available, shaped windows will look
1685 * ugly, but programs still work. Stefan Wille
1688 gdk_window_shape_combine_mask (GdkWindow *window,
1694 g_return_if_fail (window != NULL);
1695 g_return_if_fail (GDK_IS_WINDOW (window));
1697 #ifdef HAVE_SHAPE_EXT
1698 if (GDK_WINDOW_DESTROYED (window))
1701 if (gdk_window_have_shape_ext ())
1705 pixmap = GDK_PIXMAP_XID (mask);
1714 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
1715 GDK_WINDOW_XID (window),
1721 #endif /* HAVE_SHAPE_EXT */
1725 gdk_window_set_override_redirect (GdkWindow *window,
1726 gboolean override_redirect)
1728 XSetWindowAttributes attr;
1730 g_return_if_fail (window != NULL);
1731 g_return_if_fail (GDK_IS_WINDOW (window));
1733 if (GDK_WINDOW_DESTROYED (window))
1735 attr.override_redirect = (override_redirect == FALSE)?False:True;
1736 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1737 GDK_WINDOW_XID (window),
1744 gdk_window_set_icon (GdkWindow *window,
1745 GdkWindow *icon_window,
1751 g_return_if_fail (window != NULL);
1752 g_return_if_fail (GDK_IS_WINDOW (window));
1754 if (GDK_WINDOW_DESTROYED (window))
1757 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1758 GDK_WINDOW_XID (window));
1760 wm_hints = XAllocWMHints ();
1762 if (icon_window != NULL)
1764 wm_hints->flags |= IconWindowHint;
1765 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
1770 wm_hints->flags |= IconPixmapHint;
1771 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
1776 wm_hints->flags |= IconMaskHint;
1777 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
1780 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1781 GDK_WINDOW_XID (window), wm_hints);
1786 gdk_window_icon_name_set (GdkWindow *window)
1788 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
1789 g_quark_from_static_string ("gdk-icon-name-set")));
1793 gdk_window_set_icon_name (GdkWindow *window,
1796 g_return_if_fail (window != NULL);
1797 g_return_if_fail (GDK_IS_WINDOW (window));
1799 if (GDK_WINDOW_DESTROYED (window))
1802 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
1803 GUINT_TO_POINTER (TRUE));
1805 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
1809 gdk_window_iconify (GdkWindow *window)
1813 g_return_if_fail (window != NULL);
1814 g_return_if_fail (GDK_IS_WINDOW (window));
1816 if (GDK_WINDOW_DESTROYED (window))
1819 display = GDK_WINDOW_XDISPLAY (window);
1820 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
1824 gdk_window_set_group (GdkWindow *window,
1829 g_return_if_fail (window != NULL);
1830 g_return_if_fail (GDK_IS_WINDOW (window));
1831 g_return_if_fail (leader != NULL);
1832 g_return_if_fail (GDK_IS_WINDOW (leader));
1834 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1837 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1838 GDK_WINDOW_XID (window));
1840 wm_hints = XAllocWMHints ();
1842 wm_hints->flags |= WindowGroupHint;
1843 wm_hints->window_group = GDK_WINDOW_XID (leader);
1845 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1846 GDK_WINDOW_XID (window), wm_hints);
1851 gdk_window_set_mwm_hints (GdkWindow *window,
1852 MotifWmHints *new_hints)
1854 static Atom hints_atom = None;
1855 MotifWmHints *hints;
1861 if (GDK_WINDOW_DESTROYED (window))
1865 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
1866 _XA_MOTIF_WM_HINTS, FALSE);
1868 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1869 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1870 False, AnyPropertyType, &type, &format, &nitems,
1871 &bytes_after, (guchar **)&hints);
1877 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1879 hints->flags |= MWM_HINTS_FUNCTIONS;
1880 hints->functions = new_hints->functions;
1882 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1884 hints->flags |= MWM_HINTS_DECORATIONS;
1885 hints->decorations = new_hints->decorations;
1889 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1890 hints_atom, hints_atom, 32, PropModeReplace,
1891 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1893 if (hints != new_hints)
1898 gdk_window_set_decorations (GdkWindow *window,
1899 GdkWMDecoration decorations)
1903 g_return_if_fail (window != NULL);
1904 g_return_if_fail (GDK_IS_WINDOW (window));
1906 hints.flags = MWM_HINTS_DECORATIONS;
1907 hints.decorations = decorations;
1909 gdk_window_set_mwm_hints (window, &hints);
1913 gdk_window_set_functions (GdkWindow *window,
1914 GdkWMFunction functions)
1918 g_return_if_fail (window != NULL);
1919 g_return_if_fail (GDK_IS_WINDOW (window));
1921 hints.flags = MWM_HINTS_FUNCTIONS;
1922 hints.functions = functions;
1924 gdk_window_set_mwm_hints (window, &hints);
1928 * propagate the shapes from all child windows of a GDK window to the parent
1929 * window. Shamelessly ripped from Enlightenment's code
1937 struct _gdk_span *next;
1941 gdk_add_to_span (struct _gdk_span **s,
1945 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1952 /* scan the spans for this line */
1955 /* -- -> new span */
1956 /* == -> existing span */
1957 /* ## -> spans intersect */
1958 /* if we are in the middle of spanning the span into the line */
1961 /* case: ---- ==== */
1962 if (xx < ptr1->start - 1)
1964 /* ends before next span - extend to here */
1968 /* case: ----##=== */
1969 else if (xx <= ptr1->end)
1971 /* crosses into next span - delete next span and append */
1972 ss->end = ptr1->end;
1973 ss->next = ptr1->next;
1977 /* case: ---###--- */
1980 /* overlaps next span - delete and keep checking */
1981 ss->next = ptr1->next;
1986 /* otherwise havent started spanning it in yet */
1989 /* case: ---- ==== */
1990 if (xx < ptr1->start - 1)
1992 /* insert span here in list */
1993 noo = g_malloc (sizeof (struct _gdk_span));
2007 /* case: ----##=== */
2008 else if ((x < ptr1->start) && (xx <= ptr1->end))
2010 /* expand this span to the left point of the new one */
2014 /* case: ===###=== */
2015 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2017 /* throw the span away */
2020 /* case: ---###--- */
2021 else if ((x < ptr1->start) && (xx > ptr1->end))
2028 /* case: ===##---- */
2029 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2035 /* case: ==== ---- */
2036 /* case handled by next loop iteration - first case */
2041 /* it started in the middle but spans beyond your current list */
2047 /* it does not start inside a span or in the middle, so add it to the end */
2048 noo = g_malloc (sizeof (struct _gdk_span));
2056 noo->next = ptr2->next;
2069 gdk_add_rectangles (Display *disp,
2071 struct _gdk_span **spans,
2078 gint x1, y1, x2, y2;
2082 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2085 /* go through all clip rects in this window's shape */
2086 for (k = 0; k < rn; k++)
2088 /* for each clip rect, add it to each line's spans */
2090 x2 = x + rl[k].x + (rl[k].width - 1);
2092 y2 = y + rl[k].y + (rl[k].height - 1);
2101 for (a = y1; a <= y2; a++)
2104 gdk_add_to_span (&spans[a], x1, x2);
2112 gdk_propagate_shapes (Display *disp,
2116 Window rt, par, *list = NULL;
2117 gint i, j, num = 0, num_rects = 0;
2121 XRectangle *rects = NULL;
2122 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2123 XWindowAttributes xatt;
2125 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2130 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2132 for (i = 0; i < h; i++)
2134 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2137 /* go through all child windows and create/insert spans */
2138 for (i = 0; i < num; i++)
2140 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2141 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2142 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2145 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2147 /* go through the spans list and build a list of rects */
2148 rects = g_malloc (sizeof (XRectangle) * 256);
2150 for (i = 0; i < baseh; i++)
2153 /* go through the line for all spans */
2156 rects[num_rects].x = ptr1->start;
2157 rects[num_rects].y = i;
2158 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2159 rects[num_rects].height = 1;
2161 /* if there are more lines */
2163 /* while contigous rects (same start/end coords) exist */
2164 while ((contig) && (j < baseh))
2166 /* search next line for spans matching this one */
2172 /* if we have an exact span match set contig */
2173 if ((ptr2->start == ptr1->start) &&
2174 (ptr2->end == ptr1->end))
2177 /* remove the span - not needed */
2180 ptr3->next = ptr2->next;
2186 spans[j] = ptr2->next;
2192 /* gone past the span point no point looking */
2193 else if (ptr2->start < ptr1->start)
2201 /* if a contiguous span was found increase the rect h */
2204 rects[num_rects].height++;
2208 /* up the rect count */
2210 /* every 256 new rects increase the rect array */
2211 if ((num_rects % 256) == 0)
2212 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2216 /* set the rects as the shape mask */
2219 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2220 ShapeSet, YXSorted);
2225 /* free up all the spans we made */
2226 for (i = 0; i < baseh; i++)
2240 gdk_window_set_child_shapes (GdkWindow *window)
2242 g_return_if_fail (window != NULL);
2243 g_return_if_fail (GDK_IS_WINDOW (window));
2245 #ifdef HAVE_SHAPE_EXT
2246 if (!GDK_WINDOW_DESTROYED (window) &&
2247 gdk_window_have_shape_ext ())
2248 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2249 GDK_WINDOW_XID (window), FALSE);
2254 gdk_window_merge_child_shapes (GdkWindow *window)
2256 g_return_if_fail (window != NULL);
2257 g_return_if_fail (GDK_IS_WINDOW (window));
2259 #ifdef HAVE_SHAPE_EXT
2260 if (!GDK_WINDOW_DESTROYED (window) &&
2261 gdk_window_have_shape_ext ())
2262 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2263 GDK_WINDOW_XID (window), TRUE);
2267 /* Support for windows that can be guffaw-scrolled
2268 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2272 gdk_window_gravity_works (void)
2274 enum { UNKNOWN, NO, YES };
2275 static gint gravity_works = UNKNOWN;
2277 if (gravity_works == UNKNOWN)
2284 /* This particular server apparently has a bug so that the test
2285 * works but the actual code crashes it
2287 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2288 (VendorRelease (gdk_display) == 3400))
2294 attr.window_type = GDK_WINDOW_TEMP;
2295 attr.wclass = GDK_INPUT_OUTPUT;
2300 attr.event_mask = 0;
2302 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2304 attr.window_type = GDK_WINDOW_CHILD;
2305 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2307 gdk_window_set_static_win_gravity (child, TRUE);
2309 gdk_window_resize (parent, 100, 110);
2310 gdk_window_move (parent, 0, -10);
2311 gdk_window_move_resize (parent, 0, 0, 100, 100);
2313 gdk_window_resize (parent, 100, 110);
2314 gdk_window_move (parent, 0, -10);
2315 gdk_window_move_resize (parent, 0, 0, 100, 100);
2317 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2319 gdk_window_destroy (parent);
2320 gdk_window_destroy (child);
2322 gravity_works = ((y == -20) ? YES : NO);
2325 return (gravity_works == YES);
2329 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2331 XSetWindowAttributes xattributes;
2332 guint xattributes_mask = 0;
2334 g_return_if_fail (window != NULL);
2336 xattributes.bit_gravity = StaticGravity;
2337 xattributes_mask |= CWBitGravity;
2338 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2339 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2340 GDK_WINDOW_XID (window),
2341 CWBitGravity, &xattributes);
2345 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2347 XSetWindowAttributes xattributes;
2349 g_return_if_fail (window != NULL);
2351 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2353 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2354 GDK_WINDOW_XID (window),
2355 CWWinGravity, &xattributes);
2358 /*************************************************************
2359 * gdk_window_set_static_gravities:
2360 * Set the bit gravity of the given window to static,
2361 * and flag it so all children get static subwindow
2364 * window: window for which to set static gravity
2365 * use_static: Whether to turn static gravity on or off.
2367 * Does the XServer support static gravity?
2368 *************************************************************/
2371 gdk_window_set_static_gravities (GdkWindow *window,
2372 gboolean use_static)
2374 GdkWindowObject *private = (GdkWindowObject *)window;
2377 g_return_val_if_fail (window != NULL, FALSE);
2378 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2380 if (!use_static == !private->guffaw_gravity)
2383 if (use_static && !gdk_window_gravity_works ())
2386 private->guffaw_gravity = use_static;
2388 if (!GDK_WINDOW_DESTROYED (window))
2390 gdk_window_set_static_bit_gravity (window, use_static);
2392 tmp_list = private->children;
2395 gdk_window_set_static_win_gravity (window, use_static);
2397 tmp_list = tmp_list->next;
2404 /* internal function created for and used by gdk_window_xid_at_coords */
2406 gdk_window_xid_at (Window base,
2412 gboolean excl_child)
2415 Window *list = NULL;
2416 Window child = 0, parent_win = 0, root_win = 0;
2418 unsigned int ww, wh, wb, wd, num;
2421 xdisplay = GDK_DISPLAY ();
2422 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2429 (x < (int) (wx + ww)) &&
2430 (y < (int) (wy + wh))))
2433 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2438 for (i = num - 1; ; i--)
2440 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2442 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2457 * The following fucntion by The Rasterman <raster@redhat.com>
2458 * This function returns the X Window ID in which the x y location is in
2459 * (x and y being relative to the root window), excluding any windows listed
2460 * in the GList excludes (this is a list of X Window ID's - gpointer being
2463 * This is primarily designed for internal gdk use - for DND for example
2464 * when using a shaped icon window as the drag object - you exclude the
2465 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2466 * You can get back an X Window ID as to what X Window ID is infact under
2467 * those X,Y co-ordinates.
2470 gdk_window_xid_at_coords (gint x,
2473 gboolean excl_child)
2477 Window *list = NULL;
2478 Window root, child = 0, parent_win = 0, root_win = 0;
2482 window = gdk_parent_root;
2483 xdisplay = GDK_WINDOW_XDISPLAY (window);
2484 root = GDK_WINDOW_XID (window);
2485 num = g_list_length (excludes);
2487 XGrabServer (xdisplay);
2488 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2490 XUngrabServer (xdisplay);
2498 XWindowAttributes xwa;
2500 XGetWindowAttributes (xdisplay, list [i], &xwa);
2502 if (xwa.map_state != IsViewable)
2505 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2508 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2513 if (!g_list_find (excludes, (gpointer *) child))
2516 XUngrabServer (xdisplay);
2523 XUngrabServer (xdisplay);
2529 XUngrabServer (xdisplay);