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 "gdkinternals.h"
46 #include <X11/extensions/shape.h>
49 const int gdk_event_mask_table[21] =
53 PointerMotionHintMask,
70 SubstructureNotifyMask,
71 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
73 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
75 /* Forward declarations */
76 static gboolean gdk_window_gravity_works (void);
77 static void gdk_window_set_static_win_gravity (GdkWindow *window,
79 static gboolean gdk_window_have_shape_ext (void);
81 GdkDrawableClass _gdk_windowing_window_class;
84 gdk_x11_window_destroy (GdkDrawable *drawable)
86 if (!GDK_DRAWABLE_DESTROYED (drawable))
88 if (GDK_DRAWABLE_TYPE (drawable) == GDK_WINDOW_FOREIGN)
89 gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable));
91 g_warning ("losing last reference to undestroyed window\n");
94 g_free (GDK_DRAWABLE_XDATA (drawable));
98 gdk_x11_window_alloc (void)
101 GdkWindowPrivate *private;
103 static gboolean initialized = FALSE;
109 _gdk_windowing_window_class = _gdk_x11_drawable_class;
110 _gdk_windowing_window_class.destroy = gdk_x11_window_destroy;
113 window = _gdk_window_alloc ();
114 private = (GdkWindowPrivate *)window;
116 private->drawable.klass = &_gdk_window_class;
117 private->drawable.klass_data = g_new (GdkWindowXData, 1);
123 gdk_window_init (void)
125 GdkWindowPrivate *private;
126 XWindowAttributes xattributes;
129 unsigned int border_width;
133 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
134 &x, &y, &width, &height, &border_width, &depth);
135 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
137 gdk_parent_root = gdk_x11_window_alloc ();
138 private = (GdkWindowPrivate *)gdk_parent_root;
140 GDK_DRAWABLE_XDATA (gdk_parent_root)->xdisplay = gdk_display;
141 GDK_DRAWABLE_XDATA (gdk_parent_root)->xid = gdk_root_window;
143 private->drawable.window_type = GDK_WINDOW_ROOT;
144 private->drawable.width = width;
145 private->drawable.height = height;
147 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
150 static GdkAtom wm_client_leader_atom = GDK_NONE;
153 gdk_window_new (GdkWindow *parent,
154 GdkWindowAttr *attributes,
155 gint attributes_mask)
158 GdkWindowPrivate *private;
159 GdkWindowPrivate *parent_private;
165 XSetWindowAttributes xattributes;
166 long xattributes_mask;
167 XSizeHints size_hints;
169 XClassHint *class_hint;
176 g_return_val_if_fail (attributes != NULL, NULL);
179 parent = gdk_parent_root;
181 parent_private = (GdkWindowPrivate*) parent;
182 if (GDK_DRAWABLE_DESTROYED (parent))
185 xparent = GDK_DRAWABLE_XID (parent);
187 window = gdk_x11_window_alloc ();
188 private = (GdkWindowPrivate *)window;
190 GDK_DRAWABLE_XDATA (window)->xdisplay = GDK_DRAWABLE_XDISPLAY (parent);
192 private->parent = parent;
194 xattributes_mask = 0;
196 if (attributes_mask & GDK_WA_X)
201 if (attributes_mask & GDK_WA_Y)
208 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
209 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
210 private->drawable.window_type = attributes->window_type;
212 _gdk_window_init_position (window);
213 if (GDK_WINDOW_XDATA (window)->position_info.big)
214 private->guffaw_gravity = TRUE;
216 if (attributes_mask & GDK_WA_VISUAL)
217 visual = attributes->visual;
219 visual = gdk_visual_get_system ();
220 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
222 xattributes.event_mask = StructureNotifyMask;
223 for (i = 0; i < gdk_nevent_masks; i++)
225 if (attributes->event_mask & (1 << (i + 1)))
226 xattributes.event_mask |= gdk_event_mask_table[i];
229 if (xattributes.event_mask)
230 xattributes_mask |= CWEventMask;
232 if (attributes_mask & GDK_WA_NOREDIR)
234 xattributes.override_redirect =
235 (attributes->override_redirect == FALSE)?False:True;
236 xattributes_mask |= CWOverrideRedirect;
239 xattributes.override_redirect = False;
241 if (parent_private && parent_private->guffaw_gravity)
243 xattributes.win_gravity = StaticGravity;
244 xattributes_mask |= CWWinGravity;
247 if (attributes->wclass == GDK_INPUT_OUTPUT)
250 depth = visual->depth;
252 private->input_only = FALSE;
253 private->drawable.depth = depth;
255 if (attributes_mask & GDK_WA_COLORMAP)
256 private->drawable.colormap = attributes->colormap;
259 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
260 private->drawable.colormap = gdk_colormap_get_system ();
262 private->drawable.colormap = gdk_colormap_new (visual, False);
265 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
266 xattributes.background_pixel = private->bg_color.pixel;
268 private->bg_pixmap = NULL;
270 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
271 xattributes_mask |= CWBorderPixel | CWBackPixel;
273 if (private->guffaw_gravity)
274 xattributes.bit_gravity = StaticGravity;
276 xattributes.bit_gravity = NorthWestGravity;
278 xattributes_mask |= CWBitGravity;
280 switch (private->drawable.window_type)
282 case GDK_WINDOW_TOPLEVEL:
283 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
284 xattributes_mask |= CWColormap;
286 xparent = gdk_root_window;
289 case GDK_WINDOW_CHILD:
290 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
291 xattributes_mask |= CWColormap;
294 case GDK_WINDOW_DIALOG:
295 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
296 xattributes_mask |= CWColormap;
298 xparent = gdk_root_window;
301 case GDK_WINDOW_TEMP:
302 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (private->drawable.colormap);
303 xattributes_mask |= CWColormap;
305 xparent = gdk_root_window;
307 xattributes.save_under = True;
308 xattributes.override_redirect = True;
309 xattributes.cursor = None;
310 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
312 case GDK_WINDOW_ROOT:
313 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
315 case GDK_WINDOW_PIXMAP:
316 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
324 private->input_only = TRUE;
325 private->drawable.colormap = NULL;
328 GDK_DRAWABLE_XDATA (private)->xid = XCreateWindow (GDK_DRAWABLE_XDISPLAY (parent),
330 x, y, private->drawable.width, private->drawable.height,
331 0, depth, class, xvisual,
332 xattributes_mask, &xattributes);
333 gdk_drawable_ref (window);
334 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
336 if (private->drawable.colormap)
337 gdk_colormap_ref (private->drawable.colormap);
339 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
340 (attributes->cursor) :
344 parent_private->children = g_list_prepend (parent_private->children, window);
346 switch (private->drawable.window_type)
348 case GDK_WINDOW_DIALOG:
349 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
350 GDK_DRAWABLE_XID (window),
352 case GDK_WINDOW_TOPLEVEL:
353 case GDK_WINDOW_TEMP:
354 XSetWMProtocols (GDK_DRAWABLE_XDISPLAY (window),
355 GDK_DRAWABLE_XID (window),
356 gdk_wm_window_protocols, 2);
358 case GDK_WINDOW_CHILD:
359 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
360 (private->drawable.colormap != gdk_colormap_get_system ()) &&
361 (private->drawable.colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
363 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
364 gdk_window_add_colormap_windows (window);
373 size_hints.flags = PSize;
374 size_hints.width = private->drawable.width;
375 size_hints.height = private->drawable.height;
377 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
378 wm_hints.window_group = gdk_leader_window;
379 wm_hints.input = True;
380 wm_hints.initial_state = NormalState;
382 /* FIXME: Is there any point in doing this? Do any WM's pay
383 * attention to PSize, and even if they do, is this the
386 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
387 GDK_DRAWABLE_XID (window),
390 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
391 GDK_DRAWABLE_XID (window),
394 if (!wm_client_leader_atom)
395 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
397 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window),
398 GDK_DRAWABLE_XID (window),
399 wm_client_leader_atom,
400 XA_WINDOW, 32, PropModeReplace,
401 (guchar*) &gdk_leader_window, 1);
403 if (attributes_mask & GDK_WA_TITLE)
404 title = attributes->title;
406 title = g_get_prgname ();
408 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
409 GDK_DRAWABLE_XID (window),
414 if (attributes_mask & GDK_WA_WMCLASS)
416 class_hint = XAllocClassHint ();
417 class_hint->res_name = attributes->wmclass_name;
418 class_hint->res_class = attributes->wmclass_class;
419 XSetClassHint (GDK_DRAWABLE_XDISPLAY (window),
420 GDK_DRAWABLE_XID (window),
429 gdk_window_foreign_new (guint32 anid)
432 GdkWindowPrivate *private;
433 GdkWindowPrivate *parent_private;
434 XWindowAttributes attrs;
436 Window *children = NULL;
440 gdk_error_trap_push ();
441 result = XGetWindowAttributes (gdk_display, anid, &attrs);
442 if (gdk_error_trap_pop () || !result)
445 /* FIXME: This is pretty expensive. Maybe the caller should supply
447 gdk_error_trap_push ();
448 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
449 if (gdk_error_trap_pop () || !result)
455 window = gdk_x11_window_alloc ();
456 private = (GdkWindowPrivate *)window;
458 private->parent = gdk_xid_table_lookup (parent);
460 parent_private = (GdkWindowPrivate *)private->parent;
463 parent_private->children = g_list_prepend (parent_private->children, window);
465 GDK_DRAWABLE_XDATA (window)->xid = anid;
466 GDK_DRAWABLE_XDATA (window)->xdisplay = gdk_display;
468 private->x = attrs.x;
469 private->y = attrs.y;
470 private->drawable.width = attrs.width;
471 private->drawable.height = attrs.height;
472 private->drawable.window_type = GDK_WINDOW_FOREIGN;
473 private->drawable.destroyed = FALSE;
474 private->mapped = (attrs.map_state != IsUnmapped);
476 gdk_drawable_ref (window);
477 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
482 /* Call this function when you want a window and all its children to
483 * disappear. When xdestroy is true, a request to destroy the XWindow
484 * is sent out. When it is false, it is assumed that the XWindow has
485 * been or will be destroyed by destroying some ancestor of this
489 gdk_window_internal_destroy (GdkWindow *window,
491 gboolean our_destroy)
493 GdkWindowPrivate *private;
494 GdkWindowPrivate *temp_private;
495 GdkWindow *temp_window;
499 g_return_if_fail (window != NULL);
501 private = (GdkWindowPrivate*) window;
503 switch (private->drawable.window_type)
505 case GDK_WINDOW_TOPLEVEL:
506 case GDK_WINDOW_CHILD:
507 case GDK_WINDOW_DIALOG:
508 case GDK_WINDOW_TEMP:
509 case GDK_WINDOW_FOREIGN:
510 if (!private->drawable.destroyed)
514 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
515 if (parent_private->children)
516 parent_private->children = g_list_remove (parent_private->children, window);
519 if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG)
521 gdk_pixmap_unref (private->bg_pixmap);
522 private->bg_pixmap = NULL;
525 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
527 children = tmp = private->children;
528 private->children = NULL;
532 temp_window = tmp->data;
535 temp_private = (GdkWindowPrivate*) temp_window;
537 gdk_window_internal_destroy (temp_window, FALSE,
541 g_list_free (children);
544 if (private->extension_events != 0)
545 gdk_input_window_destroy (window);
547 if (private->filters)
549 tmp = private->filters;
557 g_list_free (private->filters);
558 private->filters = NULL;
561 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
563 if (our_destroy && (private->parent != NULL))
565 /* It's somebody elses window, but in our heirarchy,
566 * so reparent it to the root window, and then send
567 * it a delete event, as if we were a WM
569 XClientMessageEvent xevent;
571 gdk_error_trap_push ();
572 gdk_window_hide (window);
573 gdk_window_reparent (window, NULL, 0, 0);
575 xevent.type = ClientMessage;
576 xevent.window = GDK_DRAWABLE_XID (window);
577 xevent.message_type = gdk_wm_protocols;
579 xevent.data.l[0] = gdk_wm_delete_window;
580 xevent.data.l[1] = CurrentTime;
582 XSendEvent (GDK_DRAWABLE_XDISPLAY (window),
583 GDK_DRAWABLE_XID (window),
584 False, 0, (XEvent *)&xevent);
586 gdk_error_trap_pop ();
590 XDestroyWindow (GDK_DRAWABLE_XDISPLAY (window),
591 GDK_DRAWABLE_XID (window));
593 if (private->drawable.colormap)
594 gdk_colormap_unref (private->drawable.colormap);
596 private->mapped = FALSE;
597 private->drawable.destroyed = TRUE;
601 case GDK_WINDOW_ROOT:
602 g_error ("attempted to destroy root window");
605 case GDK_WINDOW_PIXMAP:
606 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
611 /* Like internal_destroy, but also destroys the reference created by
615 gdk_window_destroy (GdkWindow *window)
617 gdk_window_internal_destroy (window, TRUE, TRUE);
618 gdk_drawable_unref (window);
621 /* This function is called when the XWindow is really gone. */
624 gdk_window_destroy_notify (GdkWindow *window)
626 g_return_if_fail (window != NULL);
628 if (!GDK_DRAWABLE_DESTROYED (window))
630 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
631 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_DRAWABLE_XID (window));
633 gdk_window_internal_destroy (window, FALSE, FALSE);
636 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
637 gdk_drawable_unref (window);
641 gdk_window_show (GdkWindow *window)
643 GdkWindowPrivate *private;
645 g_return_if_fail (window != NULL);
647 private = (GdkWindowPrivate*) window;
648 if (!private->drawable.destroyed)
650 private->mapped = TRUE;
651 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window),
652 GDK_DRAWABLE_XID (window));
654 if (GDK_WINDOW_XDATA (window)->position_info.mapped)
655 XMapWindow (GDK_DRAWABLE_XDISPLAY (window),
656 GDK_DRAWABLE_XID (window));
661 gdk_window_hide (GdkWindow *window)
663 GdkWindowPrivate *private;
665 g_return_if_fail (window != NULL);
667 private = (GdkWindowPrivate*) window;
668 if (!private->drawable.destroyed)
670 private->mapped = FALSE;
671 XUnmapWindow (GDK_DRAWABLE_XDISPLAY (window),
672 GDK_DRAWABLE_XID (window));
677 gdk_window_withdraw (GdkWindow *window)
679 GdkWindowPrivate *private;
681 g_return_if_fail (window != NULL);
683 private = (GdkWindowPrivate*) window;
684 if (!private->drawable.destroyed)
685 XWithdrawWindow (GDK_DRAWABLE_XDISPLAY (window),
686 GDK_DRAWABLE_XID (window), 0);
690 gdk_window_move (GdkWindow *window,
694 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
696 g_return_if_fail (window != NULL);
697 g_return_if_fail (GDK_IS_WINDOW (window));
699 gdk_window_move_resize (window, x, y,
700 private->drawable.width, private->drawable.height);
704 gdk_window_resize (GdkWindow *window,
708 GdkWindowPrivate *private;
710 g_return_if_fail (window != NULL);
711 g_return_if_fail (GDK_IS_WINDOW (window));
718 private = (GdkWindowPrivate*) window;
720 if (!GDK_DRAWABLE_DESTROYED (window))
722 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
723 _gdk_window_move_resize_child (window, private->x, private->y,
727 XResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
728 GDK_DRAWABLE_XID (window),
730 private->resize_count += 1;
736 gdk_window_move_resize (GdkWindow *window,
742 GdkWindowPrivate *private;
744 g_return_if_fail (window != NULL);
745 g_return_if_fail (GDK_IS_WINDOW (window));
752 private = (GdkWindowPrivate*) window;
754 if (!GDK_DRAWABLE_DESTROYED (window))
756 if (GDK_DRAWABLE_TYPE (private) == GDK_WINDOW_CHILD)
757 _gdk_window_move_resize_child (window, x, y, width, height);
760 XMoveResizeWindow (GDK_DRAWABLE_XDISPLAY (window),
761 GDK_DRAWABLE_XID (window),
762 x, y, width, height);
768 gdk_window_reparent (GdkWindow *window,
769 GdkWindow *new_parent,
773 GdkWindowPrivate *window_private;
774 GdkWindowPrivate *parent_private;
775 GdkWindowPrivate *old_parent_private;
777 g_return_if_fail (window != NULL);
778 g_return_if_fail (GDK_IS_WINDOW (window));
779 g_return_if_fail (new_parent != NULL);
780 g_return_if_fail (GDK_IS_WINDOW (new_parent));
783 new_parent = gdk_parent_root;
785 window_private = (GdkWindowPrivate*) window;
786 old_parent_private = (GdkWindowPrivate*)window_private->parent;
787 parent_private = (GdkWindowPrivate*) new_parent;
789 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (new_parent))
790 XReparentWindow (GDK_DRAWABLE_XDISPLAY (window),
791 GDK_DRAWABLE_XID (window),
792 GDK_DRAWABLE_XID (new_parent),
795 window_private->parent = new_parent;
797 if (old_parent_private)
798 old_parent_private->children = g_list_remove (old_parent_private->children, window);
800 if ((old_parent_private &&
801 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
802 (!old_parent_private && parent_private->guffaw_gravity))
803 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
805 parent_private->children = g_list_prepend (parent_private->children, window);
809 _gdk_windowing_window_clear_area (GdkWindow *window,
815 g_return_if_fail (window != NULL);
816 g_return_if_fail (GDK_IS_WINDOW (window));
818 if (!GDK_DRAWABLE_DESTROYED (window))
819 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
820 x, y, width, height, False);
824 _gdk_windowing_window_clear_area_e (GdkWindow *window,
830 g_return_if_fail (window != NULL);
831 g_return_if_fail (GDK_IS_WINDOW (window));
833 if (!GDK_DRAWABLE_DESTROYED (window))
834 XClearArea (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
835 x, y, width, height, True);
839 gdk_window_raise (GdkWindow *window)
841 g_return_if_fail (window != NULL);
842 g_return_if_fail (GDK_IS_WINDOW (window));
844 if (!GDK_DRAWABLE_DESTROYED (window))
845 XRaiseWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
849 gdk_window_lower (GdkWindow *window)
851 g_return_if_fail (window != NULL);
852 g_return_if_fail (GDK_IS_WINDOW (window));
854 if (!GDK_DRAWABLE_DESTROYED (window))
855 XLowerWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window));
859 gdk_window_set_hints (GdkWindow *window,
868 XSizeHints size_hints;
870 g_return_if_fail (window != NULL);
871 g_return_if_fail (GDK_IS_WINDOW (window));
873 if (GDK_DRAWABLE_DESTROYED (window))
876 size_hints.flags = 0;
878 if (flags & GDK_HINT_POS)
880 size_hints.flags |= PPosition;
885 if (flags & GDK_HINT_MIN_SIZE)
887 size_hints.flags |= PMinSize;
888 size_hints.min_width = min_width;
889 size_hints.min_height = min_height;
892 if (flags & GDK_HINT_MAX_SIZE)
894 size_hints.flags |= PMaxSize;
895 size_hints.max_width = max_width;
896 size_hints.max_height = max_height;
899 /* FIXME: Would it be better to delete this property of
900 * flags == 0? It would save space on the server
902 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
903 GDK_DRAWABLE_XID (window),
908 gdk_window_set_geometry_hints (GdkWindow *window,
909 GdkGeometry *geometry,
910 GdkWindowHints geom_mask)
912 XSizeHints size_hints;
914 g_return_if_fail (window != NULL);
915 g_return_if_fail (GDK_IS_WINDOW (window));
917 if (GDK_DRAWABLE_DESTROYED (window))
920 size_hints.flags = 0;
922 if (geom_mask & GDK_HINT_POS)
924 size_hints.flags |= PPosition;
925 /* We need to initialize the following obsolete fields because KWM
926 * apparently uses these fields if they are non-zero.
933 if (geom_mask & GDK_HINT_MIN_SIZE)
935 size_hints.flags |= PMinSize;
936 size_hints.min_width = geometry->min_width;
937 size_hints.min_height = geometry->min_height;
940 if (geom_mask & GDK_HINT_MAX_SIZE)
942 size_hints.flags |= PMaxSize;
943 size_hints.max_width = MAX (geometry->max_width, 1);
944 size_hints.max_height = MAX (geometry->max_height, 1);
947 if (geom_mask & GDK_HINT_BASE_SIZE)
949 size_hints.flags |= PBaseSize;
950 size_hints.base_width = geometry->base_width;
951 size_hints.base_height = geometry->base_height;
954 if (geom_mask & GDK_HINT_RESIZE_INC)
956 size_hints.flags |= PResizeInc;
957 size_hints.width_inc = geometry->width_inc;
958 size_hints.height_inc = geometry->height_inc;
961 if (geom_mask & GDK_HINT_ASPECT)
963 size_hints.flags |= PAspect;
964 if (geometry->min_aspect <= 1)
966 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
967 size_hints.min_aspect.y = 65536;
971 size_hints.min_aspect.x = 65536;
972 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
974 if (geometry->max_aspect <= 1)
976 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
977 size_hints.max_aspect.y = 65536;
981 size_hints.max_aspect.x = 65536;
982 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
986 /* FIXME: Would it be better to delete this property of
987 * geom_mask == 0? It would save space on the server
989 XSetWMNormalHints (GDK_DRAWABLE_XDISPLAY (window),
990 GDK_DRAWABLE_XID (window),
995 gdk_window_set_title (GdkWindow *window,
998 g_return_if_fail (window != NULL);
999 g_return_if_fail (GDK_IS_WINDOW (window));
1001 if (!GDK_DRAWABLE_DESTROYED (window))
1002 XmbSetWMProperties (GDK_DRAWABLE_XDISPLAY (window),
1003 GDK_DRAWABLE_XID (window),
1004 title, title, NULL, 0, NULL, NULL, NULL);
1008 gdk_window_set_role (GdkWindow *window,
1011 g_return_if_fail (window != NULL);
1012 g_return_if_fail (GDK_IS_WINDOW (window));
1014 if (!GDK_DRAWABLE_DESTROYED (window))
1017 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1018 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1019 8, PropModeReplace, role, strlen (role));
1021 XDeleteProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1022 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1027 gdk_window_set_transient_for (GdkWindow *window,
1030 GdkWindowPrivate *private;
1031 GdkWindowPrivate *parent_private;
1033 g_return_if_fail (window != NULL);
1034 g_return_if_fail (GDK_IS_WINDOW (window));
1036 private = (GdkWindowPrivate*) window;
1037 parent_private = (GdkWindowPrivate*) parent;
1039 if (!GDK_DRAWABLE_DESTROYED (window) && !GDK_DRAWABLE_DESTROYED (parent))
1040 XSetTransientForHint (GDK_DRAWABLE_XDISPLAY (window),
1041 GDK_DRAWABLE_XID (window),
1042 GDK_DRAWABLE_XID (parent));
1046 gdk_window_set_background (GdkWindow *window,
1049 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1051 g_return_if_fail (window != NULL);
1052 g_return_if_fail (GDK_IS_WINDOW (window));
1054 if (!GDK_DRAWABLE_DESTROYED (window))
1055 XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
1056 GDK_DRAWABLE_XID (window), color->pixel);
1058 private->bg_color = *color;
1060 if (private->bg_pixmap &&
1061 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1062 private->bg_pixmap != GDK_NO_BG)
1064 gdk_pixmap_unref (private->bg_pixmap);
1065 private->bg_pixmap = NULL;
1070 gdk_window_set_back_pixmap (GdkWindow *window,
1072 gboolean parent_relative)
1074 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1077 g_return_if_fail (window != NULL);
1078 g_return_if_fail (GDK_IS_WINDOW (window));
1079 g_return_if_fail (pixmap == NULL || !parent_relative);
1081 if (private->bg_pixmap &&
1082 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1083 private->bg_pixmap != GDK_NO_BG)
1084 gdk_pixmap_unref (private->bg_pixmap);
1086 if (parent_relative)
1088 xpixmap = ParentRelative;
1089 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1095 gdk_pixmap_ref (pixmap);
1096 private->bg_pixmap = pixmap;
1097 xpixmap = GDK_DRAWABLE_XID (pixmap);
1102 private->bg_pixmap = GDK_NO_BG;
1106 if (!GDK_DRAWABLE_DESTROYED (window))
1107 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
1108 GDK_DRAWABLE_XID (window), xpixmap);
1112 gdk_window_set_cursor (GdkWindow *window,
1115 GdkCursorPrivate *cursor_private;
1118 g_return_if_fail (window != NULL);
1119 g_return_if_fail (GDK_IS_WINDOW (window));
1121 cursor_private = (GdkCursorPrivate*) cursor;
1126 xcursor = cursor_private->xcursor;
1128 if (!GDK_DRAWABLE_DESTROYED (window))
1129 XDefineCursor (GDK_DRAWABLE_XDISPLAY (window),
1130 GDK_DRAWABLE_XID (window),
1135 gdk_window_get_geometry (GdkWindow *window,
1147 guint tborder_width;
1150 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1153 window = gdk_parent_root;
1155 if (!GDK_DRAWABLE_DESTROYED (window))
1157 XGetGeometry (GDK_DRAWABLE_XDISPLAY (window),
1158 GDK_DRAWABLE_XID (window),
1159 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1175 gdk_window_get_origin (GdkWindow *window,
1184 g_return_val_if_fail (window != NULL, 0);
1186 if (!GDK_DRAWABLE_DESTROYED (window))
1188 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1189 GDK_DRAWABLE_XID (window),
1207 gdk_window_get_deskrelative_origin (GdkWindow *window,
1211 gboolean return_val = FALSE;
1212 gint num_children, format_return;
1213 Window win, *child, parent, root;
1217 static Atom atom = 0;
1218 gulong number_return, bytes_after_return;
1219 guchar *data_return;
1221 g_return_val_if_fail (window != NULL, 0);
1222 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1224 if (!GDK_DRAWABLE_DESTROYED (window))
1227 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1228 win = GDK_DRAWABLE_XID (window);
1230 while (XQueryTree (GDK_DRAWABLE_XDISPLAY (window), win, &root, &parent,
1231 &child, (unsigned int *)&num_children))
1233 if ((child) && (num_children > 0))
1245 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), win, atom, 0, 0,
1246 False, XA_CARDINAL, &type_return, &format_return,
1247 &number_return, &bytes_after_return, &data_return);
1248 if (type_return == XA_CARDINAL)
1250 XFree (data_return);
1255 return_val = XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1256 GDK_DRAWABLE_XID (window),
1271 gdk_window_get_root_origin (GdkWindow *window,
1275 GdkWindowPrivate *private;
1280 unsigned int nchildren;
1282 g_return_if_fail (window != NULL);
1283 g_return_if_fail (GDK_IS_WINDOW (window));
1285 private = (GdkWindowPrivate*) window;
1291 if (GDK_DRAWABLE_DESTROYED (window))
1294 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1295 private = (GdkWindowPrivate*) private->parent;
1296 if (GDK_DRAWABLE_DESTROYED (window))
1299 xparent = GDK_DRAWABLE_XID (window);
1303 if (!XQueryTree (GDK_DRAWABLE_XDISPLAY (window), xwindow,
1305 &children, &nchildren))
1311 while (xparent != root);
1313 if (xparent == root)
1315 unsigned int ww, wh, wb, wd;
1318 if (XGetGeometry (GDK_DRAWABLE_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1329 gdk_window_get_pointer (GdkWindow *window,
1332 GdkModifierType *mask)
1334 GdkWindow *return_val;
1340 unsigned int xmask = 0;
1341 gint xoffset, yoffset;
1343 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1346 window = gdk_parent_root;
1348 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1351 if (!GDK_DRAWABLE_DESTROYED (window) &&
1352 XQueryPointer (GDK_DRAWABLE_XDISPLAY (window),
1353 GDK_DRAWABLE_XID (window),
1354 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1357 return_val = gdk_window_lookup (child);
1361 *x = winx + xoffset;
1363 *y = winy + yoffset;
1371 gdk_window_at_pointer (gint *win_x,
1377 Window xwindow_last = 0;
1379 int rootx = -1, rooty = -1;
1383 xwindow = GDK_ROOT_WINDOW ();
1384 xdisplay = GDK_DISPLAY ();
1386 XGrabServer (xdisplay);
1389 xwindow_last = xwindow;
1390 XQueryPointer (xdisplay, xwindow,
1396 XUngrabServer (xdisplay);
1398 window = gdk_window_lookup (xwindow_last);
1401 *win_x = window ? winx : -1;
1403 *win_y = window ? winy : -1;
1409 gdk_window_get_children (GdkWindow *window)
1416 unsigned int nchildren;
1419 g_return_val_if_fail (window != NULL, NULL);
1420 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1422 if (GDK_DRAWABLE_DESTROYED (window))
1425 XQueryTree (GDK_DRAWABLE_XDISPLAY (window),
1426 GDK_DRAWABLE_XID (window),
1427 &root, &parent, &xchildren, &nchildren);
1433 for (i = 0; i < nchildren; i++)
1435 child = gdk_window_lookup (xchildren[i]);
1437 children = g_list_prepend (children, child);
1448 gdk_window_get_events (GdkWindow *window)
1450 XWindowAttributes attrs;
1451 GdkEventMask event_mask;
1454 g_return_val_if_fail (window != NULL, 0);
1455 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1457 if (GDK_DRAWABLE_DESTROYED (window))
1461 XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1462 GDK_DRAWABLE_XID (window),
1466 for (i = 0; i < gdk_nevent_masks; i++)
1468 if (attrs.your_event_mask & gdk_event_mask_table[i])
1469 event_mask |= 1 << (i + 1);
1477 gdk_window_set_events (GdkWindow *window,
1478 GdkEventMask event_mask)
1483 g_return_if_fail (window != NULL);
1484 g_return_if_fail (GDK_IS_WINDOW (window));
1486 if (!GDK_DRAWABLE_DESTROYED (window))
1488 xevent_mask = StructureNotifyMask;
1489 for (i = 0; i < gdk_nevent_masks; i++)
1491 if (event_mask & (1 << (i + 1)))
1492 xevent_mask |= gdk_event_mask_table[i];
1495 XSelectInput (GDK_DRAWABLE_XDISPLAY (window),
1496 GDK_DRAWABLE_XID (window),
1502 gdk_window_add_colormap_windows (GdkWindow *window)
1504 GdkWindow *toplevel;
1505 Window *old_windows;
1506 Window *new_windows;
1509 g_return_if_fail (window != NULL);
1510 g_return_if_fail (GDK_IS_WINDOW (window));
1512 toplevel = gdk_window_get_toplevel (window);
1513 if (GDK_DRAWABLE_DESTROYED (toplevel))
1517 if (!XGetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1518 GDK_DRAWABLE_XID (toplevel),
1519 &old_windows, &count))
1524 for (i = 0; i < count; i++)
1525 if (old_windows[i] == GDK_DRAWABLE_XID (window))
1527 XFree (old_windows);
1531 new_windows = g_new (Window, count + 1);
1533 for (i = 0; i < count; i++)
1534 new_windows[i] = old_windows[i];
1535 new_windows[count] = GDK_DRAWABLE_XID (window);
1537 XSetWMColormapWindows (GDK_DRAWABLE_XDISPLAY (toplevel),
1538 GDK_DRAWABLE_XID (toplevel),
1539 new_windows, count + 1);
1541 g_free (new_windows);
1543 XFree (old_windows);
1547 gdk_window_have_shape_ext (void)
1549 enum { UNKNOWN, NO, YES };
1550 static gint have_shape = UNKNOWN;
1552 if (have_shape == UNKNOWN)
1555 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1561 return (have_shape == YES);
1565 * This needs the X11 shape extension.
1566 * If not available, shaped windows will look
1567 * ugly, but programs still work. Stefan Wille
1570 gdk_window_shape_combine_mask (GdkWindow *window,
1576 g_return_if_fail (window != NULL);
1577 g_return_if_fail (GDK_IS_WINDOW (window));
1579 #ifdef HAVE_SHAPE_EXT
1580 if (GDK_DRAWABLE_DESTROYED (window))
1583 if (gdk_window_have_shape_ext ())
1587 pixmap = GDK_DRAWABLE_XID (mask);
1596 XShapeCombineMask (GDK_DRAWABLE_XDISPLAY (window),
1597 GDK_DRAWABLE_XID (window),
1603 #endif /* HAVE_SHAPE_EXT */
1607 gdk_window_set_override_redirect (GdkWindow *window,
1608 gboolean override_redirect)
1610 XSetWindowAttributes attr;
1612 g_return_if_fail (window != NULL);
1613 g_return_if_fail (GDK_IS_WINDOW (window));
1615 if (GDK_DRAWABLE_DESTROYED (window))
1617 attr.override_redirect = (override_redirect == FALSE)?False:True;
1618 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
1619 GDK_DRAWABLE_XID (window),
1626 gdk_window_set_icon (GdkWindow *window,
1627 GdkWindow *icon_window,
1633 g_return_if_fail (window != NULL);
1634 g_return_if_fail (GDK_IS_WINDOW (window));
1636 if (GDK_DRAWABLE_DESTROYED (window))
1639 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1640 GDK_DRAWABLE_XID (window));
1642 wm_hints = XAllocWMHints ();
1644 if (icon_window != NULL)
1646 wm_hints->flags |= IconWindowHint;
1647 wm_hints->icon_window = GDK_DRAWABLE_XID (icon_window);
1652 wm_hints->flags |= IconPixmapHint;
1653 wm_hints->icon_pixmap = GDK_DRAWABLE_XID (pixmap);
1658 wm_hints->flags |= IconMaskHint;
1659 wm_hints->icon_mask = GDK_DRAWABLE_XID (mask);
1662 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1663 GDK_DRAWABLE_XID (window), wm_hints);
1668 gdk_window_set_icon_name (GdkWindow *window,
1671 XTextProperty property;
1674 g_return_if_fail (window != NULL);
1675 g_return_if_fail (GDK_IS_WINDOW (window));
1677 if (GDK_DRAWABLE_DESTROYED (window))
1680 res = XmbTextListToTextProperty (GDK_DRAWABLE_XDISPLAY (window),
1681 &name, 1, XStdICCTextStyle,
1685 g_warning ("Error converting icon name to text property: %d\n", res);
1689 XSetWMIconName (GDK_DRAWABLE_XDISPLAY (window),
1690 GDK_DRAWABLE_XID (window),
1694 XFree (property.value);
1698 gdk_window_set_group (GdkWindow *window,
1703 g_return_if_fail (window != NULL);
1704 g_return_if_fail (GDK_IS_WINDOW (window));
1705 g_return_if_fail (leader != NULL);
1706 g_return_if_fail (GDK_IS_WINDOW (leader));
1708 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
1711 wm_hints = XGetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1712 GDK_DRAWABLE_XID (window));
1714 wm_hints = XAllocWMHints ();
1716 wm_hints->flags |= WindowGroupHint;
1717 wm_hints->window_group = GDK_DRAWABLE_XID (leader);
1719 XSetWMHints (GDK_DRAWABLE_XDISPLAY (window),
1720 GDK_DRAWABLE_XID (window), wm_hints);
1725 gdk_window_set_mwm_hints (GdkWindow *window,
1726 MotifWmHints *new_hints)
1728 static Atom hints_atom = None;
1729 MotifWmHints *hints;
1735 if (GDK_DRAWABLE_DESTROYED (window))
1739 hints_atom = XInternAtom (GDK_DRAWABLE_XDISPLAY (window),
1740 _XA_MOTIF_WM_HINTS, FALSE);
1742 XGetWindowProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1743 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
1744 False, AnyPropertyType, &type, &format, &nitems,
1745 &bytes_after, (guchar **)&hints);
1751 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1753 hints->flags |= MWM_HINTS_FUNCTIONS;
1754 hints->functions = new_hints->functions;
1756 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1758 hints->flags |= MWM_HINTS_DECORATIONS;
1759 hints->decorations = new_hints->decorations;
1763 XChangeProperty (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window),
1764 hints_atom, hints_atom, 32, PropModeReplace,
1765 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
1767 if (hints != new_hints)
1772 gdk_window_set_decorations (GdkWindow *window,
1773 GdkWMDecoration decorations)
1777 g_return_if_fail (window != NULL);
1778 g_return_if_fail (GDK_IS_WINDOW (window));
1780 hints.flags = MWM_HINTS_DECORATIONS;
1781 hints.decorations = decorations;
1783 gdk_window_set_mwm_hints (window, &hints);
1787 gdk_window_set_functions (GdkWindow *window,
1788 GdkWMFunction functions)
1792 g_return_if_fail (window != NULL);
1793 g_return_if_fail (GDK_IS_WINDOW (window));
1795 hints.flags = MWM_HINTS_FUNCTIONS;
1796 hints.functions = functions;
1798 gdk_window_set_mwm_hints (window, &hints);
1802 * propagate the shapes from all child windows of a GDK window to the parent
1803 * window. Shamelessly ripped from Enlightenment's code
1811 struct _gdk_span *next;
1815 gdk_add_to_span (struct _gdk_span **s,
1819 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
1826 /* scan the spans for this line */
1829 /* -- -> new span */
1830 /* == -> existing span */
1831 /* ## -> spans intersect */
1832 /* if we are in the middle of spanning the span into the line */
1835 /* case: ---- ==== */
1836 if (xx < ptr1->start - 1)
1838 /* ends before next span - extend to here */
1842 /* case: ----##=== */
1843 else if (xx <= ptr1->end)
1845 /* crosses into next span - delete next span and append */
1846 ss->end = ptr1->end;
1847 ss->next = ptr1->next;
1851 /* case: ---###--- */
1854 /* overlaps next span - delete and keep checking */
1855 ss->next = ptr1->next;
1860 /* otherwise havent started spanning it in yet */
1863 /* case: ---- ==== */
1864 if (xx < ptr1->start - 1)
1866 /* insert span here in list */
1867 noo = g_malloc (sizeof (struct _gdk_span));
1881 /* case: ----##=== */
1882 else if ((x < ptr1->start) && (xx <= ptr1->end))
1884 /* expand this span to the left point of the new one */
1888 /* case: ===###=== */
1889 else if ((x >= ptr1->start) && (xx <= ptr1->end))
1891 /* throw the span away */
1894 /* case: ---###--- */
1895 else if ((x < ptr1->start) && (xx > ptr1->end))
1902 /* case: ===##---- */
1903 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
1909 /* case: ==== ---- */
1910 /* case handled by next loop iteration - first case */
1915 /* it started in the middle but spans beyond your current list */
1921 /* it does not start inside a span or in the middle, so add it to the end */
1922 noo = g_malloc (sizeof (struct _gdk_span));
1930 noo->next = ptr2->next;
1943 gdk_add_rectangles (Display *disp,
1945 struct _gdk_span **spans,
1952 gint x1, y1, x2, y2;
1956 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
1959 /* go through all clip rects in this window's shape */
1960 for (k = 0; k < rn; k++)
1962 /* for each clip rect, add it to each line's spans */
1964 x2 = x + rl[k].x + (rl[k].width - 1);
1966 y2 = y + rl[k].y + (rl[k].height - 1);
1975 for (a = y1; a <= y2; a++)
1978 gdk_add_to_span (&spans[a], x1, x2);
1986 gdk_propagate_shapes (Display *disp,
1990 Window rt, par, *list = NULL;
1991 gint i, j, num = 0, num_rects = 0;
1995 XRectangle *rects = NULL;
1996 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
1997 XWindowAttributes xatt;
1999 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2004 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2006 for (i = 0; i < h; i++)
2008 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2011 /* go through all child windows and create/insert spans */
2012 for (i = 0; i < num; i++)
2014 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2015 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2016 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2019 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2021 /* go through the spans list and build a list of rects */
2022 rects = g_malloc (sizeof (XRectangle) * 256);
2024 for (i = 0; i < baseh; i++)
2027 /* go through the line for all spans */
2030 rects[num_rects].x = ptr1->start;
2031 rects[num_rects].y = i;
2032 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2033 rects[num_rects].height = 1;
2035 /* if there are more lines */
2037 /* while contigous rects (same start/end coords) exist */
2038 while ((contig) && (j < baseh))
2040 /* search next line for spans matching this one */
2046 /* if we have an exact span match set contig */
2047 if ((ptr2->start == ptr1->start) &&
2048 (ptr2->end == ptr1->end))
2051 /* remove the span - not needed */
2054 ptr3->next = ptr2->next;
2060 spans[j] = ptr2->next;
2066 /* gone past the span point no point looking */
2067 else if (ptr2->start < ptr1->start)
2075 /* if a contiguous span was found increase the rect h */
2078 rects[num_rects].height++;
2082 /* up the rect count */
2084 /* every 256 new rects increase the rect array */
2085 if ((num_rects % 256) == 0)
2086 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2090 /* set the rects as the shape mask */
2093 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2094 ShapeSet, YXSorted);
2099 /* free up all the spans we made */
2100 for (i = 0; i < baseh; i++)
2114 gdk_window_set_child_shapes (GdkWindow *window)
2116 g_return_if_fail (window != NULL);
2117 g_return_if_fail (GDK_IS_WINDOW (window));
2119 #ifdef HAVE_SHAPE_EXT
2120 if (!GDK_DRAWABLE_DESTROYED (window) &&
2121 gdk_window_have_shape_ext ())
2122 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2123 GDK_DRAWABLE_XID (window), FALSE);
2128 gdk_window_merge_child_shapes (GdkWindow *window)
2130 g_return_if_fail (window != NULL);
2131 g_return_if_fail (GDK_IS_WINDOW (window));
2133 #ifdef HAVE_SHAPE_EXT
2134 if (!GDK_DRAWABLE_DESTROYED (window) &&
2135 gdk_window_have_shape_ext ())
2136 gdk_propagate_shapes (GDK_DRAWABLE_XDISPLAY (window),
2137 GDK_DRAWABLE_XID (window), TRUE);
2141 /* Support for windows that can be guffaw-scrolled
2142 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2146 gdk_window_gravity_works (void)
2148 enum { UNKNOWN, NO, YES };
2149 static gint gravity_works = UNKNOWN;
2151 if (gravity_works == UNKNOWN)
2158 /* This particular server apparently has a bug so that the test
2159 * works but the actual code crashes it
2161 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2162 (VendorRelease (gdk_display) == 3400))
2168 attr.window_type = GDK_WINDOW_TEMP;
2169 attr.wclass = GDK_INPUT_OUTPUT;
2174 attr.event_mask = 0;
2176 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2178 attr.window_type = GDK_WINDOW_CHILD;
2179 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2181 gdk_window_set_static_win_gravity (child, TRUE);
2183 gdk_window_resize (parent, 100, 110);
2184 gdk_window_move (parent, 0, -10);
2185 gdk_window_move_resize (parent, 0, 0, 100, 100);
2187 gdk_window_resize (parent, 100, 110);
2188 gdk_window_move (parent, 0, -10);
2189 gdk_window_move_resize (parent, 0, 0, 100, 100);
2191 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2193 gdk_window_destroy (parent);
2194 gdk_window_destroy (child);
2196 gravity_works = ((y == -20) ? YES : NO);
2199 return (gravity_works == YES);
2203 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2205 XSetWindowAttributes xattributes;
2206 guint xattributes_mask = 0;
2208 g_return_if_fail (window != NULL);
2210 xattributes.bit_gravity = StaticGravity;
2211 xattributes_mask |= CWBitGravity;
2212 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2213 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2214 GDK_DRAWABLE_XID (window),
2215 CWBitGravity, &xattributes);
2219 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2221 XSetWindowAttributes xattributes;
2223 g_return_if_fail (window != NULL);
2225 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2227 XChangeWindowAttributes (GDK_DRAWABLE_XDISPLAY (window),
2228 GDK_DRAWABLE_XID (window),
2229 CWWinGravity, &xattributes);
2232 /*************************************************************
2233 * gdk_window_set_static_gravities:
2234 * Set the bit gravity of the given window to static,
2235 * and flag it so all children get static subwindow
2238 * window: window for which to set static gravity
2239 * use_static: Whether to turn static gravity on or off.
2241 * Does the XServer support static gravity?
2242 *************************************************************/
2245 gdk_window_set_static_gravities (GdkWindow *window,
2246 gboolean use_static)
2248 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2251 g_return_val_if_fail (window != NULL, FALSE);
2252 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2254 if (!use_static == !private->guffaw_gravity)
2257 if (use_static && !gdk_window_gravity_works ())
2260 private->guffaw_gravity = use_static;
2262 if (!GDK_DRAWABLE_DESTROYED (window))
2264 gdk_window_set_static_bit_gravity (window, use_static);
2266 tmp_list = private->children;
2269 gdk_window_set_static_win_gravity (window, use_static);
2271 tmp_list = tmp_list->next;
2278 /* internal function created for and used by gdk_window_xid_at_coords */
2280 gdk_window_xid_at (Window base,
2286 gboolean excl_child)
2289 Window *list = NULL;
2290 Window child = 0, parent_win = 0, root_win = 0;
2292 unsigned int ww, wh, wb, wd, num;
2295 xdisplay = GDK_DISPLAY ();
2296 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
2303 (x < (int) (wx + ww)) &&
2304 (y < (int) (wy + wh))))
2307 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
2312 for (i = num - 1; ; i--)
2314 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
2316 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
2331 * The following fucntion by The Rasterman <raster@redhat.com>
2332 * This function returns the X Window ID in which the x y location is in
2333 * (x and y being relative to the root window), excluding any windows listed
2334 * in the GList excludes (this is a list of X Window ID's - gpointer being
2337 * This is primarily designed for internal gdk use - for DND for example
2338 * when using a shaped icon window as the drag object - you exclude the
2339 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
2340 * You can get back an X Window ID as to what X Window ID is infact under
2341 * those X,Y co-ordinates.
2344 gdk_window_xid_at_coords (gint x,
2347 gboolean excl_child)
2350 GdkDrawablePrivate *private;
2352 Window *list = NULL;
2353 Window root, child = 0, parent_win = 0, root_win = 0;
2357 window = gdk_parent_root;
2358 private = (GdkDrawablePrivate*) window;
2359 xdisplay = GDK_DRAWABLE_XDISPLAY (private);
2360 root = GDK_DRAWABLE_XID (private);
2361 num = g_list_length (excludes);
2363 XGrabServer (xdisplay);
2364 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
2366 XUngrabServer (xdisplay);
2374 XWindowAttributes xwa;
2376 XGetWindowAttributes (xdisplay, list [i], &xwa);
2378 if (xwa.map_state != IsViewable)
2381 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
2384 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
2389 if (!g_list_find (excludes, (gpointer *) child))
2392 XUngrabServer (xdisplay);
2399 XUngrabServer (xdisplay);
2405 XUngrabServer (xdisplay);