1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
34 #include "gdkwindow.h"
35 #include "gdkinputprivate.h"
36 #include "gdkprivate-x11.h"
37 #include "gdkregion.h"
38 #include "gdkinternals.h"
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);
83 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
84 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
86 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
89 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
90 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
91 static void gdk_window_impl_x11_finalize (GObject *object);
93 static gpointer parent_class = NULL;
96 gdk_window_impl_x11_get_type (void)
98 static GType object_type = 0;
102 static const GTypeInfo object_info =
104 sizeof (GdkWindowImplX11Class),
105 (GBaseInitFunc) NULL,
106 (GBaseFinalizeFunc) NULL,
107 (GClassInitFunc) gdk_window_impl_x11_class_init,
108 NULL, /* class_finalize */
109 NULL, /* class_data */
110 sizeof (GdkWindowImplX11),
112 (GInstanceInitFunc) gdk_window_impl_x11_init,
115 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
124 _gdk_window_impl_get_type (void)
126 return gdk_window_impl_x11_get_type ();
130 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
137 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
139 GObjectClass *object_class = G_OBJECT_CLASS (klass);
140 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
142 parent_class = g_type_class_peek_parent (klass);
144 object_class->finalize = gdk_window_impl_x11_finalize;
146 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
147 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
148 drawable_class->get_size = gdk_window_impl_x11_get_size;
152 gdk_window_impl_x11_finalize (GObject *object)
154 GdkWindowObject *wrapper;
155 GdkDrawableImplX11 *draw_impl;
156 GdkWindowImplX11 *window_impl;
158 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
160 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
161 window_impl = GDK_WINDOW_IMPL_X11 (object);
163 wrapper = (GdkWindowObject*) draw_impl->wrapper;
165 if (!GDK_WINDOW_DESTROYED (wrapper))
167 gdk_xid_table_remove (draw_impl->xid);
170 G_OBJECT_CLASS (parent_class)->finalize (object);
174 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
176 GdkDrawableImplX11 *drawable_impl;
177 GdkWindowImplX11 *window_impl;
179 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
181 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
182 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
184 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
185 drawable_impl->colormap == NULL)
187 XWindowAttributes window_attributes;
189 XGetWindowAttributes (drawable_impl->xdisplay,
192 drawable_impl->colormap =
193 gdk_colormap_lookup (window_attributes.colormap);
196 return drawable_impl->colormap;
200 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
203 GdkWindowImplX11 *impl;
204 GdkDrawableImplX11 *draw_impl;
206 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
207 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
209 impl = GDK_WINDOW_IMPL_X11 (drawable);
210 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
212 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
214 XSetWindowColormap (draw_impl->xdisplay,
216 GDK_COLORMAP_XCOLORMAP (cmap));
218 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
220 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
225 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
229 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
232 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
234 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
238 _gdk_windowing_window_init (void)
240 GdkWindowObject *private;
241 GdkWindowImplX11 *impl;
242 GdkDrawableImplX11 *draw_impl;
243 XWindowAttributes xattributes;
246 unsigned int border_width;
250 g_assert (gdk_parent_root == NULL);
252 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
253 &x, &y, &width, &height, &border_width, &depth);
254 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
256 gdk_parent_root = GDK_WINDOW (g_type_create_instance (GDK_TYPE_WINDOW));
257 private = (GdkWindowObject *)gdk_parent_root;
258 impl = GDK_WINDOW_IMPL_X11 (private->impl);
259 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
261 draw_impl->xdisplay = gdk_display;
262 draw_impl->xid = gdk_root_window;
263 draw_impl->wrapper = GDK_DRAWABLE (private);
265 private->window_type = GDK_WINDOW_ROOT;
266 private->depth = depth;
268 impl->height = height;
270 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
273 static GdkAtom wm_client_leader_atom = GDK_NONE;
276 gdk_window_new (GdkWindow *parent,
277 GdkWindowAttr *attributes,
278 gint attributes_mask)
281 GdkWindowObject *private;
282 GdkWindowObject *parent_private;
283 GdkWindowImplX11 *impl;
284 GdkDrawableImplX11 *draw_impl;
290 XSetWindowAttributes xattributes;
291 long xattributes_mask;
292 XSizeHints size_hints;
294 XClassHint *class_hint;
301 g_return_val_if_fail (attributes != NULL, NULL);
304 parent = gdk_parent_root;
306 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
308 parent_private = (GdkWindowObject*) parent;
309 if (GDK_WINDOW_DESTROYED (parent))
312 xparent = GDK_WINDOW_XID (parent);
314 window = GDK_WINDOW (g_type_create_instance (GDK_TYPE_WINDOW));
315 private = (GdkWindowObject *)window;
316 impl = GDK_WINDOW_IMPL_X11 (private->impl);
317 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
318 draw_impl->wrapper = GDK_DRAWABLE (window);
320 draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
322 private->parent = (GdkWindowObject *)parent;
324 xattributes_mask = 0;
326 if (attributes_mask & GDK_WA_X)
331 if (attributes_mask & GDK_WA_Y)
338 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
339 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
340 private->window_type = attributes->window_type;
342 _gdk_window_init_position (GDK_WINDOW (private));
343 if (impl->position_info.big)
344 private->guffaw_gravity = TRUE;
346 if (attributes_mask & GDK_WA_VISUAL)
347 visual = attributes->visual;
349 visual = gdk_visual_get_system ();
350 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
352 xattributes.event_mask = StructureNotifyMask;
353 for (i = 0; i < gdk_nevent_masks; i++)
355 if (attributes->event_mask & (1 << (i + 1)))
356 xattributes.event_mask |= gdk_event_mask_table[i];
359 if (xattributes.event_mask)
360 xattributes_mask |= CWEventMask;
362 if (attributes_mask & GDK_WA_NOREDIR)
364 xattributes.override_redirect =
365 (attributes->override_redirect == FALSE)?False:True;
366 xattributes_mask |= CWOverrideRedirect;
369 xattributes.override_redirect = False;
371 if (parent_private && parent_private->guffaw_gravity)
373 xattributes.win_gravity = StaticGravity;
374 xattributes_mask |= CWWinGravity;
377 if (attributes->wclass == GDK_INPUT_OUTPUT)
380 depth = visual->depth;
382 private->input_only = FALSE;
383 private->depth = depth;
385 if (attributes_mask & GDK_WA_COLORMAP)
387 draw_impl->colormap = attributes->colormap;
388 gdk_colormap_ref (attributes->colormap);
392 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
394 draw_impl->colormap =
395 gdk_colormap_get_system ();
396 gdk_colormap_ref (draw_impl->colormap);
400 draw_impl->colormap =
401 gdk_colormap_new (visual, FALSE);
405 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
406 xattributes.background_pixel = private->bg_color.pixel;
408 private->bg_pixmap = NULL;
410 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
411 xattributes_mask |= CWBorderPixel | CWBackPixel;
413 if (private->guffaw_gravity)
414 xattributes.bit_gravity = StaticGravity;
416 xattributes.bit_gravity = NorthWestGravity;
418 xattributes_mask |= CWBitGravity;
420 switch (private->window_type)
422 case GDK_WINDOW_TOPLEVEL:
423 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
424 xattributes_mask |= CWColormap;
426 xparent = gdk_root_window;
429 case GDK_WINDOW_CHILD:
430 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
431 xattributes_mask |= CWColormap;
434 case GDK_WINDOW_DIALOG:
435 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
436 xattributes_mask |= CWColormap;
438 xparent = gdk_root_window;
441 case GDK_WINDOW_TEMP:
442 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
443 xattributes_mask |= CWColormap;
445 xparent = gdk_root_window;
447 xattributes.save_under = True;
448 xattributes.override_redirect = True;
449 xattributes.cursor = None;
450 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
452 case GDK_WINDOW_ROOT:
453 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
462 private->input_only = TRUE;
463 draw_impl->colormap = NULL;
466 draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
469 impl->width, impl->height,
470 0, depth, class, xvisual,
471 xattributes_mask, &xattributes);
473 gdk_drawable_ref (window);
474 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
476 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
477 (attributes->cursor) :
481 parent_private->children = g_list_prepend (parent_private->children, window);
483 switch (GDK_WINDOW_TYPE (private))
485 case GDK_WINDOW_DIALOG:
486 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
487 GDK_WINDOW_XID (window),
489 case GDK_WINDOW_TOPLEVEL:
490 case GDK_WINDOW_TEMP:
491 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
492 GDK_WINDOW_XID (window),
493 gdk_wm_window_protocols, 2);
495 case GDK_WINDOW_CHILD:
496 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
497 (draw_impl->colormap != gdk_colormap_get_system ()) &&
498 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
500 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
501 gdk_window_add_colormap_windows (window);
510 size_hints.flags = PSize;
511 size_hints.width = impl->width;
512 size_hints.height = impl->height;
514 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
515 wm_hints.window_group = gdk_leader_window;
516 wm_hints.input = True;
517 wm_hints.initial_state = NormalState;
519 /* FIXME: Is there any point in doing this? Do any WM's pay
520 * attention to PSize, and even if they do, is this the
523 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
524 GDK_WINDOW_XID (window),
527 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
528 GDK_WINDOW_XID (window),
531 if (!wm_client_leader_atom)
532 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
534 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
535 GDK_WINDOW_XID (window),
536 wm_client_leader_atom,
537 XA_WINDOW, 32, PropModeReplace,
538 (guchar*) &gdk_leader_window, 1);
540 if (attributes_mask & GDK_WA_TITLE)
541 title = attributes->title;
543 title = g_get_prgname ();
545 XmbSetWMProperties (GDK_WINDOW_XDISPLAY (window),
546 GDK_WINDOW_XID (window),
551 if (attributes_mask & GDK_WA_WMCLASS)
553 class_hint = XAllocClassHint ();
554 class_hint->res_name = attributes->wmclass_name;
555 class_hint->res_class = attributes->wmclass_class;
556 XSetClassHint (GDK_WINDOW_XDISPLAY (window),
557 GDK_WINDOW_XID (window),
566 gdk_window_foreign_new (GdkNativeWindow anid)
569 GdkWindowObject *private;
570 GdkWindowObject *parent_private;
571 GdkWindowImplX11 *impl;
572 GdkDrawableImplX11 *draw_impl;
573 XWindowAttributes attrs;
575 Window *children = NULL;
579 gdk_error_trap_push ();
580 result = XGetWindowAttributes (gdk_display, anid, &attrs);
581 if (gdk_error_trap_pop () || !result)
584 /* FIXME: This is pretty expensive. Maybe the caller should supply
586 gdk_error_trap_push ();
587 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
588 if (gdk_error_trap_pop () || !result)
594 window = GDK_WINDOW (g_type_create_instance (GDK_TYPE_WINDOW));
595 private = (GdkWindowObject *)window;
596 impl = GDK_WINDOW_IMPL_X11 (private->impl);
597 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
598 draw_impl->wrapper = GDK_DRAWABLE (window);
600 private->parent = gdk_xid_table_lookup (parent);
602 parent_private = (GdkWindowObject *)private->parent;
605 parent_private->children = g_list_prepend (parent_private->children, window);
607 draw_impl->xid = anid;
608 draw_impl->xdisplay = gdk_display;
610 private->x = attrs.x;
611 private->y = attrs.y;
612 impl->width = attrs.width;
613 impl->height = attrs.height;
614 private->window_type = GDK_WINDOW_FOREIGN;
615 private->destroyed = FALSE;
616 private->mapped = (attrs.map_state != IsUnmapped);
617 private->depth = attrs.depth;
619 gdk_drawable_ref (window);
620 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
626 _gdk_windowing_window_destroy (GdkWindow *window,
628 gboolean foreign_destroy)
630 GdkWindowObject *private = (GdkWindowObject *)window;
632 g_return_if_fail (GDK_IS_WINDOW (window));
634 if (private->extension_events != 0)
635 gdk_input_window_destroy (window);
637 if (private->window_type == GDK_WINDOW_FOREIGN)
639 if (!foreign_destroy && (private->parent != NULL))
641 /* It's somebody else's window, but in our heirarchy,
642 * so reparent it to the root window, and then send
643 * it a delete event, as if we were a WM
645 XClientMessageEvent xevent;
647 gdk_error_trap_push ();
648 gdk_window_hide (window);
649 gdk_window_reparent (window, NULL, 0, 0);
651 xevent.type = ClientMessage;
652 xevent.window = GDK_WINDOW_XID (window);
653 xevent.message_type = gdk_wm_protocols;
655 xevent.data.l[0] = gdk_wm_delete_window;
656 xevent.data.l[1] = CurrentTime;
658 XSendEvent (GDK_WINDOW_XDISPLAY (window),
659 GDK_WINDOW_XID (window),
660 False, 0, (XEvent *)&xevent);
662 gdk_error_trap_pop ();
665 else if (!recursing && !foreign_destroy)
666 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
669 /* This function is called when the XWindow is really gone.
672 gdk_window_destroy_notify (GdkWindow *window)
674 g_return_if_fail (window != NULL);
676 if (!GDK_WINDOW_DESTROYED (window))
678 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
679 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
681 _gdk_window_destroy (window, TRUE);
684 gdk_xid_table_remove (GDK_WINDOW_XID (window));
685 gdk_drawable_unref (window);
689 gdk_window_show (GdkWindow *window)
691 GdkWindowObject *private;
693 g_return_if_fail (GDK_IS_WINDOW (window));
695 private = (GdkWindowObject*) window;
696 if (!private->destroyed)
698 private->mapped = TRUE;
699 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
700 GDK_WINDOW_XID (window));
702 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
703 XMapWindow (GDK_WINDOW_XDISPLAY (window),
704 GDK_WINDOW_XID (window));
709 gdk_window_hide (GdkWindow *window)
711 GdkWindowObject *private;
713 g_return_if_fail (window != NULL);
715 private = (GdkWindowObject*) window;
716 if (!private->destroyed)
718 private->mapped = FALSE;
720 _gdk_window_clear_update_area (window);
722 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
723 GDK_WINDOW_XID (window));
728 gdk_window_withdraw (GdkWindow *window)
730 GdkWindowObject *private;
732 g_return_if_fail (window != NULL);
734 private = (GdkWindowObject*) window;
735 if (!private->destroyed)
736 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
737 GDK_WINDOW_XID (window), 0);
741 gdk_window_move (GdkWindow *window,
745 GdkWindowObject *private = (GdkWindowObject *)window;
746 GdkWindowImplX11 *impl;
748 g_return_if_fail (window != NULL);
749 g_return_if_fail (GDK_IS_WINDOW (window));
751 impl = GDK_WINDOW_IMPL_X11 (private->impl);
753 gdk_window_move_resize (window, x, y,
754 impl->width, impl->height);
758 gdk_window_resize (GdkWindow *window,
762 GdkWindowObject *private;
764 g_return_if_fail (window != NULL);
765 g_return_if_fail (GDK_IS_WINDOW (window));
772 private = (GdkWindowObject*) window;
774 if (!GDK_WINDOW_DESTROYED (window))
776 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
777 _gdk_window_move_resize_child (window, private->x, private->y,
781 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
782 GDK_WINDOW_XID (window),
784 private->resize_count += 1;
790 gdk_window_move_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, x, y, width, height);
814 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
815 GDK_WINDOW_XID (window),
816 x, y, width, height);
822 gdk_window_reparent (GdkWindow *window,
823 GdkWindow *new_parent,
827 GdkWindowObject *window_private;
828 GdkWindowObject *parent_private;
829 GdkWindowObject *old_parent_private;
831 g_return_if_fail (window != NULL);
832 g_return_if_fail (GDK_IS_WINDOW (window));
833 g_return_if_fail (new_parent != NULL);
834 g_return_if_fail (GDK_IS_WINDOW (new_parent));
837 new_parent = gdk_parent_root;
839 window_private = (GdkWindowObject*) window;
840 old_parent_private = (GdkWindowObject*)window_private->parent;
841 parent_private = (GdkWindowObject*) new_parent;
843 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
844 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
845 GDK_WINDOW_XID (window),
846 GDK_WINDOW_XID (new_parent),
849 window_private->parent = (GdkWindowObject *)new_parent;
851 if (old_parent_private)
852 old_parent_private->children = g_list_remove (old_parent_private->children, window);
854 if ((old_parent_private &&
855 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
856 (!old_parent_private && parent_private->guffaw_gravity))
857 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
859 parent_private->children = g_list_prepend (parent_private->children, window);
863 _gdk_windowing_window_clear_area (GdkWindow *window,
869 g_return_if_fail (window != NULL);
870 g_return_if_fail (GDK_IS_WINDOW (window));
872 if (!GDK_WINDOW_DESTROYED (window))
873 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
874 x, y, width, height, False);
878 _gdk_windowing_window_clear_area_e (GdkWindow *window,
884 g_return_if_fail (window != NULL);
885 g_return_if_fail (GDK_IS_WINDOW (window));
887 if (!GDK_WINDOW_DESTROYED (window))
888 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
889 x, y, width, height, True);
893 gdk_window_raise (GdkWindow *window)
895 g_return_if_fail (window != NULL);
896 g_return_if_fail (GDK_IS_WINDOW (window));
898 if (!GDK_WINDOW_DESTROYED (window))
899 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
903 gdk_window_lower (GdkWindow *window)
905 g_return_if_fail (window != NULL);
906 g_return_if_fail (GDK_IS_WINDOW (window));
908 if (!GDK_WINDOW_DESTROYED (window))
909 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
913 gdk_window_set_hints (GdkWindow *window,
922 XSizeHints size_hints;
924 g_return_if_fail (window != NULL);
925 g_return_if_fail (GDK_IS_WINDOW (window));
927 if (GDK_WINDOW_DESTROYED (window))
930 size_hints.flags = 0;
932 if (flags & GDK_HINT_POS)
934 size_hints.flags |= PPosition;
939 if (flags & GDK_HINT_MIN_SIZE)
941 size_hints.flags |= PMinSize;
942 size_hints.min_width = min_width;
943 size_hints.min_height = min_height;
946 if (flags & GDK_HINT_MAX_SIZE)
948 size_hints.flags |= PMaxSize;
949 size_hints.max_width = max_width;
950 size_hints.max_height = max_height;
953 /* FIXME: Would it be better to delete this property of
954 * flags == 0? It would save space on the server
956 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
957 GDK_WINDOW_XID (window),
962 gdk_window_set_geometry_hints (GdkWindow *window,
963 GdkGeometry *geometry,
964 GdkWindowHints geom_mask)
966 XSizeHints size_hints;
968 g_return_if_fail (window != NULL);
969 g_return_if_fail (GDK_IS_WINDOW (window));
971 if (GDK_WINDOW_DESTROYED (window))
974 size_hints.flags = 0;
976 if (geom_mask & GDK_HINT_POS)
978 size_hints.flags |= PPosition;
979 /* We need to initialize the following obsolete fields because KWM
980 * apparently uses these fields if they are non-zero.
987 if (geom_mask & GDK_HINT_MIN_SIZE)
989 size_hints.flags |= PMinSize;
990 size_hints.min_width = geometry->min_width;
991 size_hints.min_height = geometry->min_height;
994 if (geom_mask & GDK_HINT_MAX_SIZE)
996 size_hints.flags |= PMaxSize;
997 size_hints.max_width = MAX (geometry->max_width, 1);
998 size_hints.max_height = MAX (geometry->max_height, 1);
1001 if (geom_mask & GDK_HINT_BASE_SIZE)
1003 size_hints.flags |= PBaseSize;
1004 size_hints.base_width = geometry->base_width;
1005 size_hints.base_height = geometry->base_height;
1008 if (geom_mask & GDK_HINT_RESIZE_INC)
1010 size_hints.flags |= PResizeInc;
1011 size_hints.width_inc = geometry->width_inc;
1012 size_hints.height_inc = geometry->height_inc;
1015 if (geom_mask & GDK_HINT_ASPECT)
1017 size_hints.flags |= PAspect;
1018 if (geometry->min_aspect <= 1)
1020 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1021 size_hints.min_aspect.y = 65536;
1025 size_hints.min_aspect.x = 65536;
1026 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1028 if (geometry->max_aspect <= 1)
1030 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1031 size_hints.max_aspect.y = 65536;
1035 size_hints.max_aspect.x = 65536;
1036 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1040 /* FIXME: Would it be better to delete this property of
1041 * geom_mask == 0? It would save space on the server
1043 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1044 GDK_WINDOW_XID (window),
1049 gdk_window_set_title (GdkWindow *window,
1052 g_return_if_fail (window != NULL);
1053 g_return_if_fail (GDK_IS_WINDOW (window));
1055 if (!GDK_WINDOW_DESTROYED (window))
1056 XmbSetWMProperties (GDK_WINDOW_XDISPLAY (window),
1057 GDK_WINDOW_XID (window),
1058 title, title, NULL, 0, NULL, NULL, NULL);
1062 gdk_window_set_role (GdkWindow *window,
1065 g_return_if_fail (window != NULL);
1066 g_return_if_fail (GDK_IS_WINDOW (window));
1068 if (!GDK_WINDOW_DESTROYED (window))
1071 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1072 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1073 8, PropModeReplace, role, strlen (role));
1075 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1076 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1081 gdk_window_set_transient_for (GdkWindow *window,
1084 GdkWindowObject *private;
1085 GdkWindowObject *parent_private;
1087 g_return_if_fail (window != NULL);
1088 g_return_if_fail (GDK_IS_WINDOW (window));
1090 private = (GdkWindowObject*) window;
1091 parent_private = (GdkWindowObject*) parent;
1093 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1094 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1095 GDK_WINDOW_XID (window),
1096 GDK_WINDOW_XID (parent));
1100 gdk_window_set_background (GdkWindow *window,
1103 GdkWindowObject *private = (GdkWindowObject *)window;
1105 g_return_if_fail (window != NULL);
1106 g_return_if_fail (GDK_IS_WINDOW (window));
1108 if (!GDK_WINDOW_DESTROYED (window))
1109 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1110 GDK_WINDOW_XID (window), color->pixel);
1112 private->bg_color = *color;
1114 if (private->bg_pixmap &&
1115 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1116 private->bg_pixmap != GDK_NO_BG)
1118 gdk_pixmap_unref (private->bg_pixmap);
1119 private->bg_pixmap = NULL;
1124 gdk_window_set_back_pixmap (GdkWindow *window,
1126 gboolean parent_relative)
1128 GdkWindowObject *private = (GdkWindowObject *)window;
1131 g_return_if_fail (window != NULL);
1132 g_return_if_fail (GDK_IS_WINDOW (window));
1133 g_return_if_fail (pixmap == NULL || !parent_relative);
1135 if (private->bg_pixmap &&
1136 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1137 private->bg_pixmap != GDK_NO_BG)
1138 gdk_pixmap_unref (private->bg_pixmap);
1140 if (parent_relative)
1142 xpixmap = ParentRelative;
1143 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1149 gdk_pixmap_ref (pixmap);
1150 private->bg_pixmap = pixmap;
1151 xpixmap = GDK_PIXMAP_XID (pixmap);
1156 private->bg_pixmap = GDK_NO_BG;
1160 if (!GDK_WINDOW_DESTROYED (window))
1161 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1162 GDK_WINDOW_XID (window), xpixmap);
1166 gdk_window_set_cursor (GdkWindow *window,
1169 GdkCursorPrivate *cursor_private;
1172 g_return_if_fail (window != NULL);
1173 g_return_if_fail (GDK_IS_WINDOW (window));
1175 cursor_private = (GdkCursorPrivate*) cursor;
1180 xcursor = cursor_private->xcursor;
1182 if (!GDK_WINDOW_DESTROYED (window))
1183 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1184 GDK_WINDOW_XID (window),
1189 gdk_window_get_geometry (GdkWindow *window,
1201 guint tborder_width;
1204 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1207 window = gdk_parent_root;
1209 if (!GDK_WINDOW_DESTROYED (window))
1211 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1212 GDK_WINDOW_XID (window),
1213 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1229 gdk_window_get_origin (GdkWindow *window,
1238 g_return_val_if_fail (window != NULL, 0);
1240 if (!GDK_WINDOW_DESTROYED (window))
1242 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1243 GDK_WINDOW_XID (window),
1261 gdk_window_get_deskrelative_origin (GdkWindow *window,
1265 gboolean return_val = FALSE;
1266 gint num_children, format_return;
1267 Window win, *child, parent, root;
1271 static Atom atom = 0;
1272 gulong number_return, bytes_after_return;
1273 guchar *data_return;
1275 g_return_val_if_fail (window != NULL, 0);
1276 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1278 if (!GDK_WINDOW_DESTROYED (window))
1281 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1282 win = GDK_WINDOW_XID (window);
1284 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1285 &child, (unsigned int *)&num_children))
1287 if ((child) && (num_children > 0))
1299 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1300 False, XA_CARDINAL, &type_return, &format_return,
1301 &number_return, &bytes_after_return, &data_return);
1302 if (type_return == XA_CARDINAL)
1304 XFree (data_return);
1309 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1310 GDK_WINDOW_XID (window),
1325 gdk_window_get_root_origin (GdkWindow *window,
1329 GdkWindowObject *private;
1334 unsigned int nchildren;
1336 g_return_if_fail (window != NULL);
1337 g_return_if_fail (GDK_IS_WINDOW (window));
1339 private = (GdkWindowObject*) window;
1345 if (GDK_WINDOW_DESTROYED (window))
1348 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1349 private = (GdkWindowObject*) private->parent;
1350 if (GDK_WINDOW_DESTROYED (window))
1353 xparent = GDK_WINDOW_XID (window);
1357 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1359 &children, &nchildren))
1365 while (xparent != root);
1367 if (xparent == root)
1369 unsigned int ww, wh, wb, wd;
1372 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1383 gdk_window_get_pointer (GdkWindow *window,
1386 GdkModifierType *mask)
1388 GdkWindow *return_val;
1394 unsigned int xmask = 0;
1395 gint xoffset, yoffset;
1397 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1400 window = gdk_parent_root;
1402 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1405 if (!GDK_WINDOW_DESTROYED (window) &&
1406 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1407 GDK_WINDOW_XID (window),
1408 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1411 return_val = gdk_window_lookup (child);
1415 *x = winx + xoffset;
1417 *y = winy + yoffset;
1425 gdk_window_at_pointer (gint *win_x,
1431 Window xwindow_last = 0;
1433 int rootx = -1, rooty = -1;
1437 xwindow = GDK_ROOT_WINDOW ();
1438 xdisplay = GDK_DISPLAY ();
1440 XGrabServer (xdisplay);
1443 xwindow_last = xwindow;
1444 XQueryPointer (xdisplay, xwindow,
1450 XUngrabServer (xdisplay);
1452 window = gdk_window_lookup (xwindow_last);
1455 *win_x = window ? winx : -1;
1457 *win_y = window ? winy : -1;
1463 gdk_window_get_events (GdkWindow *window)
1465 XWindowAttributes attrs;
1466 GdkEventMask event_mask;
1469 g_return_val_if_fail (window != NULL, 0);
1470 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1472 if (GDK_WINDOW_DESTROYED (window))
1476 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1477 GDK_WINDOW_XID (window),
1481 for (i = 0; i < gdk_nevent_masks; i++)
1483 if (attrs.your_event_mask & gdk_event_mask_table[i])
1484 event_mask |= 1 << (i + 1);
1492 gdk_window_set_events (GdkWindow *window,
1493 GdkEventMask event_mask)
1498 g_return_if_fail (window != NULL);
1499 g_return_if_fail (GDK_IS_WINDOW (window));
1501 if (!GDK_WINDOW_DESTROYED (window))
1503 xevent_mask = StructureNotifyMask;
1504 for (i = 0; i < gdk_nevent_masks; i++)
1506 if (event_mask & (1 << (i + 1)))
1507 xevent_mask |= gdk_event_mask_table[i];
1510 XSelectInput (GDK_WINDOW_XDISPLAY (window),
1511 GDK_WINDOW_XID (window),
1517 gdk_window_add_colormap_windows (GdkWindow *window)
1519 GdkWindow *toplevel;
1520 Window *old_windows;
1521 Window *new_windows;
1524 g_return_if_fail (window != NULL);
1525 g_return_if_fail (GDK_IS_WINDOW (window));
1527 toplevel = gdk_window_get_toplevel (window);
1528 if (GDK_WINDOW_DESTROYED (toplevel))
1532 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1533 GDK_WINDOW_XID (toplevel),
1534 &old_windows, &count))
1539 for (i = 0; i < count; i++)
1540 if (old_windows[i] == GDK_WINDOW_XID (window))
1542 XFree (old_windows);
1546 new_windows = g_new (Window, count + 1);
1548 for (i = 0; i < count; i++)
1549 new_windows[i] = old_windows[i];
1550 new_windows[count] = GDK_WINDOW_XID (window);
1552 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1553 GDK_WINDOW_XID (toplevel),
1554 new_windows, count + 1);
1556 g_free (new_windows);
1558 XFree (old_windows);
1562 gdk_window_have_shape_ext (void)
1564 enum { UNKNOWN, NO, YES };
1565 static gint have_shape = UNKNOWN;
1567 if (have_shape == UNKNOWN)
1570 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1576 return (have_shape == YES);
1580 * This needs the X11 shape extension.
1581 * If not available, shaped windows will look
1582 * ugly, but programs still work. Stefan Wille
1585 gdk_window_shape_combine_mask (GdkWindow *window,
1591 g_return_if_fail (window != NULL);
1592 g_return_if_fail (GDK_IS_WINDOW (window));
1594 #ifdef HAVE_SHAPE_EXT
1595 if (GDK_WINDOW_DESTROYED (window))
1598 if (gdk_window_have_shape_ext ())
1602 pixmap = GDK_PIXMAP_XID (mask);
1611 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
1612 GDK_WINDOW_XID (window),
1618 #endif /* HAVE_SHAPE_EXT */
1622 gdk_window_set_override_redirect (GdkWindow *window,
1623 gboolean override_redirect)
1625 XSetWindowAttributes attr;
1627 g_return_if_fail (window != NULL);
1628 g_return_if_fail (GDK_IS_WINDOW (window));
1630 if (GDK_WINDOW_DESTROYED (window))
1632 attr.override_redirect = (override_redirect == FALSE)?False:True;
1633 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1634 GDK_WINDOW_XID (window),
1641 gdk_window_set_icon (GdkWindow *window,
1642 GdkWindow *icon_window,
1648 g_return_if_fail (window != NULL);
1649 g_return_if_fail (GDK_IS_WINDOW (window));
1651 if (GDK_WINDOW_DESTROYED (window))
1654 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1655 GDK_WINDOW_XID (window));
1657 wm_hints = XAllocWMHints ();
1659 if (icon_window != NULL)
1661 wm_hints->flags |= IconWindowHint;
1662 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
1667 wm_hints->flags |= IconPixmapHint;
1668 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
1673 wm_hints->flags |= IconMaskHint;
1674 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
1677 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1678 GDK_WINDOW_XID (window), wm_hints);
1683 gdk_window_set_icon_name (GdkWindow *window,
1686 XTextProperty property;
1689 g_return_if_fail (window != NULL);
1690 g_return_if_fail (GDK_IS_WINDOW (window));
1692 if (GDK_WINDOW_DESTROYED (window))
1695 res = XmbTextListToTextProperty (GDK_WINDOW_XDISPLAY (window),
1696 &name, 1, XStdICCTextStyle,
1700 g_warning ("Error converting icon name to text property: %d\n", res);
1704 XSetWMIconName (GDK_WINDOW_XDISPLAY (window),
1705 GDK_WINDOW_XID (window),
1709 XFree (property.value);
1713 gdk_window_set_group (GdkWindow *window,
1718 g_return_if_fail (window != NULL);
1719 g_return_if_fail (GDK_IS_WINDOW (window));
1720 g_return_if_fail (leader != NULL);
1721 g_return_if_fail (GDK_IS_WINDOW (leader));
1723 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1726 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1727 GDK_WINDOW_XID (window));
1729 wm_hints = XAllocWMHints ();
1731 wm_hints->flags |= WindowGroupHint;
1732 wm_hints->window_group = GDK_WINDOW_XID (leader);
1734 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1735 GDK_WINDOW_XID (window), wm_hints);
1740 gdk_window_set_mwm_hints (GdkWindow *window,
1741 MotifWmHints *new_hints)
1743 static Atom hints_atom = None;
1744 MotifWmHints *hints;
1750 if (GDK_WINDOW_DESTROYED (window))
1754 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
1755 _XA_MOTIF_WM_HINTS, FALSE);
1757 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1758 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1759 False, AnyPropertyType, &type, &format, &nitems,
1760 &bytes_after, (guchar **)&hints);
1766 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1768 hints->flags |= MWM_HINTS_FUNCTIONS;
1769 hints->functions = new_hints->functions;
1771 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1773 hints->flags |= MWM_HINTS_DECORATIONS;
1774 hints->decorations = new_hints->decorations;
1778 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1779 hints_atom, hints_atom, 32, PropModeReplace,
1780 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1782 if (hints != new_hints)
1787 gdk_window_set_decorations (GdkWindow *window,
1788 GdkWMDecoration decorations)
1792 g_return_if_fail (window != NULL);
1793 g_return_if_fail (GDK_IS_WINDOW (window));
1795 hints.flags = MWM_HINTS_DECORATIONS;
1796 hints.decorations = decorations;
1798 gdk_window_set_mwm_hints (window, &hints);
1802 gdk_window_set_functions (GdkWindow *window,
1803 GdkWMFunction functions)
1807 g_return_if_fail (window != NULL);
1808 g_return_if_fail (GDK_IS_WINDOW (window));
1810 hints.flags = MWM_HINTS_FUNCTIONS;
1811 hints.functions = functions;
1813 gdk_window_set_mwm_hints (window, &hints);
1817 * propagate the shapes from all child windows of a GDK window to the parent
1818 * window. Shamelessly ripped from Enlightenment's code
1826 struct _gdk_span *next;
1830 gdk_add_to_span (struct _gdk_span **s,
1834 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1841 /* scan the spans for this line */
1844 /* -- -> new span */
1845 /* == -> existing span */
1846 /* ## -> spans intersect */
1847 /* if we are in the middle of spanning the span into the line */
1850 /* case: ---- ==== */
1851 if (xx < ptr1->start - 1)
1853 /* ends before next span - extend to here */
1857 /* case: ----##=== */
1858 else if (xx <= ptr1->end)
1860 /* crosses into next span - delete next span and append */
1861 ss->end = ptr1->end;
1862 ss->next = ptr1->next;
1866 /* case: ---###--- */
1869 /* overlaps next span - delete and keep checking */
1870 ss->next = ptr1->next;
1875 /* otherwise havent started spanning it in yet */
1878 /* case: ---- ==== */
1879 if (xx < ptr1->start - 1)
1881 /* insert span here in list */
1882 noo = g_malloc (sizeof (struct _gdk_span));
1896 /* case: ----##=== */
1897 else if ((x < ptr1->start) && (xx <= ptr1->end))
1899 /* expand this span to the left point of the new one */
1903 /* case: ===###=== */
1904 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1906 /* throw the span away */
1909 /* case: ---###--- */
1910 else if ((x < ptr1->start) && (xx > ptr1->end))
1917 /* case: ===##---- */
1918 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
1924 /* case: ==== ---- */
1925 /* case handled by next loop iteration - first case */
1930 /* it started in the middle but spans beyond your current list */
1936 /* it does not start inside a span or in the middle, so add it to the end */
1937 noo = g_malloc (sizeof (struct _gdk_span));
1945 noo->next = ptr2->next;
1958 gdk_add_rectangles (Display *disp,
1960 struct _gdk_span **spans,
1967 gint x1, y1, x2, y2;
1971 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
1974 /* go through all clip rects in this window's shape */
1975 for (k = 0; k < rn; k++)
1977 /* for each clip rect, add it to each line's spans */
1979 x2 = x + rl[k].x + (rl[k].width - 1);
1981 y2 = y + rl[k].y + (rl[k].height - 1);
1990 for (a = y1; a <= y2; a++)
1993 gdk_add_to_span (&spans[a], x1, x2);
2001 gdk_propagate_shapes (Display *disp,
2005 Window rt, par, *list = NULL;
2006 gint i, j, num = 0, num_rects = 0;
2010 XRectangle *rects = NULL;
2011 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2012 XWindowAttributes xatt;
2014 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2019 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2021 for (i = 0; i < h; i++)
2023 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2026 /* go through all child windows and create/insert spans */
2027 for (i = 0; i < num; i++)
2029 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2030 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2031 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2034 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2036 /* go through the spans list and build a list of rects */
2037 rects = g_malloc (sizeof (XRectangle) * 256);
2039 for (i = 0; i < baseh; i++)
2042 /* go through the line for all spans */
2045 rects[num_rects].x = ptr1->start;
2046 rects[num_rects].y = i;
2047 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2048 rects[num_rects].height = 1;
2050 /* if there are more lines */
2052 /* while contigous rects (same start/end coords) exist */
2053 while ((contig) && (j < baseh))
2055 /* search next line for spans matching this one */
2061 /* if we have an exact span match set contig */
2062 if ((ptr2->start == ptr1->start) &&
2063 (ptr2->end == ptr1->end))
2066 /* remove the span - not needed */
2069 ptr3->next = ptr2->next;
2075 spans[j] = ptr2->next;
2081 /* gone past the span point no point looking */
2082 else if (ptr2->start < ptr1->start)
2090 /* if a contiguous span was found increase the rect h */
2093 rects[num_rects].height++;
2097 /* up the rect count */
2099 /* every 256 new rects increase the rect array */
2100 if ((num_rects % 256) == 0)
2101 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2105 /* set the rects as the shape mask */
2108 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2109 ShapeSet, YXSorted);
2114 /* free up all the spans we made */
2115 for (i = 0; i < baseh; i++)
2129 gdk_window_set_child_shapes (GdkWindow *window)
2131 g_return_if_fail (window != NULL);
2132 g_return_if_fail (GDK_IS_WINDOW (window));
2134 #ifdef HAVE_SHAPE_EXT
2135 if (!GDK_WINDOW_DESTROYED (window) &&
2136 gdk_window_have_shape_ext ())
2137 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2138 GDK_WINDOW_XID (window), FALSE);
2143 gdk_window_merge_child_shapes (GdkWindow *window)
2145 g_return_if_fail (window != NULL);
2146 g_return_if_fail (GDK_IS_WINDOW (window));
2148 #ifdef HAVE_SHAPE_EXT
2149 if (!GDK_WINDOW_DESTROYED (window) &&
2150 gdk_window_have_shape_ext ())
2151 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2152 GDK_WINDOW_XID (window), TRUE);
2156 /* Support for windows that can be guffaw-scrolled
2157 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2161 gdk_window_gravity_works (void)
2163 enum { UNKNOWN, NO, YES };
2164 static gint gravity_works = UNKNOWN;
2166 if (gravity_works == UNKNOWN)
2173 /* This particular server apparently has a bug so that the test
2174 * works but the actual code crashes it
2176 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2177 (VendorRelease (gdk_display) == 3400))
2183 attr.window_type = GDK_WINDOW_TEMP;
2184 attr.wclass = GDK_INPUT_OUTPUT;
2189 attr.event_mask = 0;
2191 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2193 attr.window_type = GDK_WINDOW_CHILD;
2194 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2196 gdk_window_set_static_win_gravity (child, TRUE);
2198 gdk_window_resize (parent, 100, 110);
2199 gdk_window_move (parent, 0, -10);
2200 gdk_window_move_resize (parent, 0, 0, 100, 100);
2202 gdk_window_resize (parent, 100, 110);
2203 gdk_window_move (parent, 0, -10);
2204 gdk_window_move_resize (parent, 0, 0, 100, 100);
2206 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2208 gdk_window_destroy (parent);
2209 gdk_window_destroy (child);
2211 gravity_works = ((y == -20) ? YES : NO);
2214 return (gravity_works == YES);
2218 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2220 XSetWindowAttributes xattributes;
2221 guint xattributes_mask = 0;
2223 g_return_if_fail (window != NULL);
2225 xattributes.bit_gravity = StaticGravity;
2226 xattributes_mask |= CWBitGravity;
2227 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2228 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2229 GDK_WINDOW_XID (window),
2230 CWBitGravity, &xattributes);
2234 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2236 XSetWindowAttributes xattributes;
2238 g_return_if_fail (window != NULL);
2240 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2242 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2243 GDK_WINDOW_XID (window),
2244 CWWinGravity, &xattributes);
2247 /*************************************************************
2248 * gdk_window_set_static_gravities:
2249 * Set the bit gravity of the given window to static,
2250 * and flag it so all children get static subwindow
2253 * window: window for which to set static gravity
2254 * use_static: Whether to turn static gravity on or off.
2256 * Does the XServer support static gravity?
2257 *************************************************************/
2260 gdk_window_set_static_gravities (GdkWindow *window,
2261 gboolean use_static)
2263 GdkWindowObject *private = (GdkWindowObject *)window;
2266 g_return_val_if_fail (window != NULL, FALSE);
2267 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2269 if (!use_static == !private->guffaw_gravity)
2272 if (use_static && !gdk_window_gravity_works ())
2275 private->guffaw_gravity = use_static;
2277 if (!GDK_WINDOW_DESTROYED (window))
2279 gdk_window_set_static_bit_gravity (window, use_static);
2281 tmp_list = private->children;
2284 gdk_window_set_static_win_gravity (window, use_static);
2286 tmp_list = tmp_list->next;
2293 /* internal function created for and used by gdk_window_xid_at_coords */
2295 gdk_window_xid_at (Window base,
2301 gboolean excl_child)
2304 Window *list = NULL;
2305 Window child = 0, parent_win = 0, root_win = 0;
2307 unsigned int ww, wh, wb, wd, num;
2310 xdisplay = GDK_DISPLAY ();
2311 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2318 (x < (int) (wx + ww)) &&
2319 (y < (int) (wy + wh))))
2322 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2327 for (i = num - 1; ; i--)
2329 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2331 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2346 * The following fucntion by The Rasterman <raster@redhat.com>
2347 * This function returns the X Window ID in which the x y location is in
2348 * (x and y being relative to the root window), excluding any windows listed
2349 * in the GList excludes (this is a list of X Window ID's - gpointer being
2352 * This is primarily designed for internal gdk use - for DND for example
2353 * when using a shaped icon window as the drag object - you exclude the
2354 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2355 * You can get back an X Window ID as to what X Window ID is infact under
2356 * those X,Y co-ordinates.
2359 gdk_window_xid_at_coords (gint x,
2362 gboolean excl_child)
2366 Window *list = NULL;
2367 Window root, child = 0, parent_win = 0, root_win = 0;
2371 window = gdk_parent_root;
2372 xdisplay = GDK_WINDOW_XDISPLAY (window);
2373 root = GDK_WINDOW_XID (window);
2374 num = g_list_length (excludes);
2376 XGrabServer (xdisplay);
2377 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2379 XUngrabServer (xdisplay);
2387 XWindowAttributes xwa;
2389 XGetWindowAttributes (xdisplay, list [i], &xwa);
2391 if (xwa.map_state != IsViewable)
2394 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2397 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2402 if (!g_list_find (excludes, (gpointer *) child))
2405 XUngrabServer (xdisplay);
2412 XUngrabServer (xdisplay);
2418 XUngrabServer (xdisplay);