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));
214 impl = GDK_WINDOW_IMPL_X11 (drawable);
215 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
218 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
222 XSetWindowColormap (draw_impl->xdisplay,
224 GDK_COLORMAP_XCOLORMAP (cmap));
226 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
228 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
234 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
238 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
241 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
243 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
247 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
249 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
250 GdkRectangle result_rect;
254 result_rect.width = impl->width;
255 result_rect.height = impl->height;
257 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
259 return gdk_region_rectangle (&result_rect);
263 _gdk_windowing_window_init (void)
265 GdkWindowObject *private;
266 GdkWindowImplX11 *impl;
267 GdkDrawableImplX11 *draw_impl;
268 XWindowAttributes xattributes;
271 unsigned int border_width;
275 g_assert (gdk_parent_root == NULL);
277 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
278 &x, &y, &width, &height, &border_width, &depth);
279 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
281 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
282 private = (GdkWindowObject *)gdk_parent_root;
283 impl = GDK_WINDOW_IMPL_X11 (private->impl);
284 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
286 draw_impl->xdisplay = gdk_display;
287 draw_impl->xid = gdk_root_window;
288 draw_impl->wrapper = GDK_DRAWABLE (private);
290 private->window_type = GDK_WINDOW_ROOT;
291 private->depth = depth;
293 impl->height = height;
295 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
298 static GdkAtom wm_client_leader_atom = GDK_NONE;
301 gdk_window_new (GdkWindow *parent,
302 GdkWindowAttr *attributes,
303 gint attributes_mask)
306 GdkWindowObject *private;
307 GdkWindowObject *parent_private;
308 GdkWindowImplX11 *impl;
309 GdkDrawableImplX11 *draw_impl;
315 XSetWindowAttributes xattributes;
316 long xattributes_mask;
317 XSizeHints size_hints;
319 XClassHint *class_hint;
326 g_return_val_if_fail (attributes != NULL, NULL);
329 parent = gdk_parent_root;
331 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
333 parent_private = (GdkWindowObject*) parent;
334 if (GDK_WINDOW_DESTROYED (parent))
337 xparent = GDK_WINDOW_XID (parent);
339 window = g_object_new (GDK_TYPE_WINDOW, NULL);
340 private = (GdkWindowObject *)window;
341 impl = GDK_WINDOW_IMPL_X11 (private->impl);
342 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
343 draw_impl->wrapper = GDK_DRAWABLE (window);
345 draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
347 private->parent = (GdkWindowObject *)parent;
349 xattributes_mask = 0;
351 if (attributes_mask & GDK_WA_X)
356 if (attributes_mask & GDK_WA_Y)
363 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
364 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
365 private->window_type = attributes->window_type;
367 _gdk_window_init_position (GDK_WINDOW (private));
368 if (impl->position_info.big)
369 private->guffaw_gravity = TRUE;
371 if (attributes_mask & GDK_WA_VISUAL)
372 visual = attributes->visual;
374 visual = gdk_visual_get_system ();
375 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
377 xattributes.event_mask = StructureNotifyMask;
378 for (i = 0; i < gdk_nevent_masks; i++)
380 if (attributes->event_mask & (1 << (i + 1)))
381 xattributes.event_mask |= gdk_event_mask_table[i];
384 if (xattributes.event_mask)
385 xattributes_mask |= CWEventMask;
387 if (attributes_mask & GDK_WA_NOREDIR)
389 xattributes.override_redirect =
390 (attributes->override_redirect == FALSE)?False:True;
391 xattributes_mask |= CWOverrideRedirect;
394 xattributes.override_redirect = False;
396 if (parent_private && parent_private->guffaw_gravity)
398 xattributes.win_gravity = StaticGravity;
399 xattributes_mask |= CWWinGravity;
402 if (attributes->wclass == GDK_INPUT_OUTPUT)
405 depth = visual->depth;
407 private->input_only = FALSE;
408 private->depth = depth;
410 if (attributes_mask & GDK_WA_COLORMAP)
412 draw_impl->colormap = attributes->colormap;
413 gdk_colormap_ref (attributes->colormap);
417 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
419 draw_impl->colormap =
420 gdk_colormap_get_system ();
421 gdk_colormap_ref (draw_impl->colormap);
425 draw_impl->colormap =
426 gdk_colormap_new (visual, FALSE);
430 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
431 xattributes.background_pixel = private->bg_color.pixel;
433 private->bg_pixmap = NULL;
435 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
436 xattributes_mask |= CWBorderPixel | CWBackPixel;
438 if (private->guffaw_gravity)
439 xattributes.bit_gravity = StaticGravity;
441 xattributes.bit_gravity = NorthWestGravity;
443 xattributes_mask |= CWBitGravity;
445 switch (private->window_type)
447 case GDK_WINDOW_TOPLEVEL:
448 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
449 xattributes_mask |= CWColormap;
451 xparent = gdk_root_window;
454 case GDK_WINDOW_CHILD:
455 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
456 xattributes_mask |= CWColormap;
459 case GDK_WINDOW_DIALOG:
460 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
461 xattributes_mask |= CWColormap;
463 xparent = gdk_root_window;
466 case GDK_WINDOW_TEMP:
467 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
468 xattributes_mask |= CWColormap;
470 xparent = gdk_root_window;
472 xattributes.save_under = True;
473 xattributes.override_redirect = True;
474 xattributes.cursor = None;
475 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
477 case GDK_WINDOW_ROOT:
478 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
487 private->input_only = TRUE;
488 draw_impl->colormap = gdk_colormap_get_system ();
489 gdk_colormap_ref (draw_impl->colormap);
492 draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
494 impl->position_info.x, impl->position_info.y,
495 impl->position_info.width, impl->position_info.height,
496 0, depth, class, xvisual,
497 xattributes_mask, &xattributes);
499 gdk_drawable_ref (window);
500 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
502 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
503 (attributes->cursor) :
507 parent_private->children = g_list_prepend (parent_private->children, window);
509 switch (GDK_WINDOW_TYPE (private))
511 case GDK_WINDOW_DIALOG:
512 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
513 GDK_WINDOW_XID (window),
515 case GDK_WINDOW_TOPLEVEL:
516 case GDK_WINDOW_TEMP:
517 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
518 GDK_WINDOW_XID (window),
519 gdk_wm_window_protocols, 3);
521 case GDK_WINDOW_CHILD:
522 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
523 (draw_impl->colormap != gdk_colormap_get_system ()) &&
524 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
526 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
527 gdk_window_add_colormap_windows (window);
536 size_hints.flags = PSize;
537 size_hints.width = impl->width;
538 size_hints.height = impl->height;
540 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
541 wm_hints.window_group = gdk_leader_window;
542 wm_hints.input = True;
543 wm_hints.initial_state = NormalState;
545 /* FIXME: Is there any point in doing this? Do any WM's pay
546 * attention to PSize, and even if they do, is this the
549 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
550 GDK_WINDOW_XID (window),
553 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
554 GDK_WINDOW_XID (window),
557 if (!wm_client_leader_atom)
558 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
560 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
561 GDK_WINDOW_XID (window),
562 wm_client_leader_atom,
563 XA_WINDOW, 32, PropModeReplace,
564 (guchar*) &gdk_leader_window, 1);
566 if (attributes_mask & GDK_WA_TITLE)
567 title = attributes->title;
569 title = g_get_prgname ();
571 gdk_window_set_title (window, title);
573 if (attributes_mask & GDK_WA_WMCLASS)
575 class_hint = XAllocClassHint ();
576 class_hint->res_name = attributes->wmclass_name;
577 class_hint->res_class = attributes->wmclass_class;
578 XSetClassHint (GDK_WINDOW_XDISPLAY (window),
579 GDK_WINDOW_XID (window),
588 gdk_window_foreign_new (GdkNativeWindow anid)
591 GdkWindowObject *private;
592 GdkWindowObject *parent_private;
593 GdkWindowImplX11 *impl;
594 GdkDrawableImplX11 *draw_impl;
595 XWindowAttributes attrs;
597 Window *children = NULL;
601 gdk_error_trap_push ();
602 result = XGetWindowAttributes (gdk_display, anid, &attrs);
603 if (gdk_error_trap_pop () || !result)
606 /* FIXME: This is pretty expensive. Maybe the caller should supply
608 gdk_error_trap_push ();
609 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
610 if (gdk_error_trap_pop () || !result)
616 window = g_object_new (GDK_TYPE_WINDOW, NULL);
617 private = (GdkWindowObject *)window;
618 impl = GDK_WINDOW_IMPL_X11 (private->impl);
619 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
620 draw_impl->wrapper = GDK_DRAWABLE (window);
622 private->parent = gdk_xid_table_lookup (parent);
624 parent_private = (GdkWindowObject *)private->parent;
627 parent_private->children = g_list_prepend (parent_private->children, window);
629 draw_impl->xid = anid;
630 draw_impl->xdisplay = gdk_display;
632 private->x = attrs.x;
633 private->y = attrs.y;
634 impl->width = attrs.width;
635 impl->height = attrs.height;
636 private->window_type = GDK_WINDOW_FOREIGN;
637 private->destroyed = FALSE;
638 private->mapped = (attrs.map_state != IsUnmapped);
639 private->depth = attrs.depth;
641 gdk_drawable_ref (window);
642 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
648 _gdk_windowing_window_destroy (GdkWindow *window,
650 gboolean foreign_destroy)
652 GdkWindowObject *private = (GdkWindowObject *)window;
654 g_return_if_fail (GDK_IS_WINDOW (window));
656 _gdk_selection_window_destroyed (window);
658 if (private->extension_events != 0)
659 gdk_input_window_destroy (window);
661 if (private->window_type == GDK_WINDOW_FOREIGN)
663 if (!foreign_destroy && (private->parent != NULL))
665 /* It's somebody else's window, but in our heirarchy,
666 * so reparent it to the root window, and then send
667 * it a delete event, as if we were a WM
669 XClientMessageEvent xevent;
671 gdk_error_trap_push ();
672 gdk_window_hide (window);
673 gdk_window_reparent (window, NULL, 0, 0);
675 xevent.type = ClientMessage;
676 xevent.window = GDK_WINDOW_XID (window);
677 xevent.message_type = gdk_wm_protocols;
679 xevent.data.l[0] = gdk_wm_delete_window;
680 xevent.data.l[1] = CurrentTime;
682 XSendEvent (GDK_WINDOW_XDISPLAY (window),
683 GDK_WINDOW_XID (window),
684 False, 0, (XEvent *)&xevent);
686 gdk_error_trap_pop ();
689 else if (!recursing && !foreign_destroy)
690 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
693 /* This function is called when the XWindow is really gone.
696 gdk_window_destroy_notify (GdkWindow *window)
698 g_return_if_fail (window != NULL);
700 if (!GDK_WINDOW_DESTROYED (window))
702 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
703 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
705 _gdk_window_destroy (window, TRUE);
708 gdk_xid_table_remove (GDK_WINDOW_XID (window));
709 gdk_drawable_unref (window);
713 gdk_window_show (GdkWindow *window)
715 GdkWindowObject *private;
717 g_return_if_fail (GDK_IS_WINDOW (window));
719 private = (GdkWindowObject*) window;
720 if (!private->destroyed)
722 private->mapped = TRUE;
723 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
724 GDK_WINDOW_XID (window));
726 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
727 XMapWindow (GDK_WINDOW_XDISPLAY (window),
728 GDK_WINDOW_XID (window));
733 gdk_window_hide (GdkWindow *window)
735 GdkWindowObject *private;
737 g_return_if_fail (window != NULL);
739 private = (GdkWindowObject*) window;
740 if (!private->destroyed)
742 private->mapped = FALSE;
744 _gdk_window_clear_update_area (window);
746 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
747 GDK_WINDOW_XID (window));
752 gdk_window_withdraw (GdkWindow *window)
754 GdkWindowObject *private;
756 g_return_if_fail (window != NULL);
758 private = (GdkWindowObject*) window;
759 if (!private->destroyed)
760 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
761 GDK_WINDOW_XID (window), 0);
765 gdk_window_move (GdkWindow *window,
769 GdkWindowObject *private = (GdkWindowObject *)window;
770 GdkWindowImplX11 *impl;
772 g_return_if_fail (window != NULL);
773 g_return_if_fail (GDK_IS_WINDOW (window));
775 impl = GDK_WINDOW_IMPL_X11 (private->impl);
777 if (!GDK_WINDOW_DESTROYED (window))
779 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
780 _gdk_window_move_resize_child (window, x, y,
781 impl->width, impl->height);
784 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
785 GDK_WINDOW_XID (window),
792 gdk_window_resize (GdkWindow *window,
796 GdkWindowObject *private;
798 g_return_if_fail (window != NULL);
799 g_return_if_fail (GDK_IS_WINDOW (window));
806 private = (GdkWindowObject*) window;
808 if (!GDK_WINDOW_DESTROYED (window))
810 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
811 _gdk_window_move_resize_child (window, private->x, private->y,
815 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
816 GDK_WINDOW_XID (window),
818 private->resize_count += 1;
824 gdk_window_move_resize (GdkWindow *window,
830 GdkWindowObject *private;
832 g_return_if_fail (window != NULL);
833 g_return_if_fail (GDK_IS_WINDOW (window));
840 private = (GdkWindowObject*) window;
842 if (!GDK_WINDOW_DESTROYED (window))
844 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
845 _gdk_window_move_resize_child (window, x, y, width, height);
848 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
849 GDK_WINDOW_XID (window),
850 x, y, width, height);
851 private->resize_count += 1;
857 gdk_window_reparent (GdkWindow *window,
858 GdkWindow *new_parent,
862 GdkWindowObject *window_private;
863 GdkWindowObject *parent_private;
864 GdkWindowObject *old_parent_private;
866 g_return_if_fail (window != NULL);
867 g_return_if_fail (GDK_IS_WINDOW (window));
868 g_return_if_fail (new_parent != NULL);
869 g_return_if_fail (GDK_IS_WINDOW (new_parent));
872 new_parent = gdk_parent_root;
874 window_private = (GdkWindowObject*) window;
875 old_parent_private = (GdkWindowObject*)window_private->parent;
876 parent_private = (GdkWindowObject*) new_parent;
878 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
879 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
880 GDK_WINDOW_XID (window),
881 GDK_WINDOW_XID (new_parent),
884 window_private->parent = (GdkWindowObject *)new_parent;
886 if (old_parent_private)
887 old_parent_private->children = g_list_remove (old_parent_private->children, window);
889 if ((old_parent_private &&
890 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
891 (!old_parent_private && parent_private->guffaw_gravity))
892 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
894 parent_private->children = g_list_prepend (parent_private->children, window);
898 _gdk_windowing_window_clear_area (GdkWindow *window,
904 g_return_if_fail (window != NULL);
905 g_return_if_fail (GDK_IS_WINDOW (window));
907 if (!GDK_WINDOW_DESTROYED (window))
908 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
909 x, y, width, height, False);
913 _gdk_windowing_window_clear_area_e (GdkWindow *window,
919 g_return_if_fail (window != NULL);
920 g_return_if_fail (GDK_IS_WINDOW (window));
922 if (!GDK_WINDOW_DESTROYED (window))
923 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
924 x, y, width, height, True);
928 gdk_window_raise (GdkWindow *window)
930 g_return_if_fail (window != NULL);
931 g_return_if_fail (GDK_IS_WINDOW (window));
933 if (!GDK_WINDOW_DESTROYED (window))
934 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
938 gdk_window_lower (GdkWindow *window)
940 g_return_if_fail (window != NULL);
941 g_return_if_fail (GDK_IS_WINDOW (window));
943 if (!GDK_WINDOW_DESTROYED (window))
944 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
948 gdk_window_set_hints (GdkWindow *window,
957 XSizeHints size_hints;
959 g_return_if_fail (window != NULL);
960 g_return_if_fail (GDK_IS_WINDOW (window));
962 if (GDK_WINDOW_DESTROYED (window))
965 size_hints.flags = 0;
967 if (flags & GDK_HINT_POS)
969 size_hints.flags |= PPosition;
974 if (flags & GDK_HINT_MIN_SIZE)
976 size_hints.flags |= PMinSize;
977 size_hints.min_width = min_width;
978 size_hints.min_height = min_height;
981 if (flags & GDK_HINT_MAX_SIZE)
983 size_hints.flags |= PMaxSize;
984 size_hints.max_width = max_width;
985 size_hints.max_height = max_height;
988 /* FIXME: Would it be better to delete this property of
989 * flags == 0? It would save space on the server
991 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
992 GDK_WINDOW_XID (window),
997 gdk_window_set_geometry_hints (GdkWindow *window,
998 GdkGeometry *geometry,
999 GdkWindowHints geom_mask)
1001 XSizeHints size_hints;
1003 g_return_if_fail (window != NULL);
1004 g_return_if_fail (GDK_IS_WINDOW (window));
1006 if (GDK_WINDOW_DESTROYED (window))
1009 size_hints.flags = 0;
1011 if (geom_mask & GDK_HINT_POS)
1013 size_hints.flags |= PPosition;
1014 /* We need to initialize the following obsolete fields because KWM
1015 * apparently uses these fields if they are non-zero.
1022 if (geom_mask & GDK_HINT_MIN_SIZE)
1024 size_hints.flags |= PMinSize;
1025 size_hints.min_width = geometry->min_width;
1026 size_hints.min_height = geometry->min_height;
1029 if (geom_mask & GDK_HINT_MAX_SIZE)
1031 size_hints.flags |= PMaxSize;
1032 size_hints.max_width = MAX (geometry->max_width, 1);
1033 size_hints.max_height = MAX (geometry->max_height, 1);
1036 if (geom_mask & GDK_HINT_BASE_SIZE)
1038 size_hints.flags |= PBaseSize;
1039 size_hints.base_width = geometry->base_width;
1040 size_hints.base_height = geometry->base_height;
1043 if (geom_mask & GDK_HINT_RESIZE_INC)
1045 size_hints.flags |= PResizeInc;
1046 size_hints.width_inc = geometry->width_inc;
1047 size_hints.height_inc = geometry->height_inc;
1050 if (geom_mask & GDK_HINT_ASPECT)
1052 size_hints.flags |= PAspect;
1053 if (geometry->min_aspect <= 1)
1055 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1056 size_hints.min_aspect.y = 65536;
1060 size_hints.min_aspect.x = 65536;
1061 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1063 if (geometry->max_aspect <= 1)
1065 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1066 size_hints.max_aspect.y = 65536;
1070 size_hints.max_aspect.x = 65536;
1071 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1075 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1077 size_hints.flags |= PWinGravity;
1078 size_hints.width_inc = geometry->win_gravity;
1081 /* FIXME: Would it be better to delete this property of
1082 * geom_mask == 0? It would save space on the server
1084 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1085 GDK_WINDOW_XID (window),
1090 utf8_is_latin1 (const gchar *str)
1092 const char *p = str;
1096 gunichar ch = g_utf8_get_char (p);
1101 p = g_utf8_next_char (p);
1107 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1108 * convertable to STRING, otherwise, set it as compound text
1111 set_text_property (GdkWindow *window,
1113 const gchar *utf8_str)
1115 guchar *prop_text = NULL;
1120 if (utf8_is_latin1 (utf8_str))
1122 prop_type = GDK_TARGET_STRING;
1123 prop_text = gdk_utf8_to_string_target (utf8_str);
1124 prop_length = strlen (prop_text);
1129 gdk_utf8_to_compound_text (utf8_str, &prop_type, &prop_format,
1130 &prop_text, &prop_length);
1135 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1136 GDK_WINDOW_XID (window),
1138 prop_type, prop_format,
1139 PropModeReplace, prop_text,
1147 gdk_window_set_title (GdkWindow *window,
1150 g_return_if_fail (window != NULL);
1151 g_return_if_fail (GDK_IS_WINDOW (window));
1153 if (GDK_WINDOW_DESTROYED (window))
1156 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1157 GDK_WINDOW_XID (window),
1158 gdk_atom_intern ("_NET_WM_NAME", FALSE),
1159 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1160 PropModeReplace, title,
1163 set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
1164 if (!gdk_window_icon_name_set (window))
1165 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
1169 gdk_window_set_role (GdkWindow *window,
1172 g_return_if_fail (window != NULL);
1173 g_return_if_fail (GDK_IS_WINDOW (window));
1175 if (!GDK_WINDOW_DESTROYED (window))
1178 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1179 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1180 8, PropModeReplace, role, strlen (role));
1182 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1183 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1188 gdk_window_set_transient_for (GdkWindow *window,
1191 GdkWindowObject *private;
1192 GdkWindowObject *parent_private;
1194 g_return_if_fail (window != NULL);
1195 g_return_if_fail (GDK_IS_WINDOW (window));
1197 private = (GdkWindowObject*) window;
1198 parent_private = (GdkWindowObject*) parent;
1200 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1201 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1202 GDK_WINDOW_XID (window),
1203 GDK_WINDOW_XID (parent));
1207 gdk_window_set_background (GdkWindow *window,
1210 GdkWindowObject *private = (GdkWindowObject *)window;
1212 g_return_if_fail (window != NULL);
1213 g_return_if_fail (GDK_IS_WINDOW (window));
1215 if (!GDK_WINDOW_DESTROYED (window))
1216 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1217 GDK_WINDOW_XID (window), color->pixel);
1219 private->bg_color = *color;
1221 if (private->bg_pixmap &&
1222 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1223 private->bg_pixmap != GDK_NO_BG)
1225 gdk_pixmap_unref (private->bg_pixmap);
1226 private->bg_pixmap = NULL;
1231 gdk_window_set_back_pixmap (GdkWindow *window,
1233 gboolean parent_relative)
1235 GdkWindowObject *private = (GdkWindowObject *)window;
1238 g_return_if_fail (window != NULL);
1239 g_return_if_fail (GDK_IS_WINDOW (window));
1240 g_return_if_fail (pixmap == NULL || !parent_relative);
1242 if (private->bg_pixmap &&
1243 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1244 private->bg_pixmap != GDK_NO_BG)
1245 gdk_pixmap_unref (private->bg_pixmap);
1247 if (parent_relative)
1249 xpixmap = ParentRelative;
1250 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1256 gdk_pixmap_ref (pixmap);
1257 private->bg_pixmap = pixmap;
1258 xpixmap = GDK_PIXMAP_XID (pixmap);
1263 private->bg_pixmap = GDK_NO_BG;
1267 if (!GDK_WINDOW_DESTROYED (window))
1268 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1269 GDK_WINDOW_XID (window), xpixmap);
1273 gdk_window_set_cursor (GdkWindow *window,
1276 GdkCursorPrivate *cursor_private;
1279 g_return_if_fail (window != NULL);
1280 g_return_if_fail (GDK_IS_WINDOW (window));
1282 cursor_private = (GdkCursorPrivate*) cursor;
1287 xcursor = cursor_private->xcursor;
1289 if (!GDK_WINDOW_DESTROYED (window))
1290 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1291 GDK_WINDOW_XID (window),
1296 gdk_window_get_geometry (GdkWindow *window,
1308 guint tborder_width;
1311 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1314 window = gdk_parent_root;
1316 if (!GDK_WINDOW_DESTROYED (window))
1318 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1319 GDK_WINDOW_XID (window),
1320 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1336 gdk_window_get_origin (GdkWindow *window,
1345 g_return_val_if_fail (window != NULL, 0);
1347 if (!GDK_WINDOW_DESTROYED (window))
1349 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1350 GDK_WINDOW_XID (window),
1368 gdk_window_get_deskrelative_origin (GdkWindow *window,
1372 gboolean return_val = FALSE;
1373 gint num_children, format_return;
1374 Window win, *child, parent, root;
1378 static Atom atom = 0;
1379 gulong number_return, bytes_after_return;
1380 guchar *data_return;
1382 g_return_val_if_fail (window != NULL, 0);
1383 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1385 if (!GDK_WINDOW_DESTROYED (window))
1388 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1389 win = GDK_WINDOW_XID (window);
1391 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1392 &child, (unsigned int *)&num_children))
1394 if ((child) && (num_children > 0))
1406 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1407 False, XA_CARDINAL, &type_return, &format_return,
1408 &number_return, &bytes_after_return, &data_return);
1409 if (type_return == XA_CARDINAL)
1411 XFree (data_return);
1416 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1417 GDK_WINDOW_XID (window),
1432 gdk_window_get_root_origin (GdkWindow *window,
1436 GdkWindowObject *private;
1441 unsigned int nchildren;
1443 g_return_if_fail (window != NULL);
1444 g_return_if_fail (GDK_IS_WINDOW (window));
1446 private = (GdkWindowObject*) window;
1452 if (GDK_WINDOW_DESTROYED (window))
1455 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1456 private = (GdkWindowObject*) private->parent;
1457 if (GDK_WINDOW_DESTROYED (window))
1460 xparent = GDK_WINDOW_XID (window);
1464 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1466 &children, &nchildren))
1472 while (xparent != root);
1474 if (xparent == root)
1476 unsigned int ww, wh, wb, wd;
1479 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1490 gdk_window_get_pointer (GdkWindow *window,
1493 GdkModifierType *mask)
1495 GdkWindow *return_val;
1501 unsigned int xmask = 0;
1502 gint xoffset, yoffset;
1504 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1507 window = gdk_parent_root;
1509 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1512 if (!GDK_WINDOW_DESTROYED (window) &&
1513 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1514 GDK_WINDOW_XID (window),
1515 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1518 return_val = gdk_window_lookup (child);
1522 *x = winx + xoffset;
1524 *y = winy + yoffset;
1532 gdk_window_at_pointer (gint *win_x,
1538 Window xwindow_last = 0;
1540 int rootx = -1, rooty = -1;
1544 xwindow = GDK_ROOT_WINDOW ();
1545 xdisplay = GDK_DISPLAY ();
1547 XGrabServer (xdisplay);
1550 xwindow_last = xwindow;
1551 XQueryPointer (xdisplay, xwindow,
1557 XUngrabServer (xdisplay);
1559 window = gdk_window_lookup (xwindow_last);
1562 *win_x = window ? winx : -1;
1564 *win_y = window ? winy : -1;
1570 gdk_window_get_events (GdkWindow *window)
1572 XWindowAttributes attrs;
1573 GdkEventMask event_mask;
1576 g_return_val_if_fail (window != NULL, 0);
1577 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1579 if (GDK_WINDOW_DESTROYED (window))
1583 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1584 GDK_WINDOW_XID (window),
1588 for (i = 0; i < gdk_nevent_masks; i++)
1590 if (attrs.your_event_mask & gdk_event_mask_table[i])
1591 event_mask |= 1 << (i + 1);
1599 gdk_window_set_events (GdkWindow *window,
1600 GdkEventMask event_mask)
1605 g_return_if_fail (window != NULL);
1606 g_return_if_fail (GDK_IS_WINDOW (window));
1608 if (!GDK_WINDOW_DESTROYED (window))
1610 xevent_mask = StructureNotifyMask;
1611 for (i = 0; i < gdk_nevent_masks; i++)
1613 if (event_mask & (1 << (i + 1)))
1614 xevent_mask |= gdk_event_mask_table[i];
1617 XSelectInput (GDK_WINDOW_XDISPLAY (window),
1618 GDK_WINDOW_XID (window),
1624 gdk_window_add_colormap_windows (GdkWindow *window)
1626 GdkWindow *toplevel;
1627 Window *old_windows;
1628 Window *new_windows;
1631 g_return_if_fail (window != NULL);
1632 g_return_if_fail (GDK_IS_WINDOW (window));
1634 toplevel = gdk_window_get_toplevel (window);
1635 if (GDK_WINDOW_DESTROYED (toplevel))
1639 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1640 GDK_WINDOW_XID (toplevel),
1641 &old_windows, &count))
1646 for (i = 0; i < count; i++)
1647 if (old_windows[i] == GDK_WINDOW_XID (window))
1649 XFree (old_windows);
1653 new_windows = g_new (Window, count + 1);
1655 for (i = 0; i < count; i++)
1656 new_windows[i] = old_windows[i];
1657 new_windows[count] = GDK_WINDOW_XID (window);
1659 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1660 GDK_WINDOW_XID (toplevel),
1661 new_windows, count + 1);
1663 g_free (new_windows);
1665 XFree (old_windows);
1669 gdk_window_have_shape_ext (void)
1671 enum { UNKNOWN, NO, YES };
1672 static gint have_shape = UNKNOWN;
1674 if (have_shape == UNKNOWN)
1677 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1683 return (have_shape == YES);
1687 * This needs the X11 shape extension.
1688 * If not available, shaped windows will look
1689 * ugly, but programs still work. Stefan Wille
1692 gdk_window_shape_combine_mask (GdkWindow *window,
1698 g_return_if_fail (window != NULL);
1699 g_return_if_fail (GDK_IS_WINDOW (window));
1701 #ifdef HAVE_SHAPE_EXT
1702 if (GDK_WINDOW_DESTROYED (window))
1705 if (gdk_window_have_shape_ext ())
1709 pixmap = GDK_PIXMAP_XID (mask);
1718 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
1719 GDK_WINDOW_XID (window),
1725 #endif /* HAVE_SHAPE_EXT */
1729 gdk_window_set_override_redirect (GdkWindow *window,
1730 gboolean override_redirect)
1732 XSetWindowAttributes attr;
1734 g_return_if_fail (window != NULL);
1735 g_return_if_fail (GDK_IS_WINDOW (window));
1737 if (GDK_WINDOW_DESTROYED (window))
1739 attr.override_redirect = (override_redirect == FALSE)?False:True;
1740 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1741 GDK_WINDOW_XID (window),
1748 gdk_window_set_icon (GdkWindow *window,
1749 GdkWindow *icon_window,
1755 g_return_if_fail (window != NULL);
1756 g_return_if_fail (GDK_IS_WINDOW (window));
1758 if (GDK_WINDOW_DESTROYED (window))
1761 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1762 GDK_WINDOW_XID (window));
1764 wm_hints = XAllocWMHints ();
1766 if (icon_window != NULL)
1768 wm_hints->flags |= IconWindowHint;
1769 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
1774 wm_hints->flags |= IconPixmapHint;
1775 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
1780 wm_hints->flags |= IconMaskHint;
1781 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
1784 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1785 GDK_WINDOW_XID (window), wm_hints);
1790 gdk_window_icon_name_set (GdkWindow *window)
1792 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
1793 g_quark_from_static_string ("gdk-icon-name-set")));
1797 gdk_window_set_icon_name (GdkWindow *window,
1800 g_return_if_fail (window != NULL);
1801 g_return_if_fail (GDK_IS_WINDOW (window));
1803 if (GDK_WINDOW_DESTROYED (window))
1806 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
1807 GUINT_TO_POINTER (TRUE));
1809 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
1813 gdk_window_iconify (GdkWindow *window)
1817 g_return_if_fail (window != NULL);
1818 g_return_if_fail (GDK_IS_WINDOW (window));
1820 if (GDK_WINDOW_DESTROYED (window))
1823 display = GDK_WINDOW_XDISPLAY (window);
1824 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
1828 gdk_window_set_group (GdkWindow *window,
1833 g_return_if_fail (window != NULL);
1834 g_return_if_fail (GDK_IS_WINDOW (window));
1835 g_return_if_fail (leader != NULL);
1836 g_return_if_fail (GDK_IS_WINDOW (leader));
1838 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1841 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1842 GDK_WINDOW_XID (window));
1844 wm_hints = XAllocWMHints ();
1846 wm_hints->flags |= WindowGroupHint;
1847 wm_hints->window_group = GDK_WINDOW_XID (leader);
1849 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1850 GDK_WINDOW_XID (window), wm_hints);
1855 gdk_window_set_mwm_hints (GdkWindow *window,
1856 MotifWmHints *new_hints)
1858 static Atom hints_atom = None;
1859 MotifWmHints *hints;
1865 if (GDK_WINDOW_DESTROYED (window))
1869 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
1870 _XA_MOTIF_WM_HINTS, FALSE);
1872 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1873 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1874 False, AnyPropertyType, &type, &format, &nitems,
1875 &bytes_after, (guchar **)&hints);
1881 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1883 hints->flags |= MWM_HINTS_FUNCTIONS;
1884 hints->functions = new_hints->functions;
1886 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1888 hints->flags |= MWM_HINTS_DECORATIONS;
1889 hints->decorations = new_hints->decorations;
1893 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1894 hints_atom, hints_atom, 32, PropModeReplace,
1895 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1897 if (hints != new_hints)
1902 gdk_window_set_decorations (GdkWindow *window,
1903 GdkWMDecoration decorations)
1907 g_return_if_fail (window != NULL);
1908 g_return_if_fail (GDK_IS_WINDOW (window));
1910 hints.flags = MWM_HINTS_DECORATIONS;
1911 hints.decorations = decorations;
1913 gdk_window_set_mwm_hints (window, &hints);
1917 gdk_window_set_functions (GdkWindow *window,
1918 GdkWMFunction functions)
1922 g_return_if_fail (window != NULL);
1923 g_return_if_fail (GDK_IS_WINDOW (window));
1925 hints.flags = MWM_HINTS_FUNCTIONS;
1926 hints.functions = functions;
1928 gdk_window_set_mwm_hints (window, &hints);
1932 * propagate the shapes from all child windows of a GDK window to the parent
1933 * window. Shamelessly ripped from Enlightenment's code
1941 struct _gdk_span *next;
1945 gdk_add_to_span (struct _gdk_span **s,
1949 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1956 /* scan the spans for this line */
1959 /* -- -> new span */
1960 /* == -> existing span */
1961 /* ## -> spans intersect */
1962 /* if we are in the middle of spanning the span into the line */
1965 /* case: ---- ==== */
1966 if (xx < ptr1->start - 1)
1968 /* ends before next span - extend to here */
1972 /* case: ----##=== */
1973 else if (xx <= ptr1->end)
1975 /* crosses into next span - delete next span and append */
1976 ss->end = ptr1->end;
1977 ss->next = ptr1->next;
1981 /* case: ---###--- */
1984 /* overlaps next span - delete and keep checking */
1985 ss->next = ptr1->next;
1990 /* otherwise havent started spanning it in yet */
1993 /* case: ---- ==== */
1994 if (xx < ptr1->start - 1)
1996 /* insert span here in list */
1997 noo = g_malloc (sizeof (struct _gdk_span));
2011 /* case: ----##=== */
2012 else if ((x < ptr1->start) && (xx <= ptr1->end))
2014 /* expand this span to the left point of the new one */
2018 /* case: ===###=== */
2019 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2021 /* throw the span away */
2024 /* case: ---###--- */
2025 else if ((x < ptr1->start) && (xx > ptr1->end))
2032 /* case: ===##---- */
2033 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2039 /* case: ==== ---- */
2040 /* case handled by next loop iteration - first case */
2045 /* it started in the middle but spans beyond your current list */
2051 /* it does not start inside a span or in the middle, so add it to the end */
2052 noo = g_malloc (sizeof (struct _gdk_span));
2060 noo->next = ptr2->next;
2073 gdk_add_rectangles (Display *disp,
2075 struct _gdk_span **spans,
2082 gint x1, y1, x2, y2;
2086 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2089 /* go through all clip rects in this window's shape */
2090 for (k = 0; k < rn; k++)
2092 /* for each clip rect, add it to each line's spans */
2094 x2 = x + rl[k].x + (rl[k].width - 1);
2096 y2 = y + rl[k].y + (rl[k].height - 1);
2105 for (a = y1; a <= y2; a++)
2108 gdk_add_to_span (&spans[a], x1, x2);
2116 gdk_propagate_shapes (Display *disp,
2120 Window rt, par, *list = NULL;
2121 gint i, j, num = 0, num_rects = 0;
2125 XRectangle *rects = NULL;
2126 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2127 XWindowAttributes xatt;
2129 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2134 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2136 for (i = 0; i < h; i++)
2138 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2141 /* go through all child windows and create/insert spans */
2142 for (i = 0; i < num; i++)
2144 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2145 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2146 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2149 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2151 /* go through the spans list and build a list of rects */
2152 rects = g_malloc (sizeof (XRectangle) * 256);
2154 for (i = 0; i < baseh; i++)
2157 /* go through the line for all spans */
2160 rects[num_rects].x = ptr1->start;
2161 rects[num_rects].y = i;
2162 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2163 rects[num_rects].height = 1;
2165 /* if there are more lines */
2167 /* while contigous rects (same start/end coords) exist */
2168 while ((contig) && (j < baseh))
2170 /* search next line for spans matching this one */
2176 /* if we have an exact span match set contig */
2177 if ((ptr2->start == ptr1->start) &&
2178 (ptr2->end == ptr1->end))
2181 /* remove the span - not needed */
2184 ptr3->next = ptr2->next;
2190 spans[j] = ptr2->next;
2196 /* gone past the span point no point looking */
2197 else if (ptr2->start < ptr1->start)
2205 /* if a contiguous span was found increase the rect h */
2208 rects[num_rects].height++;
2212 /* up the rect count */
2214 /* every 256 new rects increase the rect array */
2215 if ((num_rects % 256) == 0)
2216 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2220 /* set the rects as the shape mask */
2223 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2224 ShapeSet, YXSorted);
2229 /* free up all the spans we made */
2230 for (i = 0; i < baseh; i++)
2244 gdk_window_set_child_shapes (GdkWindow *window)
2246 g_return_if_fail (window != NULL);
2247 g_return_if_fail (GDK_IS_WINDOW (window));
2249 #ifdef HAVE_SHAPE_EXT
2250 if (!GDK_WINDOW_DESTROYED (window) &&
2251 gdk_window_have_shape_ext ())
2252 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2253 GDK_WINDOW_XID (window), FALSE);
2258 gdk_window_merge_child_shapes (GdkWindow *window)
2260 g_return_if_fail (window != NULL);
2261 g_return_if_fail (GDK_IS_WINDOW (window));
2263 #ifdef HAVE_SHAPE_EXT
2264 if (!GDK_WINDOW_DESTROYED (window) &&
2265 gdk_window_have_shape_ext ())
2266 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2267 GDK_WINDOW_XID (window), TRUE);
2271 /* Support for windows that can be guffaw-scrolled
2272 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2276 gdk_window_gravity_works (void)
2278 enum { UNKNOWN, NO, YES };
2279 static gint gravity_works = UNKNOWN;
2281 if (gravity_works == UNKNOWN)
2288 /* This particular server apparently has a bug so that the test
2289 * works but the actual code crashes it
2291 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2292 (VendorRelease (gdk_display) == 3400))
2298 attr.window_type = GDK_WINDOW_TEMP;
2299 attr.wclass = GDK_INPUT_OUTPUT;
2304 attr.event_mask = 0;
2306 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2308 attr.window_type = GDK_WINDOW_CHILD;
2309 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2311 gdk_window_set_static_win_gravity (child, TRUE);
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_resize (parent, 100, 110);
2318 gdk_window_move (parent, 0, -10);
2319 gdk_window_move_resize (parent, 0, 0, 100, 100);
2321 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2323 gdk_window_destroy (parent);
2324 gdk_window_destroy (child);
2326 gravity_works = ((y == -20) ? YES : NO);
2329 return (gravity_works == YES);
2333 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2335 XSetWindowAttributes xattributes;
2336 guint xattributes_mask = 0;
2338 g_return_if_fail (window != NULL);
2340 xattributes.bit_gravity = StaticGravity;
2341 xattributes_mask |= CWBitGravity;
2342 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2343 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2344 GDK_WINDOW_XID (window),
2345 CWBitGravity, &xattributes);
2349 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2351 XSetWindowAttributes xattributes;
2353 g_return_if_fail (window != NULL);
2355 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2357 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2358 GDK_WINDOW_XID (window),
2359 CWWinGravity, &xattributes);
2362 /*************************************************************
2363 * gdk_window_set_static_gravities:
2364 * Set the bit gravity of the given window to static,
2365 * and flag it so all children get static subwindow
2368 * window: window for which to set static gravity
2369 * use_static: Whether to turn static gravity on or off.
2371 * Does the XServer support static gravity?
2372 *************************************************************/
2375 gdk_window_set_static_gravities (GdkWindow *window,
2376 gboolean use_static)
2378 GdkWindowObject *private = (GdkWindowObject *)window;
2381 g_return_val_if_fail (window != NULL, FALSE);
2382 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2384 if (!use_static == !private->guffaw_gravity)
2387 if (use_static && !gdk_window_gravity_works ())
2390 private->guffaw_gravity = use_static;
2392 if (!GDK_WINDOW_DESTROYED (window))
2394 gdk_window_set_static_bit_gravity (window, use_static);
2396 tmp_list = private->children;
2399 gdk_window_set_static_win_gravity (window, use_static);
2401 tmp_list = tmp_list->next;
2408 /* internal function created for and used by gdk_window_xid_at_coords */
2410 gdk_window_xid_at (Window base,
2416 gboolean excl_child)
2419 Window *list = NULL;
2420 Window child = 0, parent_win = 0, root_win = 0;
2422 unsigned int ww, wh, wb, wd, num;
2425 xdisplay = GDK_DISPLAY ();
2426 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2433 (x < (int) (wx + ww)) &&
2434 (y < (int) (wy + wh))))
2437 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2442 for (i = num - 1; ; i--)
2444 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2446 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2461 * The following fucntion by The Rasterman <raster@redhat.com>
2462 * This function returns the X Window ID in which the x y location is in
2463 * (x and y being relative to the root window), excluding any windows listed
2464 * in the GList excludes (this is a list of X Window ID's - gpointer being
2467 * This is primarily designed for internal gdk use - for DND for example
2468 * when using a shaped icon window as the drag object - you exclude the
2469 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2470 * You can get back an X Window ID as to what X Window ID is infact under
2471 * those X,Y co-ordinates.
2474 gdk_window_xid_at_coords (gint x,
2477 gboolean excl_child)
2481 Window *list = NULL;
2482 Window root, child = 0, parent_win = 0, root_win = 0;
2486 window = gdk_parent_root;
2487 xdisplay = GDK_WINDOW_XDISPLAY (window);
2488 root = GDK_WINDOW_XID (window);
2489 num = g_list_length (excludes);
2491 XGrabServer (xdisplay);
2492 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2494 XUngrabServer (xdisplay);
2502 XWindowAttributes xwa;
2504 XGetWindowAttributes (xdisplay, list [i], &xwa);
2506 if (xwa.map_state != IsViewable)
2509 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2512 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2517 if (!g_list_find (excludes, (gpointer *) child))
2520 XUngrabServer (xdisplay);
2527 XUngrabServer (xdisplay);
2533 XUngrabServer (xdisplay);