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 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
23 #include <netinet/in.h>
27 #include "gdkprivate.h"
44 #include <X11/extensions/shape.h>
47 const int gdk_event_mask_table[20] =
51 PointerMotionHintMask,
56 ButtonPressMask | OwnerGrabButtonMask,
57 ButtonReleaseMask | OwnerGrabButtonMask,
68 SubstructureNotifyMask
70 const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int);
72 static gboolean gdk_window_have_shape_ext (void);
74 /* internal function created for and used by gdk_window_xid_at_coords */
76 gdk_window_xid_at (Window base,
85 GdkWindowPrivate *private;
88 Window child = 0, parent_win = 0, root_win = 0;
90 unsigned int ww, wh, wb, wd, num;
93 window = (GdkWindow*) &gdk_root_parent;
94 private = (GdkWindowPrivate*) window;
95 disp = private->xdisplay;
96 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
103 (x < (int) (wx + ww)) &&
104 (y < (int) (wy + wh))))
107 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
112 for (i = num - 1; ; i--)
114 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
116 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
131 * The following fucntion by The Rasterman <raster@redhat.com>
132 * This function returns the X Window ID in which the x y location is in
133 * (x and y being relative to the root window), excluding any windows listed
134 * in the GList excludes (this is a list of X Window ID's - gpointer being
137 * This is primarily designed for internal gdk use - for DND for example
138 * when using a shaped icon window as the drag object - you exclude the
139 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
140 * You can get back an X Window ID as to what X Window ID is infact under
141 * those X,Y co-ordinates.
144 gdk_window_xid_at_coords (gint x,
150 GdkWindowPrivate *private;
153 Window root, child = 0, parent_win = 0, root_win = 0;
157 window = (GdkWindow*) &gdk_root_parent;
158 private = (GdkWindowPrivate*) window;
159 disp = private->xdisplay;
160 root = private->xwindow;
161 num = g_list_length (excludes);
164 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
174 XWindowAttributes xwa;
176 XGetWindowAttributes (disp, list [i], &xwa);
178 if (xwa.map_state != IsViewable)
181 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
184 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
189 if (!g_list_find (excludes, (gpointer *) child))
192 XUngrabServer (disp);
199 XUngrabServer (disp);
205 XUngrabServer (disp);
210 gdk_window_init (void)
212 XWindowAttributes xattributes;
215 unsigned int border_width;
219 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
220 &x, &y, &width, &height, &border_width, &depth);
221 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
223 gdk_root_parent.xwindow = gdk_root_window;
224 gdk_root_parent.xdisplay = gdk_display;
225 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
226 gdk_root_parent.window.user_data = NULL;
227 gdk_root_parent.width = width;
228 gdk_root_parent.height = height;
229 gdk_root_parent.children = NULL;
230 gdk_root_parent.colormap = NULL;
231 gdk_root_parent.ref_count = 1;
233 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
237 gdk_window_new (GdkWindow *parent,
238 GdkWindowAttr *attributes,
239 gint attributes_mask)
242 GdkWindowPrivate *private;
243 GdkWindowPrivate *parent_private;
245 Display *parent_display;
248 XSetWindowAttributes xattributes;
249 long xattributes_mask;
250 XSizeHints size_hints;
252 XClassHint *class_hint;
258 g_return_val_if_fail (attributes != NULL, NULL);
261 parent = (GdkWindow*) &gdk_root_parent;
263 parent_private = (GdkWindowPrivate*) parent;
264 if (parent_private->destroyed)
267 xparent = parent_private->xwindow;
268 parent_display = parent_private->xdisplay;
270 private = g_new (GdkWindowPrivate, 1);
271 window = (GdkWindow*) private;
273 private->parent = parent;
276 parent_private->children = g_list_prepend (parent_private->children, window);
278 private->xdisplay = parent_display;
279 private->destroyed = FALSE;
280 private->mapped = FALSE;
281 private->resize_count = 0;
282 private->ref_count = 1;
283 xattributes_mask = 0;
285 if (attributes_mask & GDK_WA_X)
290 if (attributes_mask & GDK_WA_Y)
297 private->width = (attributes->width > 1) ? (attributes->width) : (1);
298 private->height = (attributes->height > 1) ? (attributes->height) : (1);
299 private->window_type = attributes->window_type;
300 private->extension_events = FALSE;
302 private->filters = NULL;
303 private->children = NULL;
305 window->user_data = NULL;
307 if (attributes_mask & GDK_WA_VISUAL)
308 visual = attributes->visual;
310 visual = gdk_visual_get_system ();
311 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
313 xattributes.event_mask = StructureNotifyMask;
314 for (i = 0; i < gdk_nevent_masks; i++)
316 if (attributes->event_mask & (1 << (i + 1)))
317 xattributes.event_mask |= gdk_event_mask_table[i];
320 if (xattributes.event_mask)
321 xattributes_mask |= CWEventMask;
323 if(attributes_mask & GDK_WA_NOREDIR) {
324 xattributes.override_redirect =
325 (attributes->override_redirect == FALSE)?False:True;
326 xattributes_mask |= CWOverrideRedirect;
328 xattributes.override_redirect = False;
330 if (attributes->wclass == GDK_INPUT_OUTPUT)
333 depth = visual->depth;
335 if (attributes_mask & GDK_WA_COLORMAP)
336 private->colormap = attributes->colormap;
339 if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
340 private->colormap = gdk_colormap_get_system ();
342 private->colormap = gdk_colormap_new (visual, False);
345 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
346 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
347 xattributes_mask |= CWBorderPixel | CWBackPixel;
349 switch (private->window_type)
351 case GDK_WINDOW_TOPLEVEL:
352 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
353 xattributes_mask |= CWColormap;
355 xparent = gdk_root_window;
358 case GDK_WINDOW_CHILD:
359 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
360 xattributes_mask |= CWColormap;
363 case GDK_WINDOW_DIALOG:
364 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
365 xattributes_mask |= CWColormap;
367 xparent = gdk_root_window;
370 case GDK_WINDOW_TEMP:
371 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
372 xattributes_mask |= CWColormap;
374 xparent = gdk_root_window;
376 xattributes.save_under = True;
377 xattributes.override_redirect = True;
378 xattributes.cursor = None;
379 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
381 case GDK_WINDOW_ROOT:
382 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
384 case GDK_WINDOW_PIXMAP:
385 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
393 private->colormap = NULL;
396 private->xwindow = XCreateWindow (private->xdisplay, xparent,
397 x, y, private->width, private->height,
398 0, depth, class, xvisual,
399 xattributes_mask, &xattributes);
400 gdk_window_ref (window);
401 gdk_xid_table_insert (&private->xwindow, window);
403 if (private->colormap)
404 gdk_colormap_ref (private->colormap);
406 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
407 (attributes->cursor) :
410 switch (private->window_type)
412 case GDK_WINDOW_DIALOG:
413 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
414 case GDK_WINDOW_TOPLEVEL:
415 case GDK_WINDOW_TEMP:
416 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
418 case GDK_WINDOW_CHILD:
419 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
420 (private->colormap != gdk_colormap_get_system ()) &&
421 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
423 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
424 gdk_window_add_colormap_windows (window);
433 size_hints.flags = PSize;
434 size_hints.width = private->width;
435 size_hints.height = private->height;
437 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
438 wm_hints.window_group = gdk_leader_window;
439 wm_hints.input = True;
440 wm_hints.initial_state = NormalState;
442 /* FIXME: Is there any point in doing this? Do any WM's pay
443 * attention to PSize, and even if they do, is this the
446 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
448 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
450 if (attributes_mask & GDK_WA_TITLE)
451 title = attributes->title;
453 title = g_get_prgname ();
455 XmbSetWMProperties (private->xdisplay, private->xwindow,
460 if (attributes_mask & GDK_WA_WMCLASS)
462 class_hint = XAllocClassHint ();
463 class_hint->res_name = attributes->wmclass_name;
464 class_hint->res_class = attributes->wmclass_class;
465 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
474 gdk_window_foreign_new (guint32 anid)
477 GdkWindowPrivate *private;
478 GdkWindowPrivate *parent_private;
479 XWindowAttributes attrs;
481 Window *children = NULL;
484 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
485 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
489 private = g_new (GdkWindowPrivate, 1);
490 window = (GdkWindow*) private;
492 /* FIXME: This is pretty expensive. Maybe the caller should supply
494 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
498 private->parent = gdk_xid_table_lookup (parent);
500 parent_private = (GdkWindowPrivate *)private->parent;
503 parent_private->children = g_list_prepend (parent_private->children, window);
505 private->xwindow = anid;
506 private->xdisplay = gdk_display;
507 private->x = attrs.x;
508 private->y = attrs.y;
509 private->width = attrs.width;
510 private->height = attrs.height;
511 private->resize_count = 0;
512 private->ref_count = 1;
513 private->window_type = GDK_WINDOW_FOREIGN;
514 private->destroyed = FALSE;
515 private->mapped = (attrs.map_state != IsUnmapped);
516 private->extension_events = 0;
518 private->colormap = NULL;
520 private->filters = NULL;
521 private->children = NULL;
523 window->user_data = NULL;
525 gdk_window_ref (window);
526 gdk_xid_table_insert (&private->xwindow, window);
531 /* Call this function when you want a window and all its children to
532 * disappear. When xdestroy is true, a request to destroy the XWindow
533 * is sent out. When it is false, it is assumed that the XWindow has
534 * been or will be destroyed by destroying some ancestor of this
538 gdk_window_internal_destroy (GdkWindow *window,
540 gboolean our_destroy)
542 GdkWindowPrivate *private;
543 GdkWindowPrivate *temp_private;
544 GdkWindow *temp_window;
548 g_return_if_fail (window != NULL);
550 private = (GdkWindowPrivate*) window;
552 switch (private->window_type)
554 case GDK_WINDOW_TOPLEVEL:
555 case GDK_WINDOW_CHILD:
556 case GDK_WINDOW_DIALOG:
557 case GDK_WINDOW_TEMP:
558 case GDK_WINDOW_FOREIGN:
559 if (!private->destroyed)
563 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
564 if (parent_private->children)
565 parent_private->children = g_list_remove (parent_private->children, window);
568 if (private->window_type != GDK_WINDOW_FOREIGN)
570 children = tmp = private->children;
571 private->children = NULL;
575 temp_window = tmp->data;
578 temp_private = (GdkWindowPrivate*) temp_window;
580 gdk_window_internal_destroy (temp_window, FALSE,
584 g_list_free (children);
587 if (private->extension_events != 0)
588 gdk_input_window_destroy (window);
590 if (private->filters)
592 tmp = private->filters;
600 g_list_free (private->filters);
601 private->filters = NULL;
604 if (private->window_type == GDK_WINDOW_FOREIGN)
606 if (our_destroy && (private->parent != NULL))
608 /* It's somebody elses window, but in our heirarchy,
609 * so reparent it to the root window, and then send
610 * it a delete event, as if we were a WM
612 XClientMessageEvent xevent;
614 gdk_window_hide (window);
615 gdk_window_reparent (window, NULL, 0, 0);
617 xevent.type = ClientMessage;
618 xevent.window = private->xwindow;
619 xevent.message_type = gdk_wm_protocols;
621 xevent.data.l[0] = gdk_wm_delete_window;
622 xevent.data.l[1] = CurrentTime;
624 XSendEvent (private->xdisplay, private->xwindow,
625 False, 0, (XEvent *)&xevent);
629 XDestroyWindow (private->xdisplay, private->xwindow);
631 if (private->colormap)
632 gdk_colormap_unref (private->colormap);
634 private->mapped = FALSE;
635 private->destroyed = TRUE;
639 case GDK_WINDOW_ROOT:
640 g_error ("attempted to destroy root window");
643 case GDK_WINDOW_PIXMAP:
644 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
649 /* Like internal_destroy, but also destroys the reference created by
653 gdk_window_destroy (GdkWindow *window)
655 gdk_window_internal_destroy (window, TRUE, TRUE);
656 gdk_window_unref (window);
659 /* This function is called when the XWindow is really gone. */
662 gdk_window_destroy_notify (GdkWindow *window)
664 GdkWindowPrivate *private;
666 g_return_if_fail (window != NULL);
668 private = (GdkWindowPrivate*) window;
670 if (!private->destroyed)
672 if (private->window_type == GDK_WINDOW_FOREIGN)
673 gdk_window_internal_destroy (window, FALSE, FALSE);
675 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
678 gdk_xid_table_remove (private->xwindow);
679 gdk_window_unref (window);
683 gdk_window_ref (GdkWindow *window)
685 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
686 g_return_val_if_fail (window != NULL, NULL);
688 private->ref_count += 1;
693 gdk_window_unref (GdkWindow *window)
695 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
696 g_return_if_fail (window != NULL);
698 private->ref_count -= 1;
699 if (private->ref_count == 0)
701 if (!private->destroyed)
703 if (private->window_type == GDK_WINDOW_FOREIGN)
704 gdk_xid_table_remove (private->xwindow);
706 g_warning ("losing last reference to undestroyed window\n");
708 g_dataset_destroy (window);
714 gdk_window_show (GdkWindow *window)
716 GdkWindowPrivate *private;
718 g_return_if_fail (window != NULL);
720 private = (GdkWindowPrivate*) window;
721 if (!private->destroyed && !private->mapped)
723 private->mapped = TRUE;
724 XRaiseWindow (private->xdisplay, private->xwindow);
725 XMapWindow (private->xdisplay, private->xwindow);
730 gdk_window_hide (GdkWindow *window)
732 GdkWindowPrivate *private;
734 g_return_if_fail (window != NULL);
736 private = (GdkWindowPrivate*) window;
737 if (!private->destroyed && private->mapped)
739 private->mapped = FALSE;
740 XUnmapWindow (private->xdisplay, private->xwindow);
745 gdk_window_withdraw (GdkWindow *window)
747 GdkWindowPrivate *private;
749 g_return_if_fail (window != NULL);
751 private = (GdkWindowPrivate*) window;
752 if (!private->destroyed)
753 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
757 gdk_window_move (GdkWindow *window,
761 GdkWindowPrivate *private;
763 g_return_if_fail (window != NULL);
765 private = (GdkWindowPrivate*) window;
766 if (!private->destroyed)
768 XMoveWindow (private->xdisplay, private->xwindow, x, y);
770 if (private->window_type == GDK_WINDOW_CHILD)
779 gdk_window_resize (GdkWindow *window,
783 GdkWindowPrivate *private;
785 g_return_if_fail (window != NULL);
792 private = (GdkWindowPrivate*) window;
794 if (!private->destroyed &&
795 ((private->resize_count > 0) ||
796 (private->width != (guint16) width) ||
797 (private->height != (guint16) height)))
799 XResizeWindow (private->xdisplay, private->xwindow, width, height);
800 private->resize_count += 1;
802 if (private->window_type == GDK_WINDOW_CHILD)
804 private->width = width;
805 private->height = height;
811 gdk_window_move_resize (GdkWindow *window,
817 GdkWindowPrivate *private;
819 g_return_if_fail (window != NULL);
826 private = (GdkWindowPrivate*) window;
827 if (!private->destroyed)
829 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
831 if (private->window_type == GDK_WINDOW_CHILD)
835 private->width = width;
836 private->height = height;
842 gdk_window_reparent (GdkWindow *window,
843 GdkWindow *new_parent,
847 GdkWindowPrivate *window_private;
848 GdkWindowPrivate *parent_private;
849 GdkWindowPrivate *old_parent_private;
851 g_return_if_fail (window != NULL);
854 new_parent = (GdkWindow*) &gdk_root_parent;
856 window_private = (GdkWindowPrivate*) window;
857 old_parent_private = (GdkWindowPrivate*)window_private->parent;
858 parent_private = (GdkWindowPrivate*) new_parent;
860 if (!window_private->destroyed && !parent_private->destroyed)
861 XReparentWindow (window_private->xdisplay,
862 window_private->xwindow,
863 parent_private->xwindow,
866 window_private->parent = new_parent;
868 if (old_parent_private)
869 old_parent_private->children = g_list_remove (old_parent_private->children, window);
870 parent_private->children = g_list_prepend (parent_private->children, window);
875 gdk_window_clear (GdkWindow *window)
877 GdkWindowPrivate *private;
879 g_return_if_fail (window != NULL);
881 private = (GdkWindowPrivate*) window;
883 if (!private->destroyed)
884 XClearWindow (private->xdisplay, private->xwindow);
888 gdk_window_clear_area (GdkWindow *window,
894 GdkWindowPrivate *private;
896 g_return_if_fail (window != NULL);
898 private = (GdkWindowPrivate*) window;
900 if (!private->destroyed)
901 XClearArea (private->xdisplay, private->xwindow,
902 x, y, width, height, False);
906 gdk_window_clear_area_e (GdkWindow *window,
912 GdkWindowPrivate *private;
914 g_return_if_fail (window != NULL);
916 private = (GdkWindowPrivate*) window;
918 if (!private->destroyed)
919 XClearArea (private->xdisplay, private->xwindow,
920 x, y, width, height, True);
924 gdk_window_copy_area (GdkWindow *window,
928 GdkWindow *source_window,
934 GdkWindowPrivate *src_private;
935 GdkWindowPrivate *dest_private;
936 GdkGCPrivate *gc_private;
938 g_return_if_fail (window != NULL);
939 g_return_if_fail (gc != NULL);
941 if (source_window == NULL)
942 source_window = window;
944 src_private = (GdkWindowPrivate*) source_window;
945 dest_private = (GdkWindowPrivate*) window;
946 gc_private = (GdkGCPrivate*) gc;
948 if (!src_private->destroyed && !dest_private->destroyed)
950 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
959 gdk_window_raise (GdkWindow *window)
961 GdkWindowPrivate *private;
963 g_return_if_fail (window != NULL);
965 private = (GdkWindowPrivate*) window;
967 if (!private->destroyed)
968 XRaiseWindow (private->xdisplay, private->xwindow);
972 gdk_window_lower (GdkWindow *window)
974 GdkWindowPrivate *private;
976 g_return_if_fail (window != NULL);
978 private = (GdkWindowPrivate*) window;
980 if (!private->destroyed)
981 XLowerWindow (private->xdisplay, private->xwindow);
985 gdk_window_set_user_data (GdkWindow *window,
988 g_return_if_fail (window != NULL);
990 window->user_data = user_data;
994 gdk_window_set_hints (GdkWindow *window,
1003 GdkWindowPrivate *private;
1004 XSizeHints size_hints;
1006 g_return_if_fail (window != NULL);
1008 private = (GdkWindowPrivate*) window;
1009 if (private->destroyed)
1012 size_hints.flags = 0;
1014 if (flags & GDK_HINT_POS)
1016 size_hints.flags |= PPosition;
1021 if (flags & GDK_HINT_MIN_SIZE)
1023 size_hints.flags |= PMinSize;
1024 size_hints.min_width = min_width;
1025 size_hints.min_height = min_height;
1028 if (flags & GDK_HINT_MAX_SIZE)
1030 size_hints.flags |= PMaxSize;
1031 size_hints.max_width = max_width;
1032 size_hints.max_height = max_height;
1036 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1040 gdk_window_set_geometry_hints (GdkWindow *window,
1041 GdkGeometry *geometry,
1042 GdkWindowHints geom_mask)
1044 GdkWindowPrivate *private;
1045 XSizeHints size_hints;
1047 g_return_if_fail (window != NULL);
1049 private = (GdkWindowPrivate*) window;
1050 if (private->destroyed)
1053 size_hints.flags = 0;
1055 if (geom_mask & GDK_HINT_POS)
1056 size_hints.flags |= PPosition;
1058 if (geom_mask & GDK_HINT_MIN_SIZE)
1060 size_hints.flags |= PMinSize;
1061 size_hints.min_width = geometry->min_width;
1062 size_hints.min_height = geometry->min_height;
1065 if (geom_mask & GDK_HINT_MAX_SIZE)
1067 size_hints.flags |= PMaxSize;
1068 size_hints.max_width = geometry->max_width;
1069 size_hints.max_height = geometry->max_height;
1072 if (geom_mask & GDK_HINT_BASE_SIZE)
1074 size_hints.flags |= PBaseSize;
1075 size_hints.base_width = geometry->base_width;
1076 size_hints.base_height = geometry->base_height;
1079 if (geom_mask & GDK_HINT_RESIZE_INC)
1081 size_hints.flags |= PResizeInc;
1082 size_hints.width_inc = geometry->width_inc;
1083 size_hints.height_inc = geometry->height_inc;
1086 if (geom_mask & GDK_HINT_ASPECT)
1088 size_hints.flags |= PAspect;
1089 if (geometry->min_aspect <= 1)
1091 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1092 size_hints.min_aspect.y = G_MAXINT;
1096 size_hints.min_aspect.x = G_MAXINT;
1097 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1099 if (geometry->max_aspect <= 1)
1101 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1102 size_hints.max_aspect.y = G_MAXINT;
1106 size_hints.max_aspect.x = G_MAXINT;
1107 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1112 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1116 gdk_window_set_title (GdkWindow *window,
1119 GdkWindowPrivate *private;
1121 g_return_if_fail (window != NULL);
1123 private = (GdkWindowPrivate*) window;
1124 if (!private->destroyed)
1125 XmbSetWMProperties (private->xdisplay, private->xwindow,
1126 title, title, NULL, 0, NULL, NULL, NULL);
1130 gdk_window_set_role (GdkWindow *window,
1133 GdkWindowPrivate *private;
1135 g_return_if_fail (window != NULL);
1137 private = (GdkWindowPrivate*) window;
1140 XChangeProperty (private->xdisplay, private->xwindow,
1141 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1142 8, PropModeReplace, role, strlen(role));
1144 XDeleteProperty (private->xdisplay, private->xwindow,
1145 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1149 gdk_window_set_transient_for (GdkWindow *window,
1152 GdkWindowPrivate *private;
1153 GdkWindowPrivate *parent_private;
1155 g_return_if_fail (window != NULL);
1157 private = (GdkWindowPrivate*) window;
1158 parent_private = (GdkWindowPrivate*) parent;
1160 if (!private->destroyed && !parent_private->destroyed)
1161 XSetTransientForHint (private->xdisplay,
1162 private->xwindow, parent_private->xwindow);
1166 gdk_window_set_background (GdkWindow *window,
1169 GdkWindowPrivate *private;
1171 g_return_if_fail (window != NULL);
1173 private = (GdkWindowPrivate*) window;
1174 if (!private->destroyed)
1175 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1179 gdk_window_set_back_pixmap (GdkWindow *window,
1181 gint parent_relative)
1183 GdkWindowPrivate *window_private;
1184 GdkPixmapPrivate *pixmap_private;
1187 g_return_if_fail (window != NULL);
1189 window_private = (GdkWindowPrivate*) window;
1190 pixmap_private = (GdkPixmapPrivate*) pixmap;
1193 xpixmap = pixmap_private->xwindow;
1197 if (parent_relative)
1198 xpixmap = ParentRelative;
1200 if (!window_private->destroyed)
1201 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1205 gdk_window_set_cursor (GdkWindow *window,
1208 GdkWindowPrivate *window_private;
1209 GdkCursorPrivate *cursor_private;
1212 g_return_if_fail (window != NULL);
1214 window_private = (GdkWindowPrivate*) window;
1215 cursor_private = (GdkCursorPrivate*) cursor;
1220 xcursor = cursor_private->xcursor;
1222 if (!window_private->destroyed)
1223 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1227 gdk_window_set_colormap (GdkWindow *window,
1228 GdkColormap *colormap)
1230 GdkWindowPrivate *window_private;
1231 GdkColormapPrivate *colormap_private;
1233 g_return_if_fail (window != NULL);
1234 g_return_if_fail (colormap != NULL);
1236 window_private = (GdkWindowPrivate*) window;
1237 colormap_private = (GdkColormapPrivate*) colormap;
1239 if (!window_private->destroyed)
1241 XSetWindowColormap (window_private->xdisplay,
1242 window_private->xwindow,
1243 colormap_private->xcolormap);
1245 if (window_private->colormap)
1246 gdk_colormap_unref (window_private->colormap);
1247 window_private->colormap = colormap;
1248 gdk_colormap_ref (window_private->colormap);
1250 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1251 gdk_window_add_colormap_windows (window);
1256 gdk_window_get_user_data (GdkWindow *window,
1259 g_return_if_fail (window != NULL);
1261 *data = window->user_data;
1265 gdk_window_get_geometry (GdkWindow *window,
1272 GdkWindowPrivate *window_private;
1278 guint tborder_width;
1282 window = (GdkWindow*) &gdk_root_parent;
1284 window_private = (GdkWindowPrivate*) window;
1286 if (!window_private->destroyed)
1288 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1289 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1305 gdk_window_get_position (GdkWindow *window,
1309 GdkWindowPrivate *window_private;
1311 g_return_if_fail (window != NULL);
1313 window_private = (GdkWindowPrivate*) window;
1316 *x = window_private->x;
1318 *y = window_private->y;
1322 gdk_window_get_size (GdkWindow *window,
1326 GdkWindowPrivate *window_private;
1328 g_return_if_fail (window != NULL);
1330 window_private = (GdkWindowPrivate*) window;
1333 *width = window_private->width;
1335 *height = window_private->height;
1339 gdk_window_get_visual (GdkWindow *window)
1341 GdkWindowPrivate *window_private;
1342 XWindowAttributes window_attributes;
1344 g_return_val_if_fail (window != NULL, NULL);
1346 window_private = (GdkWindowPrivate*) window;
1347 /* Huh? ->parent is never set for a pixmap. We should just return
1350 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1351 window_private = (GdkWindowPrivate*) window_private->parent;
1353 if (window_private && !window_private->destroyed)
1355 if (window_private->colormap == NULL)
1357 XGetWindowAttributes (window_private->xdisplay,
1358 window_private->xwindow,
1359 &window_attributes);
1360 return gdk_visual_lookup (window_attributes.visual);
1363 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1370 gdk_window_get_colormap (GdkWindow *window)
1372 GdkWindowPrivate *window_private;
1373 XWindowAttributes window_attributes;
1375 g_return_val_if_fail (window != NULL, NULL);
1376 window_private = (GdkWindowPrivate*) window;
1378 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1379 if (!window_private->destroyed)
1381 if (window_private->colormap == NULL)
1383 XGetWindowAttributes (window_private->xdisplay,
1384 window_private->xwindow,
1385 &window_attributes);
1386 return gdk_colormap_lookup (window_attributes.colormap);
1389 return window_private->colormap;
1396 gdk_window_get_type (GdkWindow *window)
1398 GdkWindowPrivate *window_private;
1400 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1402 window_private = (GdkWindowPrivate*) window;
1403 return window_private->window_type;
1407 gdk_window_get_origin (GdkWindow *window,
1411 GdkWindowPrivate *private;
1417 g_return_val_if_fail (window != NULL, 0);
1419 private = (GdkWindowPrivate*) window;
1421 if (!private->destroyed)
1423 return_val = XTranslateCoordinates (private->xdisplay,
1442 gdk_window_get_deskrelative_origin (GdkWindow *window,
1446 GdkWindowPrivate *private;
1447 gboolean return_val = FALSE;
1448 gint num_children, format_return;
1449 Window win, *child, parent, root;
1453 static Atom atom = 0;
1454 gulong number_return, bytes_after_return;
1455 guchar *data_return;
1457 g_return_val_if_fail (window != NULL, 0);
1459 private = (GdkWindowPrivate*) window;
1461 if (!private->destroyed)
1464 atom = XInternAtom(private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1465 win = private->xwindow;
1467 while (XQueryTree(private->xdisplay, win, &root, &parent,
1468 &child, (unsigned int *)&num_children))
1470 if ((child) && (num_children > 0))
1482 XGetWindowProperty(private->xdisplay, win, atom, 0, 0,
1483 False, XA_CARDINAL, &type_return, &format_return,
1484 &number_return, &bytes_after_return, &data_return);
1485 if (type_return == XA_CARDINAL)
1492 return_val = XTranslateCoordinates (private->xdisplay,
1508 gdk_window_get_root_origin (GdkWindow *window,
1512 GdkWindowPrivate *private;
1517 unsigned int nchildren;
1519 g_return_if_fail (window != NULL);
1521 private = (GdkWindowPrivate*) window;
1526 if (private->destroyed)
1529 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1530 private = (GdkWindowPrivate*) private->parent;
1531 if (private->destroyed)
1534 xparent = private->xwindow;
1538 if (!XQueryTree (private->xdisplay, xwindow,
1540 &children, &nchildren))
1546 while (xparent != root);
1548 if (xparent == root)
1550 unsigned int ww, wh, wb, wd;
1553 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1564 gdk_window_get_pointer (GdkWindow *window,
1567 GdkModifierType *mask)
1569 GdkWindowPrivate *private;
1570 GdkWindow *return_val;
1576 unsigned int xmask = 0;
1579 window = (GdkWindow*) &gdk_root_parent;
1581 private = (GdkWindowPrivate*) window;
1584 if (!private->destroyed &&
1585 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1586 &rootx, &rooty, &winx, &winy, &xmask))
1589 return_val = gdk_window_lookup (child);
1603 gdk_window_at_pointer (gint *win_x,
1606 GdkWindowPrivate *private;
1610 Window xwindow_last = 0;
1611 int rootx = -1, rooty = -1;
1615 private = &gdk_root_parent;
1617 xwindow = private->xwindow;
1619 XGrabServer (private->xdisplay);
1622 xwindow_last = xwindow;
1623 XQueryPointer (private->xdisplay,
1630 XUngrabServer (private->xdisplay);
1632 window = gdk_window_lookup (xwindow_last);
1635 *win_x = window ? winx : -1;
1637 *win_y = window ? winy : -1;
1643 gdk_window_get_parent (GdkWindow *window)
1645 g_return_val_if_fail (window != NULL, NULL);
1647 return ((GdkWindowPrivate*) window)->parent;
1651 gdk_window_get_toplevel (GdkWindow *window)
1653 GdkWindowPrivate *private;
1655 g_return_val_if_fail (window != NULL, NULL);
1657 private = (GdkWindowPrivate*) window;
1659 while (private->window_type == GDK_WINDOW_CHILD)
1661 window = ((GdkWindowPrivate*) window)->parent;
1662 private = (GdkWindowPrivate*) window;
1669 gdk_window_get_children (GdkWindow *window)
1671 GdkWindowPrivate *private;
1677 unsigned int nchildren;
1680 g_return_val_if_fail (window != NULL, NULL);
1682 private = (GdkWindowPrivate*) window;
1683 if (private->destroyed)
1686 XQueryTree (private->xdisplay, private->xwindow,
1687 &root, &parent, &xchildren, &nchildren);
1693 for (i = 0; i < nchildren; i++)
1695 child = gdk_window_lookup (xchildren[i]);
1697 children = g_list_prepend (children, child);
1708 gdk_window_get_events (GdkWindow *window)
1710 GdkWindowPrivate *private;
1711 XWindowAttributes attrs;
1712 GdkEventMask event_mask;
1715 g_return_val_if_fail (window != NULL, 0);
1717 private = (GdkWindowPrivate*) window;
1718 if (private->destroyed)
1721 XGetWindowAttributes (gdk_display, private->xwindow,
1725 for (i = 0; i < gdk_nevent_masks; i++)
1727 if (attrs.your_event_mask & gdk_event_mask_table[i])
1728 event_mask |= 1 << (i + 1);
1735 gdk_window_set_events (GdkWindow *window,
1736 GdkEventMask event_mask)
1738 GdkWindowPrivate *private;
1742 g_return_if_fail (window != NULL);
1744 private = (GdkWindowPrivate*) window;
1745 if (private->destroyed)
1748 xevent_mask = StructureNotifyMask;
1749 for (i = 0; i < gdk_nevent_masks; i++)
1751 if (event_mask & (1 << (i + 1)))
1752 xevent_mask |= gdk_event_mask_table[i];
1755 XSelectInput (gdk_display, private->xwindow,
1760 gdk_window_add_colormap_windows (GdkWindow *window)
1762 GdkWindow *toplevel;
1763 GdkWindowPrivate *toplevel_private;
1764 GdkWindowPrivate *window_private;
1765 Window *old_windows;
1766 Window *new_windows;
1769 g_return_if_fail (window != NULL);
1771 toplevel = gdk_window_get_toplevel (window);
1772 toplevel_private = (GdkWindowPrivate*) toplevel;
1773 window_private = (GdkWindowPrivate*) window;
1774 if (window_private->destroyed)
1778 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1779 toplevel_private->xwindow,
1780 &old_windows, &count))
1785 for (i = 0; i < count; i++)
1786 if (old_windows[i] == window_private->xwindow)
1788 XFree (old_windows);
1792 new_windows = g_new (Window, count + 1);
1794 for (i = 0; i < count; i++)
1795 new_windows[i] = old_windows[i];
1796 new_windows[count] = window_private->xwindow;
1798 XSetWMColormapWindows (toplevel_private->xdisplay,
1799 toplevel_private->xwindow,
1800 new_windows, count + 1);
1802 g_free (new_windows);
1804 XFree (old_windows);
1808 gdk_window_have_shape_ext (void)
1810 enum { UNKNOWN, NO, YES };
1811 static gint have_shape = UNKNOWN;
1813 if (have_shape == UNKNOWN)
1816 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1822 return (have_shape == YES);
1826 * This needs the X11 shape extension.
1827 * If not available, shaped windows will look
1828 * ugly, but programs still work. Stefan Wille
1831 gdk_window_shape_combine_mask (GdkWindow *window,
1835 GdkWindowPrivate *window_private;
1838 g_return_if_fail (window != NULL);
1840 #ifdef HAVE_SHAPE_EXT
1841 window_private = (GdkWindowPrivate*) window;
1842 if (window_private->destroyed)
1845 if (gdk_window_have_shape_ext())
1849 GdkWindowPrivate *pixmap_private;
1851 pixmap_private = (GdkWindowPrivate*) mask;
1852 pixmap = (Pixmap) pixmap_private->xwindow;
1861 XShapeCombineMask (window_private->xdisplay,
1862 window_private->xwindow,
1868 #endif /* HAVE_SHAPE_EXT */
1872 gdk_window_add_filter (GdkWindow *window,
1873 GdkFilterFunc function,
1876 GdkWindowPrivate *private;
1878 GdkEventFilter *filter;
1880 private = (GdkWindowPrivate*) window;
1881 if (private && private->destroyed)
1885 tmp_list = private->filters;
1887 tmp_list = gdk_default_filters;
1891 filter = (GdkEventFilter *)tmp_list->data;
1892 if ((filter->function == function) && (filter->data == data))
1894 tmp_list = tmp_list->next;
1897 filter = g_new (GdkEventFilter, 1);
1898 filter->function = function;
1899 filter->data = data;
1902 private->filters = g_list_append (private->filters, filter);
1904 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1908 gdk_window_remove_filter (GdkWindow *window,
1909 GdkFilterFunc function,
1912 GdkWindowPrivate *private;
1913 GList *tmp_list, *node;
1914 GdkEventFilter *filter;
1916 private = (GdkWindowPrivate*) window;
1919 tmp_list = private->filters;
1921 tmp_list = gdk_default_filters;
1925 filter = (GdkEventFilter *)tmp_list->data;
1927 tmp_list = tmp_list->next;
1929 if ((filter->function == function) && (filter->data == data))
1932 private->filters = g_list_remove_link (private->filters, node);
1934 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1935 g_list_free_1 (node);
1944 gdk_window_set_override_redirect(GdkWindow *window,
1945 gboolean override_redirect)
1947 GdkWindowPrivate *private;
1948 XSetWindowAttributes attr;
1950 g_return_if_fail (window != NULL);
1951 private = (GdkWindowPrivate*) window;
1952 if (private->destroyed)
1955 attr.override_redirect = (override_redirect == FALSE)?False:True;
1956 XChangeWindowAttributes(gdk_display,
1957 ((GdkWindowPrivate *)window)->xwindow,
1963 gdk_window_set_icon (GdkWindow *window,
1964 GdkWindow *icon_window,
1969 GdkWindowPrivate *window_private;
1970 GdkWindowPrivate *private;
1972 g_return_if_fail (window != NULL);
1973 window_private = (GdkWindowPrivate*) window;
1974 if (window_private->destroyed)
1979 if (icon_window != NULL)
1981 private = (GdkWindowPrivate *)icon_window;
1982 wm_hints.flags |= IconWindowHint;
1983 wm_hints.icon_window = private->xwindow;
1988 private = (GdkWindowPrivate *)pixmap;
1989 wm_hints.flags |= IconPixmapHint;
1990 wm_hints.icon_pixmap = private->xwindow;
1995 private = (GdkWindowPrivate *)mask;
1996 wm_hints.flags |= IconMaskHint;
1997 wm_hints.icon_mask = private->xwindow;
2000 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2004 gdk_window_set_icon_name (GdkWindow *window,
2007 GdkWindowPrivate *window_private;
2008 XTextProperty property;
2011 g_return_if_fail (window != NULL);
2012 window_private = (GdkWindowPrivate*) window;
2013 if (window_private->destroyed)
2015 res = XmbTextListToTextProperty (window_private->xdisplay,
2016 &name, 1, XStdICCTextStyle,
2020 g_warning("Error converting icon name to text property: %d\n", res);
2024 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2028 XFree (property.value);
2032 gdk_window_set_group (GdkWindow *window,
2036 GdkWindowPrivate *window_private;
2037 GdkWindowPrivate *private;
2039 g_return_if_fail (window != NULL);
2040 g_return_if_fail (leader != NULL);
2041 window_private = (GdkWindowPrivate*) window;
2042 if (window_private->destroyed)
2045 private = (GdkWindowPrivate *)leader;
2046 wm_hints.flags = WindowGroupHint;
2047 wm_hints.window_group = private->xwindow;
2049 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2053 gdk_window_set_mwm_hints (GdkWindow *window,
2054 MotifWmHints *new_hints)
2056 static Atom hints_atom = None;
2057 MotifWmHints *hints;
2063 GdkWindowPrivate *window_private;
2065 g_return_if_fail (window != NULL);
2066 window_private = (GdkWindowPrivate*) window;
2067 if (window_private->destroyed)
2071 hints_atom = XInternAtom (window_private->xdisplay,
2072 _XA_MOTIF_WM_HINTS, FALSE);
2074 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2075 hints_atom, 0, sizeof(MotifWmHints)/4,
2076 False, AnyPropertyType, &type, &format, &nitems,
2077 &bytes_after, (guchar **)&hints);
2083 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2085 hints->flags |= MWM_HINTS_FUNCTIONS;
2086 hints->functions = new_hints->functions;
2088 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2090 hints->flags |= MWM_HINTS_DECORATIONS;
2091 hints->decorations = new_hints->decorations;
2095 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2096 hints_atom, hints_atom, 32, PropModeReplace,
2097 (guchar *)hints, sizeof(MotifWmHints)/4);
2099 if (hints != new_hints)
2104 gdk_window_set_decorations (GdkWindow *window,
2105 GdkWMDecoration decorations)
2109 hints.flags = MWM_HINTS_DECORATIONS;
2110 hints.decorations = decorations;
2112 gdk_window_set_mwm_hints (window, &hints);
2116 gdk_window_set_functions (GdkWindow *window,
2117 GdkWMFunction functions)
2121 hints.flags = MWM_HINTS_FUNCTIONS;
2122 hints.functions = functions;
2124 gdk_window_set_mwm_hints (window, &hints);
2128 gdk_window_get_toplevels (void)
2130 GList *new_list = NULL;
2133 tmp_list = gdk_root_parent.children;
2136 new_list = g_list_prepend (new_list, tmp_list->data);
2137 tmp_list = tmp_list->next;
2144 * propagate the shapes from all child windows of a GDK window to the parent
2145 * window. Shamelessly ripped from Enlightenment's code
2154 struct _gdk_span *next;
2158 gdk_add_to_span(struct _gdk_span **s, int x, int xx)
2160 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2167 /* scan the spans for this line */
2170 /* -- -> new span */
2171 /* == -> existing span */
2172 /* ## -> spans intersect */
2173 /* if we are in the middle of spanning the span into the line */
2176 /* case: ---- ==== */
2177 if (xx < ptr1->start - 1)
2179 /* ends before next span - extend to here */
2183 /* case: ----##=== */
2184 else if (xx <= ptr1->end)
2186 /* crosses into next span - delete next span and append */
2187 ss->end = ptr1->end;
2188 ss->next = ptr1->next;
2192 /* case: ---###--- */
2195 /* overlaps next span - delete and keep checking */
2196 ss->next = ptr1->next;
2201 /* otherwise havent started spanning it in yet */
2204 /* case: ---- ==== */
2205 if (xx < ptr1->start - 1)
2207 /* insert span here in list */
2208 noo = g_malloc(sizeof(struct _gdk_span));
2222 /* case: ----##=== */
2223 else if ((x < ptr1->start) && (xx <= ptr1->end))
2225 /* expand this span to the left point of the new one */
2229 /* case: ===###=== */
2230 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2232 /* throw the span away */
2235 /* case: ---###--- */
2236 else if ((x < ptr1->start) && (xx > ptr1->end))
2243 /* case: ===##---- */
2244 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2250 /* case: ==== ---- */
2251 /* case handled by next loop iteration - first case */
2256 /* it started in the middle but spans beyond your current list */
2262 /* it does not start inside a span or in the middle, so add it to the end */
2263 noo = g_malloc(sizeof(struct _gdk_span));
2271 noo->next = ptr2->next;
2284 gdk_add_rectangles (Display *disp, Window win, struct _gdk_span **spans,
2285 gint basew, gint baseh, gint x, gint y)
2288 gint x1, y1, x2, y2;
2292 rl = XShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord);
2295 /* go through all clip rects in this window's shape */
2296 for (k = 0; k < rn; k++)
2298 /* for each clip rect, add it to each line's spans */
2300 x2 = x + rl[k].x + (rl[k].width - 1);
2302 y2 = y + rl[k].y + (rl[k].height - 1);
2311 for (a = y1; a <= y2; a++)
2314 gdk_add_to_span(&spans[a], x1, x2);
2322 gdk_propagate_shapes(Display *disp, Window win, gboolean merge)
2324 Window rt, par, *list = NULL;
2325 gint i, j, num = 0, num_rects = 0;
2329 XRectangle *rects = NULL;
2330 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2331 XWindowAttributes xatt;
2333 XGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d);
2338 spans = g_malloc(sizeof(struct _gdk_span *) * h);
2340 for (i = 0; i < h; i++)
2342 XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num);
2345 /* go through all child windows and create/insert spans */
2346 for (i = 0; i < num; i++)
2348 if (XGetWindowAttributes(disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2349 if (XGetGeometry(disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2350 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2353 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2355 /* go through the spans list and build a list of rects */
2356 rects = g_malloc(sizeof(XRectangle) * 256);
2358 for (i = 0; i < baseh; i++)
2361 /* go through the line for all spans */
2364 rects[num_rects].x = ptr1->start;
2365 rects[num_rects].y = i;
2366 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2367 rects[num_rects].height = 1;
2369 /* if there are more lines */
2371 /* while contigous rects (same start/end coords) exist */
2372 while ((contig) && (j < baseh))
2374 /* search next line for spans matching this one */
2380 /* if we have an exact span match set contig */
2381 if ((ptr2->start == ptr1->start) &&
2382 (ptr2->end == ptr1->end))
2385 /* remove the span - not needed */
2388 ptr3->next = ptr2->next;
2394 spans[j] = ptr2->next;
2400 /* gone past the span point no point looking */
2401 else if (ptr2->start < ptr1->start)
2409 /* if a contiguous span was found increase the rect h */
2412 rects[num_rects].height++;
2416 /* up the rect count */
2418 /* every 256 new rects increase the rect array */
2419 if ((num_rects % 256) == 0)
2420 rects = g_realloc(rects, sizeof(XRectangle) * (num_rects + 256));
2424 /* set the rects as the shape mask */
2427 XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects,
2428 ShapeSet, YXSorted);
2433 /* free up all the spans we made */
2434 for (i = 0; i < baseh; i++)
2448 gdk_window_set_child_shapes (GdkWindow *window)
2450 GdkWindowPrivate *private;
2452 g_return_if_fail (window != NULL);
2454 #ifdef HAVE_SHAPE_EXT
2455 private = (GdkWindowPrivate*) window;
2456 if (private->destroyed)
2459 if (gdk_window_have_shape_ext())
2460 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2465 gdk_window_merge_child_shapes (GdkWindow *window)
2467 GdkWindowPrivate *private;
2469 g_return_if_fail (window != NULL);
2471 #ifdef HAVE_SHAPE_EXT
2472 private = (GdkWindowPrivate*) window;
2473 if (private->destroyed)
2476 if (gdk_window_have_shape_ext())
2477 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2481 /*************************************************************
2482 * gdk_window_is_visible:
2483 * Check if the given window is mapped.
2487 * is the window mapped
2488 *************************************************************/
2491 gdk_window_is_visible (GdkWindow *window)
2493 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2495 g_return_val_if_fail (window != NULL, FALSE);
2497 return private->mapped;
2500 /*************************************************************
2501 * gdk_window_is_viewable:
2502 * Check if the window and all ancestors of the window
2503 * are mapped. (This is not necessarily "viewable" in
2504 * the X sense, since we only check as far as we have
2505 * GDK window parents, not to the root window)
2509 * is the window viewable
2510 *************************************************************/
2513 gdk_window_is_viewable (GdkWindow *window)
2515 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2517 g_return_val_if_fail (window != NULL, FALSE);
2519 while (private && (private != &gdk_root_parent))
2521 if (!private->mapped)
2524 private = (GdkWindowPrivate *)private->parent;
2531 gdk_drawable_set_data (GdkDrawable *drawable,
2534 GDestroyNotify destroy_func)
2536 g_dataset_set_data_full (drawable, key, data, destroy_func);