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);
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 = g_object_new (GDK_TYPE_WINDOW, NULL);
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 = g_object_new (GDK_TYPE_WINDOW, NULL);
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),
468 impl->position_info.x, impl->position_info.y,
469 impl->position_info.width, impl->position_info.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 = g_object_new (GDK_TYPE_WINDOW, NULL);
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 if (!GDK_WINDOW_DESTROYED (window))
755 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
756 _gdk_window_move_resize_child (window, x, y,
757 impl->width, impl->height);
760 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
761 GDK_WINDOW_XID (window),
768 gdk_window_resize (GdkWindow *window,
772 GdkWindowObject *private;
774 g_return_if_fail (window != NULL);
775 g_return_if_fail (GDK_IS_WINDOW (window));
782 private = (GdkWindowObject*) window;
784 if (!GDK_WINDOW_DESTROYED (window))
786 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
787 _gdk_window_move_resize_child (window, private->x, private->y,
791 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
792 GDK_WINDOW_XID (window),
794 private->resize_count += 1;
800 gdk_window_move_resize (GdkWindow *window,
806 GdkWindowObject *private;
808 g_return_if_fail (window != NULL);
809 g_return_if_fail (GDK_IS_WINDOW (window));
816 private = (GdkWindowObject*) window;
818 if (!GDK_WINDOW_DESTROYED (window))
820 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
821 _gdk_window_move_resize_child (window, x, y, width, height);
824 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
825 GDK_WINDOW_XID (window),
826 x, y, width, height);
827 private->resize_count += 1;
833 gdk_window_reparent (GdkWindow *window,
834 GdkWindow *new_parent,
838 GdkWindowObject *window_private;
839 GdkWindowObject *parent_private;
840 GdkWindowObject *old_parent_private;
842 g_return_if_fail (window != NULL);
843 g_return_if_fail (GDK_IS_WINDOW (window));
844 g_return_if_fail (new_parent != NULL);
845 g_return_if_fail (GDK_IS_WINDOW (new_parent));
848 new_parent = gdk_parent_root;
850 window_private = (GdkWindowObject*) window;
851 old_parent_private = (GdkWindowObject*)window_private->parent;
852 parent_private = (GdkWindowObject*) new_parent;
854 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
855 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
856 GDK_WINDOW_XID (window),
857 GDK_WINDOW_XID (new_parent),
860 window_private->parent = (GdkWindowObject *)new_parent;
862 if (old_parent_private)
863 old_parent_private->children = g_list_remove (old_parent_private->children, window);
865 if ((old_parent_private &&
866 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
867 (!old_parent_private && parent_private->guffaw_gravity))
868 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
870 parent_private->children = g_list_prepend (parent_private->children, window);
874 _gdk_windowing_window_clear_area (GdkWindow *window,
880 g_return_if_fail (window != NULL);
881 g_return_if_fail (GDK_IS_WINDOW (window));
883 if (!GDK_WINDOW_DESTROYED (window))
884 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
885 x, y, width, height, False);
889 _gdk_windowing_window_clear_area_e (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 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
900 x, y, width, height, True);
904 gdk_window_raise (GdkWindow *window)
906 g_return_if_fail (window != NULL);
907 g_return_if_fail (GDK_IS_WINDOW (window));
909 if (!GDK_WINDOW_DESTROYED (window))
910 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
914 gdk_window_lower (GdkWindow *window)
916 g_return_if_fail (window != NULL);
917 g_return_if_fail (GDK_IS_WINDOW (window));
919 if (!GDK_WINDOW_DESTROYED (window))
920 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
924 gdk_window_set_hints (GdkWindow *window,
933 XSizeHints size_hints;
935 g_return_if_fail (window != NULL);
936 g_return_if_fail (GDK_IS_WINDOW (window));
938 if (GDK_WINDOW_DESTROYED (window))
941 size_hints.flags = 0;
943 if (flags & GDK_HINT_POS)
945 size_hints.flags |= PPosition;
950 if (flags & GDK_HINT_MIN_SIZE)
952 size_hints.flags |= PMinSize;
953 size_hints.min_width = min_width;
954 size_hints.min_height = min_height;
957 if (flags & GDK_HINT_MAX_SIZE)
959 size_hints.flags |= PMaxSize;
960 size_hints.max_width = max_width;
961 size_hints.max_height = max_height;
964 /* FIXME: Would it be better to delete this property of
965 * flags == 0? It would save space on the server
967 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
968 GDK_WINDOW_XID (window),
973 gdk_window_set_geometry_hints (GdkWindow *window,
974 GdkGeometry *geometry,
975 GdkWindowHints geom_mask)
977 XSizeHints size_hints;
979 g_return_if_fail (window != NULL);
980 g_return_if_fail (GDK_IS_WINDOW (window));
982 if (GDK_WINDOW_DESTROYED (window))
985 size_hints.flags = 0;
987 if (geom_mask & GDK_HINT_POS)
989 size_hints.flags |= PPosition;
990 /* We need to initialize the following obsolete fields because KWM
991 * apparently uses these fields if they are non-zero.
998 if (geom_mask & GDK_HINT_MIN_SIZE)
1000 size_hints.flags |= PMinSize;
1001 size_hints.min_width = geometry->min_width;
1002 size_hints.min_height = geometry->min_height;
1005 if (geom_mask & GDK_HINT_MAX_SIZE)
1007 size_hints.flags |= PMaxSize;
1008 size_hints.max_width = MAX (geometry->max_width, 1);
1009 size_hints.max_height = MAX (geometry->max_height, 1);
1012 if (geom_mask & GDK_HINT_BASE_SIZE)
1014 size_hints.flags |= PBaseSize;
1015 size_hints.base_width = geometry->base_width;
1016 size_hints.base_height = geometry->base_height;
1019 if (geom_mask & GDK_HINT_RESIZE_INC)
1021 size_hints.flags |= PResizeInc;
1022 size_hints.width_inc = geometry->width_inc;
1023 size_hints.height_inc = geometry->height_inc;
1026 if (geom_mask & GDK_HINT_ASPECT)
1028 size_hints.flags |= PAspect;
1029 if (geometry->min_aspect <= 1)
1031 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1032 size_hints.min_aspect.y = 65536;
1036 size_hints.min_aspect.x = 65536;
1037 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1039 if (geometry->max_aspect <= 1)
1041 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1042 size_hints.max_aspect.y = 65536;
1046 size_hints.max_aspect.x = 65536;
1047 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1051 /* FIXME: Would it be better to delete this property of
1052 * geom_mask == 0? It would save space on the server
1054 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1055 GDK_WINDOW_XID (window),
1060 gdk_window_set_title (GdkWindow *window,
1063 g_return_if_fail (window != NULL);
1064 g_return_if_fail (GDK_IS_WINDOW (window));
1066 if (!GDK_WINDOW_DESTROYED (window))
1067 XmbSetWMProperties (GDK_WINDOW_XDISPLAY (window),
1068 GDK_WINDOW_XID (window),
1069 title, title, NULL, 0, NULL, NULL, NULL);
1073 gdk_window_set_role (GdkWindow *window,
1076 g_return_if_fail (window != NULL);
1077 g_return_if_fail (GDK_IS_WINDOW (window));
1079 if (!GDK_WINDOW_DESTROYED (window))
1082 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1083 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1084 8, PropModeReplace, role, strlen (role));
1086 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1087 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1092 gdk_window_set_transient_for (GdkWindow *window,
1095 GdkWindowObject *private;
1096 GdkWindowObject *parent_private;
1098 g_return_if_fail (window != NULL);
1099 g_return_if_fail (GDK_IS_WINDOW (window));
1101 private = (GdkWindowObject*) window;
1102 parent_private = (GdkWindowObject*) parent;
1104 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1105 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1106 GDK_WINDOW_XID (window),
1107 GDK_WINDOW_XID (parent));
1111 gdk_window_set_background (GdkWindow *window,
1114 GdkWindowObject *private = (GdkWindowObject *)window;
1116 g_return_if_fail (window != NULL);
1117 g_return_if_fail (GDK_IS_WINDOW (window));
1119 if (!GDK_WINDOW_DESTROYED (window))
1120 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1121 GDK_WINDOW_XID (window), color->pixel);
1123 private->bg_color = *color;
1125 if (private->bg_pixmap &&
1126 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1127 private->bg_pixmap != GDK_NO_BG)
1129 gdk_pixmap_unref (private->bg_pixmap);
1130 private->bg_pixmap = NULL;
1135 gdk_window_set_back_pixmap (GdkWindow *window,
1137 gboolean parent_relative)
1139 GdkWindowObject *private = (GdkWindowObject *)window;
1142 g_return_if_fail (window != NULL);
1143 g_return_if_fail (GDK_IS_WINDOW (window));
1144 g_return_if_fail (pixmap == NULL || !parent_relative);
1146 if (private->bg_pixmap &&
1147 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1148 private->bg_pixmap != GDK_NO_BG)
1149 gdk_pixmap_unref (private->bg_pixmap);
1151 if (parent_relative)
1153 xpixmap = ParentRelative;
1154 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1160 gdk_pixmap_ref (pixmap);
1161 private->bg_pixmap = pixmap;
1162 xpixmap = GDK_PIXMAP_XID (pixmap);
1167 private->bg_pixmap = GDK_NO_BG;
1171 if (!GDK_WINDOW_DESTROYED (window))
1172 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1173 GDK_WINDOW_XID (window), xpixmap);
1177 gdk_window_set_cursor (GdkWindow *window,
1180 GdkCursorPrivate *cursor_private;
1183 g_return_if_fail (window != NULL);
1184 g_return_if_fail (GDK_IS_WINDOW (window));
1186 cursor_private = (GdkCursorPrivate*) cursor;
1191 xcursor = cursor_private->xcursor;
1193 if (!GDK_WINDOW_DESTROYED (window))
1194 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1195 GDK_WINDOW_XID (window),
1200 gdk_window_get_geometry (GdkWindow *window,
1212 guint tborder_width;
1215 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1218 window = gdk_parent_root;
1220 if (!GDK_WINDOW_DESTROYED (window))
1222 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1223 GDK_WINDOW_XID (window),
1224 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1240 gdk_window_get_origin (GdkWindow *window,
1249 g_return_val_if_fail (window != NULL, 0);
1251 if (!GDK_WINDOW_DESTROYED (window))
1253 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1254 GDK_WINDOW_XID (window),
1272 gdk_window_get_deskrelative_origin (GdkWindow *window,
1276 gboolean return_val = FALSE;
1277 gint num_children, format_return;
1278 Window win, *child, parent, root;
1282 static Atom atom = 0;
1283 gulong number_return, bytes_after_return;
1284 guchar *data_return;
1286 g_return_val_if_fail (window != NULL, 0);
1287 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1289 if (!GDK_WINDOW_DESTROYED (window))
1292 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1293 win = GDK_WINDOW_XID (window);
1295 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1296 &child, (unsigned int *)&num_children))
1298 if ((child) && (num_children > 0))
1310 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1311 False, XA_CARDINAL, &type_return, &format_return,
1312 &number_return, &bytes_after_return, &data_return);
1313 if (type_return == XA_CARDINAL)
1315 XFree (data_return);
1320 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1321 GDK_WINDOW_XID (window),
1336 gdk_window_get_root_origin (GdkWindow *window,
1340 GdkWindowObject *private;
1345 unsigned int nchildren;
1347 g_return_if_fail (window != NULL);
1348 g_return_if_fail (GDK_IS_WINDOW (window));
1350 private = (GdkWindowObject*) window;
1356 if (GDK_WINDOW_DESTROYED (window))
1359 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1360 private = (GdkWindowObject*) private->parent;
1361 if (GDK_WINDOW_DESTROYED (window))
1364 xparent = GDK_WINDOW_XID (window);
1368 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1370 &children, &nchildren))
1376 while (xparent != root);
1378 if (xparent == root)
1380 unsigned int ww, wh, wb, wd;
1383 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1394 gdk_window_get_pointer (GdkWindow *window,
1397 GdkModifierType *mask)
1399 GdkWindow *return_val;
1405 unsigned int xmask = 0;
1406 gint xoffset, yoffset;
1408 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1411 window = gdk_parent_root;
1413 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1416 if (!GDK_WINDOW_DESTROYED (window) &&
1417 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1418 GDK_WINDOW_XID (window),
1419 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1422 return_val = gdk_window_lookup (child);
1426 *x = winx + xoffset;
1428 *y = winy + yoffset;
1436 gdk_window_at_pointer (gint *win_x,
1442 Window xwindow_last = 0;
1444 int rootx = -1, rooty = -1;
1448 xwindow = GDK_ROOT_WINDOW ();
1449 xdisplay = GDK_DISPLAY ();
1451 XGrabServer (xdisplay);
1454 xwindow_last = xwindow;
1455 XQueryPointer (xdisplay, xwindow,
1461 XUngrabServer (xdisplay);
1463 window = gdk_window_lookup (xwindow_last);
1466 *win_x = window ? winx : -1;
1468 *win_y = window ? winy : -1;
1474 gdk_window_get_events (GdkWindow *window)
1476 XWindowAttributes attrs;
1477 GdkEventMask event_mask;
1480 g_return_val_if_fail (window != NULL, 0);
1481 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1483 if (GDK_WINDOW_DESTROYED (window))
1487 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1488 GDK_WINDOW_XID (window),
1492 for (i = 0; i < gdk_nevent_masks; i++)
1494 if (attrs.your_event_mask & gdk_event_mask_table[i])
1495 event_mask |= 1 << (i + 1);
1503 gdk_window_set_events (GdkWindow *window,
1504 GdkEventMask event_mask)
1509 g_return_if_fail (window != NULL);
1510 g_return_if_fail (GDK_IS_WINDOW (window));
1512 if (!GDK_WINDOW_DESTROYED (window))
1514 xevent_mask = StructureNotifyMask;
1515 for (i = 0; i < gdk_nevent_masks; i++)
1517 if (event_mask & (1 << (i + 1)))
1518 xevent_mask |= gdk_event_mask_table[i];
1521 XSelectInput (GDK_WINDOW_XDISPLAY (window),
1522 GDK_WINDOW_XID (window),
1528 gdk_window_add_colormap_windows (GdkWindow *window)
1530 GdkWindow *toplevel;
1531 Window *old_windows;
1532 Window *new_windows;
1535 g_return_if_fail (window != NULL);
1536 g_return_if_fail (GDK_IS_WINDOW (window));
1538 toplevel = gdk_window_get_toplevel (window);
1539 if (GDK_WINDOW_DESTROYED (toplevel))
1543 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1544 GDK_WINDOW_XID (toplevel),
1545 &old_windows, &count))
1550 for (i = 0; i < count; i++)
1551 if (old_windows[i] == GDK_WINDOW_XID (window))
1553 XFree (old_windows);
1557 new_windows = g_new (Window, count + 1);
1559 for (i = 0; i < count; i++)
1560 new_windows[i] = old_windows[i];
1561 new_windows[count] = GDK_WINDOW_XID (window);
1563 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
1564 GDK_WINDOW_XID (toplevel),
1565 new_windows, count + 1);
1567 g_free (new_windows);
1569 XFree (old_windows);
1573 gdk_window_have_shape_ext (void)
1575 enum { UNKNOWN, NO, YES };
1576 static gint have_shape = UNKNOWN;
1578 if (have_shape == UNKNOWN)
1581 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1587 return (have_shape == YES);
1591 * This needs the X11 shape extension.
1592 * If not available, shaped windows will look
1593 * ugly, but programs still work. Stefan Wille
1596 gdk_window_shape_combine_mask (GdkWindow *window,
1602 g_return_if_fail (window != NULL);
1603 g_return_if_fail (GDK_IS_WINDOW (window));
1605 #ifdef HAVE_SHAPE_EXT
1606 if (GDK_WINDOW_DESTROYED (window))
1609 if (gdk_window_have_shape_ext ())
1613 pixmap = GDK_PIXMAP_XID (mask);
1622 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
1623 GDK_WINDOW_XID (window),
1629 #endif /* HAVE_SHAPE_EXT */
1633 gdk_window_set_override_redirect (GdkWindow *window,
1634 gboolean override_redirect)
1636 XSetWindowAttributes attr;
1638 g_return_if_fail (window != NULL);
1639 g_return_if_fail (GDK_IS_WINDOW (window));
1641 if (GDK_WINDOW_DESTROYED (window))
1643 attr.override_redirect = (override_redirect == FALSE)?False:True;
1644 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1645 GDK_WINDOW_XID (window),
1652 gdk_window_set_icon (GdkWindow *window,
1653 GdkWindow *icon_window,
1659 g_return_if_fail (window != NULL);
1660 g_return_if_fail (GDK_IS_WINDOW (window));
1662 if (GDK_WINDOW_DESTROYED (window))
1665 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1666 GDK_WINDOW_XID (window));
1668 wm_hints = XAllocWMHints ();
1670 if (icon_window != NULL)
1672 wm_hints->flags |= IconWindowHint;
1673 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
1678 wm_hints->flags |= IconPixmapHint;
1679 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
1684 wm_hints->flags |= IconMaskHint;
1685 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
1688 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1689 GDK_WINDOW_XID (window), wm_hints);
1694 gdk_window_set_icon_name (GdkWindow *window,
1697 XTextProperty property;
1700 g_return_if_fail (window != NULL);
1701 g_return_if_fail (GDK_IS_WINDOW (window));
1703 if (GDK_WINDOW_DESTROYED (window))
1706 res = XmbTextListToTextProperty (GDK_WINDOW_XDISPLAY (window),
1707 &name, 1, XStdICCTextStyle,
1711 g_warning ("Error converting icon name to text property: %d\n", res);
1715 XSetWMIconName (GDK_WINDOW_XDISPLAY (window),
1716 GDK_WINDOW_XID (window),
1720 XFree (property.value);
1724 gdk_window_set_group (GdkWindow *window,
1729 g_return_if_fail (window != NULL);
1730 g_return_if_fail (GDK_IS_WINDOW (window));
1731 g_return_if_fail (leader != NULL);
1732 g_return_if_fail (GDK_IS_WINDOW (leader));
1734 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1737 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
1738 GDK_WINDOW_XID (window));
1740 wm_hints = XAllocWMHints ();
1742 wm_hints->flags |= WindowGroupHint;
1743 wm_hints->window_group = GDK_WINDOW_XID (leader);
1745 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1746 GDK_WINDOW_XID (window), wm_hints);
1751 gdk_window_set_mwm_hints (GdkWindow *window,
1752 MotifWmHints *new_hints)
1754 static Atom hints_atom = None;
1755 MotifWmHints *hints;
1761 if (GDK_WINDOW_DESTROYED (window))
1765 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
1766 _XA_MOTIF_WM_HINTS, FALSE);
1768 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1769 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1770 False, AnyPropertyType, &type, &format, &nitems,
1771 &bytes_after, (guchar **)&hints);
1777 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1779 hints->flags |= MWM_HINTS_FUNCTIONS;
1780 hints->functions = new_hints->functions;
1782 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1784 hints->flags |= MWM_HINTS_DECORATIONS;
1785 hints->decorations = new_hints->decorations;
1789 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1790 hints_atom, hints_atom, 32, PropModeReplace,
1791 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1793 if (hints != new_hints)
1798 gdk_window_set_decorations (GdkWindow *window,
1799 GdkWMDecoration decorations)
1803 g_return_if_fail (window != NULL);
1804 g_return_if_fail (GDK_IS_WINDOW (window));
1806 hints.flags = MWM_HINTS_DECORATIONS;
1807 hints.decorations = decorations;
1809 gdk_window_set_mwm_hints (window, &hints);
1813 gdk_window_set_functions (GdkWindow *window,
1814 GdkWMFunction functions)
1818 g_return_if_fail (window != NULL);
1819 g_return_if_fail (GDK_IS_WINDOW (window));
1821 hints.flags = MWM_HINTS_FUNCTIONS;
1822 hints.functions = functions;
1824 gdk_window_set_mwm_hints (window, &hints);
1828 * propagate the shapes from all child windows of a GDK window to the parent
1829 * window. Shamelessly ripped from Enlightenment's code
1837 struct _gdk_span *next;
1841 gdk_add_to_span (struct _gdk_span **s,
1845 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1852 /* scan the spans for this line */
1855 /* -- -> new span */
1856 /* == -> existing span */
1857 /* ## -> spans intersect */
1858 /* if we are in the middle of spanning the span into the line */
1861 /* case: ---- ==== */
1862 if (xx < ptr1->start - 1)
1864 /* ends before next span - extend to here */
1868 /* case: ----##=== */
1869 else if (xx <= ptr1->end)
1871 /* crosses into next span - delete next span and append */
1872 ss->end = ptr1->end;
1873 ss->next = ptr1->next;
1877 /* case: ---###--- */
1880 /* overlaps next span - delete and keep checking */
1881 ss->next = ptr1->next;
1886 /* otherwise havent started spanning it in yet */
1889 /* case: ---- ==== */
1890 if (xx < ptr1->start - 1)
1892 /* insert span here in list */
1893 noo = g_malloc (sizeof (struct _gdk_span));
1907 /* case: ----##=== */
1908 else if ((x < ptr1->start) && (xx <= ptr1->end))
1910 /* expand this span to the left point of the new one */
1914 /* case: ===###=== */
1915 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1917 /* throw the span away */
1920 /* case: ---###--- */
1921 else if ((x < ptr1->start) && (xx > ptr1->end))
1928 /* case: ===##---- */
1929 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
1935 /* case: ==== ---- */
1936 /* case handled by next loop iteration - first case */
1941 /* it started in the middle but spans beyond your current list */
1947 /* it does not start inside a span or in the middle, so add it to the end */
1948 noo = g_malloc (sizeof (struct _gdk_span));
1956 noo->next = ptr2->next;
1969 gdk_add_rectangles (Display *disp,
1971 struct _gdk_span **spans,
1978 gint x1, y1, x2, y2;
1982 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
1985 /* go through all clip rects in this window's shape */
1986 for (k = 0; k < rn; k++)
1988 /* for each clip rect, add it to each line's spans */
1990 x2 = x + rl[k].x + (rl[k].width - 1);
1992 y2 = y + rl[k].y + (rl[k].height - 1);
2001 for (a = y1; a <= y2; a++)
2004 gdk_add_to_span (&spans[a], x1, x2);
2012 gdk_propagate_shapes (Display *disp,
2016 Window rt, par, *list = NULL;
2017 gint i, j, num = 0, num_rects = 0;
2021 XRectangle *rects = NULL;
2022 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2023 XWindowAttributes xatt;
2025 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2030 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2032 for (i = 0; i < h; i++)
2034 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2037 /* go through all child windows and create/insert spans */
2038 for (i = 0; i < num; i++)
2040 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2041 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2042 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2045 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2047 /* go through the spans list and build a list of rects */
2048 rects = g_malloc (sizeof (XRectangle) * 256);
2050 for (i = 0; i < baseh; i++)
2053 /* go through the line for all spans */
2056 rects[num_rects].x = ptr1->start;
2057 rects[num_rects].y = i;
2058 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2059 rects[num_rects].height = 1;
2061 /* if there are more lines */
2063 /* while contigous rects (same start/end coords) exist */
2064 while ((contig) && (j < baseh))
2066 /* search next line for spans matching this one */
2072 /* if we have an exact span match set contig */
2073 if ((ptr2->start == ptr1->start) &&
2074 (ptr2->end == ptr1->end))
2077 /* remove the span - not needed */
2080 ptr3->next = ptr2->next;
2086 spans[j] = ptr2->next;
2092 /* gone past the span point no point looking */
2093 else if (ptr2->start < ptr1->start)
2101 /* if a contiguous span was found increase the rect h */
2104 rects[num_rects].height++;
2108 /* up the rect count */
2110 /* every 256 new rects increase the rect array */
2111 if ((num_rects % 256) == 0)
2112 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2116 /* set the rects as the shape mask */
2119 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2120 ShapeSet, YXSorted);
2125 /* free up all the spans we made */
2126 for (i = 0; i < baseh; i++)
2140 gdk_window_set_child_shapes (GdkWindow *window)
2142 g_return_if_fail (window != NULL);
2143 g_return_if_fail (GDK_IS_WINDOW (window));
2145 #ifdef HAVE_SHAPE_EXT
2146 if (!GDK_WINDOW_DESTROYED (window) &&
2147 gdk_window_have_shape_ext ())
2148 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2149 GDK_WINDOW_XID (window), FALSE);
2154 gdk_window_merge_child_shapes (GdkWindow *window)
2156 g_return_if_fail (window != NULL);
2157 g_return_if_fail (GDK_IS_WINDOW (window));
2159 #ifdef HAVE_SHAPE_EXT
2160 if (!GDK_WINDOW_DESTROYED (window) &&
2161 gdk_window_have_shape_ext ())
2162 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
2163 GDK_WINDOW_XID (window), TRUE);
2167 /* Support for windows that can be guffaw-scrolled
2168 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2172 gdk_window_gravity_works (void)
2174 enum { UNKNOWN, NO, YES };
2175 static gint gravity_works = UNKNOWN;
2177 if (gravity_works == UNKNOWN)
2184 /* This particular server apparently has a bug so that the test
2185 * works but the actual code crashes it
2187 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2188 (VendorRelease (gdk_display) == 3400))
2194 attr.window_type = GDK_WINDOW_TEMP;
2195 attr.wclass = GDK_INPUT_OUTPUT;
2200 attr.event_mask = 0;
2202 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2204 attr.window_type = GDK_WINDOW_CHILD;
2205 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2207 gdk_window_set_static_win_gravity (child, TRUE);
2209 gdk_window_resize (parent, 100, 110);
2210 gdk_window_move (parent, 0, -10);
2211 gdk_window_move_resize (parent, 0, 0, 100, 100);
2213 gdk_window_resize (parent, 100, 110);
2214 gdk_window_move (parent, 0, -10);
2215 gdk_window_move_resize (parent, 0, 0, 100, 100);
2217 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2219 gdk_window_destroy (parent);
2220 gdk_window_destroy (child);
2222 gravity_works = ((y == -20) ? YES : NO);
2225 return (gravity_works == YES);
2229 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2231 XSetWindowAttributes xattributes;
2232 guint xattributes_mask = 0;
2234 g_return_if_fail (window != NULL);
2236 xattributes.bit_gravity = StaticGravity;
2237 xattributes_mask |= CWBitGravity;
2238 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2239 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2240 GDK_WINDOW_XID (window),
2241 CWBitGravity, &xattributes);
2245 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2247 XSetWindowAttributes xattributes;
2249 g_return_if_fail (window != NULL);
2251 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2253 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2254 GDK_WINDOW_XID (window),
2255 CWWinGravity, &xattributes);
2258 /*************************************************************
2259 * gdk_window_set_static_gravities:
2260 * Set the bit gravity of the given window to static,
2261 * and flag it so all children get static subwindow
2264 * window: window for which to set static gravity
2265 * use_static: Whether to turn static gravity on or off.
2267 * Does the XServer support static gravity?
2268 *************************************************************/
2271 gdk_window_set_static_gravities (GdkWindow *window,
2272 gboolean use_static)
2274 GdkWindowObject *private = (GdkWindowObject *)window;
2277 g_return_val_if_fail (window != NULL, FALSE);
2278 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2280 if (!use_static == !private->guffaw_gravity)
2283 if (use_static && !gdk_window_gravity_works ())
2286 private->guffaw_gravity = use_static;
2288 if (!GDK_WINDOW_DESTROYED (window))
2290 gdk_window_set_static_bit_gravity (window, use_static);
2292 tmp_list = private->children;
2295 gdk_window_set_static_win_gravity (window, use_static);
2297 tmp_list = tmp_list->next;
2304 /* internal function created for and used by gdk_window_xid_at_coords */
2306 gdk_window_xid_at (Window base,
2312 gboolean excl_child)
2315 Window *list = NULL;
2316 Window child = 0, parent_win = 0, root_win = 0;
2318 unsigned int ww, wh, wb, wd, num;
2321 xdisplay = GDK_DISPLAY ();
2322 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2329 (x < (int) (wx + ww)) &&
2330 (y < (int) (wy + wh))))
2333 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2338 for (i = num - 1; ; i--)
2340 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2342 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2357 * The following fucntion by The Rasterman <raster@redhat.com>
2358 * This function returns the X Window ID in which the x y location is in
2359 * (x and y being relative to the root window), excluding any windows listed
2360 * in the GList excludes (this is a list of X Window ID's - gpointer being
2363 * This is primarily designed for internal gdk use - for DND for example
2364 * when using a shaped icon window as the drag object - you exclude the
2365 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2366 * You can get back an X Window ID as to what X Window ID is infact under
2367 * those X,Y co-ordinates.
2370 gdk_window_xid_at_coords (gint x,
2373 gboolean excl_child)
2377 Window *list = NULL;
2378 Window root, child = 0, parent_win = 0, root_win = 0;
2382 window = gdk_parent_root;
2383 xdisplay = GDK_WINDOW_XDISPLAY (window);
2384 root = GDK_WINDOW_XID (window);
2385 num = g_list_length (excludes);
2387 XGrabServer (xdisplay);
2388 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2390 XUngrabServer (xdisplay);
2398 XWindowAttributes xwa;
2400 XGetWindowAttributes (xdisplay, list [i], &xwa);
2402 if (xwa.map_state != IsViewable)
2405 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2408 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2413 if (!g_list_find (excludes, (gpointer *) child))
2416 XUngrabServer (xdisplay);
2423 XUngrabServer (xdisplay);
2429 XUngrabServer (xdisplay);