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);
236 static GdkAtom wm_client_leader_atom = GDK_NONE;
239 gdk_window_new (GdkWindow *parent,
240 GdkWindowAttr *attributes,
241 gint attributes_mask)
244 GdkWindowPrivate *private;
245 GdkWindowPrivate *parent_private;
247 Display *parent_display;
250 XSetWindowAttributes xattributes;
251 long xattributes_mask;
252 XSizeHints size_hints;
254 XClassHint *class_hint;
260 g_return_val_if_fail (attributes != NULL, NULL);
263 parent = (GdkWindow*) &gdk_root_parent;
265 parent_private = (GdkWindowPrivate*) parent;
266 if (parent_private->destroyed)
269 xparent = parent_private->xwindow;
270 parent_display = parent_private->xdisplay;
272 private = g_new (GdkWindowPrivate, 1);
273 window = (GdkWindow*) private;
275 private->parent = parent;
278 parent_private->children = g_list_prepend (parent_private->children, window);
280 private->xdisplay = parent_display;
281 private->destroyed = FALSE;
282 private->mapped = FALSE;
283 private->resize_count = 0;
284 private->ref_count = 1;
285 xattributes_mask = 0;
287 if (attributes_mask & GDK_WA_X)
292 if (attributes_mask & GDK_WA_Y)
299 private->width = (attributes->width > 1) ? (attributes->width) : (1);
300 private->height = (attributes->height > 1) ? (attributes->height) : (1);
301 private->window_type = attributes->window_type;
302 private->extension_events = FALSE;
304 private->filters = NULL;
305 private->children = NULL;
307 window->user_data = NULL;
309 if (attributes_mask & GDK_WA_VISUAL)
310 visual = attributes->visual;
312 visual = gdk_visual_get_system ();
313 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
315 xattributes.event_mask = StructureNotifyMask;
316 for (i = 0; i < gdk_nevent_masks; i++)
318 if (attributes->event_mask & (1 << (i + 1)))
319 xattributes.event_mask |= gdk_event_mask_table[i];
322 if (xattributes.event_mask)
323 xattributes_mask |= CWEventMask;
325 if(attributes_mask & GDK_WA_NOREDIR) {
326 xattributes.override_redirect =
327 (attributes->override_redirect == FALSE)?False:True;
328 xattributes_mask |= CWOverrideRedirect;
330 xattributes.override_redirect = False;
332 if (attributes->wclass == GDK_INPUT_OUTPUT)
335 depth = visual->depth;
337 if (attributes_mask & GDK_WA_COLORMAP)
338 private->colormap = attributes->colormap;
341 if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
342 private->colormap = gdk_colormap_get_system ();
344 private->colormap = gdk_colormap_new (visual, False);
347 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
348 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
349 xattributes_mask |= CWBorderPixel | CWBackPixel;
351 switch (private->window_type)
353 case GDK_WINDOW_TOPLEVEL:
354 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
355 xattributes_mask |= CWColormap;
357 xparent = gdk_root_window;
360 case GDK_WINDOW_CHILD:
361 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
362 xattributes_mask |= CWColormap;
365 case GDK_WINDOW_DIALOG:
366 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
367 xattributes_mask |= CWColormap;
369 xparent = gdk_root_window;
372 case GDK_WINDOW_TEMP:
373 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
374 xattributes_mask |= CWColormap;
376 xparent = gdk_root_window;
378 xattributes.save_under = True;
379 xattributes.override_redirect = True;
380 xattributes.cursor = None;
381 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
383 case GDK_WINDOW_ROOT:
384 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
386 case GDK_WINDOW_PIXMAP:
387 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
395 private->colormap = NULL;
398 private->xwindow = XCreateWindow (private->xdisplay, xparent,
399 x, y, private->width, private->height,
400 0, depth, class, xvisual,
401 xattributes_mask, &xattributes);
402 gdk_window_ref (window);
403 gdk_xid_table_insert (&private->xwindow, window);
405 if (private->colormap)
406 gdk_colormap_ref (private->colormap);
408 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
409 (attributes->cursor) :
412 switch (private->window_type)
414 case GDK_WINDOW_DIALOG:
415 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
416 case GDK_WINDOW_TOPLEVEL:
417 case GDK_WINDOW_TEMP:
418 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
420 case GDK_WINDOW_CHILD:
421 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
422 (private->colormap != gdk_colormap_get_system ()) &&
423 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
425 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
426 gdk_window_add_colormap_windows (window);
435 size_hints.flags = PSize;
436 size_hints.width = private->width;
437 size_hints.height = private->height;
439 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
440 wm_hints.window_group = gdk_leader_window;
441 wm_hints.input = True;
442 wm_hints.initial_state = NormalState;
444 /* FIXME: Is there any point in doing this? Do any WM's pay
445 * attention to PSize, and even if they do, is this the
448 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
450 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
452 if (!wm_client_leader_atom)
453 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
455 XChangeProperty (private->xdisplay, private->xwindow,
456 wm_client_leader_atom,
457 XA_WINDOW, 32, PropModeReplace,
458 (guchar*) &gdk_leader_window, 1);
460 if (attributes_mask & GDK_WA_TITLE)
461 title = attributes->title;
463 title = g_get_prgname ();
465 XmbSetWMProperties (private->xdisplay, private->xwindow,
470 if (attributes_mask & GDK_WA_WMCLASS)
472 class_hint = XAllocClassHint ();
473 class_hint->res_name = attributes->wmclass_name;
474 class_hint->res_class = attributes->wmclass_class;
475 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
484 gdk_window_foreign_new (guint32 anid)
487 GdkWindowPrivate *private;
488 GdkWindowPrivate *parent_private;
489 XWindowAttributes attrs;
491 Window *children = NULL;
494 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
495 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
499 private = g_new (GdkWindowPrivate, 1);
500 window = (GdkWindow*) private;
502 /* FIXME: This is pretty expensive. Maybe the caller should supply
504 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
508 private->parent = gdk_xid_table_lookup (parent);
510 parent_private = (GdkWindowPrivate *)private->parent;
513 parent_private->children = g_list_prepend (parent_private->children, window);
515 private->xwindow = anid;
516 private->xdisplay = gdk_display;
517 private->x = attrs.x;
518 private->y = attrs.y;
519 private->width = attrs.width;
520 private->height = attrs.height;
521 private->resize_count = 0;
522 private->ref_count = 1;
523 private->window_type = GDK_WINDOW_FOREIGN;
524 private->destroyed = FALSE;
525 private->mapped = (attrs.map_state != IsUnmapped);
526 private->extension_events = 0;
528 private->colormap = NULL;
530 private->filters = NULL;
531 private->children = NULL;
533 window->user_data = NULL;
535 gdk_window_ref (window);
536 gdk_xid_table_insert (&private->xwindow, window);
541 /* Call this function when you want a window and all its children to
542 * disappear. When xdestroy is true, a request to destroy the XWindow
543 * is sent out. When it is false, it is assumed that the XWindow has
544 * been or will be destroyed by destroying some ancestor of this
548 gdk_window_internal_destroy (GdkWindow *window,
550 gboolean our_destroy)
552 GdkWindowPrivate *private;
553 GdkWindowPrivate *temp_private;
554 GdkWindow *temp_window;
558 g_return_if_fail (window != NULL);
560 private = (GdkWindowPrivate*) window;
562 switch (private->window_type)
564 case GDK_WINDOW_TOPLEVEL:
565 case GDK_WINDOW_CHILD:
566 case GDK_WINDOW_DIALOG:
567 case GDK_WINDOW_TEMP:
568 case GDK_WINDOW_FOREIGN:
569 if (!private->destroyed)
573 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
574 if (parent_private->children)
575 parent_private->children = g_list_remove (parent_private->children, window);
578 if (private->window_type != GDK_WINDOW_FOREIGN)
580 children = tmp = private->children;
581 private->children = NULL;
585 temp_window = tmp->data;
588 temp_private = (GdkWindowPrivate*) temp_window;
590 gdk_window_internal_destroy (temp_window, FALSE,
594 g_list_free (children);
597 if (private->extension_events != 0)
598 gdk_input_window_destroy (window);
600 if (private->filters)
602 tmp = private->filters;
610 g_list_free (private->filters);
611 private->filters = NULL;
614 if (private->window_type == GDK_WINDOW_FOREIGN)
616 if (our_destroy && (private->parent != NULL))
618 /* It's somebody elses window, but in our heirarchy,
619 * so reparent it to the root window, and then send
620 * it a delete event, as if we were a WM
622 XClientMessageEvent xevent;
624 gdk_window_hide (window);
625 gdk_window_reparent (window, NULL, 0, 0);
627 xevent.type = ClientMessage;
628 xevent.window = private->xwindow;
629 xevent.message_type = gdk_wm_protocols;
631 xevent.data.l[0] = gdk_wm_delete_window;
632 xevent.data.l[1] = CurrentTime;
634 XSendEvent (private->xdisplay, private->xwindow,
635 False, 0, (XEvent *)&xevent);
639 XDestroyWindow (private->xdisplay, private->xwindow);
641 if (private->colormap)
642 gdk_colormap_unref (private->colormap);
644 private->mapped = FALSE;
645 private->destroyed = TRUE;
649 case GDK_WINDOW_ROOT:
650 g_error ("attempted to destroy root window");
653 case GDK_WINDOW_PIXMAP:
654 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
659 /* Like internal_destroy, but also destroys the reference created by
663 gdk_window_destroy (GdkWindow *window)
665 gdk_window_internal_destroy (window, TRUE, TRUE);
666 gdk_window_unref (window);
669 /* This function is called when the XWindow is really gone. */
672 gdk_window_destroy_notify (GdkWindow *window)
674 GdkWindowPrivate *private;
676 g_return_if_fail (window != NULL);
678 private = (GdkWindowPrivate*) window;
680 if (!private->destroyed)
682 if (private->window_type == GDK_WINDOW_FOREIGN)
683 gdk_window_internal_destroy (window, FALSE, FALSE);
685 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
688 gdk_xid_table_remove (private->xwindow);
689 gdk_window_unref (window);
693 gdk_window_ref (GdkWindow *window)
695 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
696 g_return_val_if_fail (window != NULL, NULL);
698 private->ref_count += 1;
703 gdk_window_unref (GdkWindow *window)
705 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
706 g_return_if_fail (window != NULL);
708 private->ref_count -= 1;
709 if (private->ref_count == 0)
711 if (!private->destroyed)
713 if (private->window_type == GDK_WINDOW_FOREIGN)
714 gdk_xid_table_remove (private->xwindow);
716 g_warning ("losing last reference to undestroyed window\n");
718 g_dataset_destroy (window);
724 gdk_window_show (GdkWindow *window)
726 GdkWindowPrivate *private;
728 g_return_if_fail (window != NULL);
730 private = (GdkWindowPrivate*) window;
731 if (!private->destroyed && !private->mapped)
733 private->mapped = TRUE;
734 XRaiseWindow (private->xdisplay, private->xwindow);
735 XMapWindow (private->xdisplay, private->xwindow);
740 gdk_window_hide (GdkWindow *window)
742 GdkWindowPrivate *private;
744 g_return_if_fail (window != NULL);
746 private = (GdkWindowPrivate*) window;
747 if (!private->destroyed && private->mapped)
749 private->mapped = FALSE;
750 XUnmapWindow (private->xdisplay, private->xwindow);
755 gdk_window_withdraw (GdkWindow *window)
757 GdkWindowPrivate *private;
759 g_return_if_fail (window != NULL);
761 private = (GdkWindowPrivate*) window;
762 if (!private->destroyed)
763 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
767 gdk_window_move (GdkWindow *window,
771 GdkWindowPrivate *private;
773 g_return_if_fail (window != NULL);
775 private = (GdkWindowPrivate*) window;
776 if (!private->destroyed)
778 XMoveWindow (private->xdisplay, private->xwindow, x, y);
780 if (private->window_type == GDK_WINDOW_CHILD)
789 gdk_window_resize (GdkWindow *window,
793 GdkWindowPrivate *private;
795 g_return_if_fail (window != NULL);
802 private = (GdkWindowPrivate*) window;
804 if (!private->destroyed &&
805 ((private->resize_count > 0) ||
806 (private->width != (guint16) width) ||
807 (private->height != (guint16) height)))
809 XResizeWindow (private->xdisplay, private->xwindow, width, height);
810 private->resize_count += 1;
812 if (private->window_type == GDK_WINDOW_CHILD)
814 private->width = width;
815 private->height = height;
821 gdk_window_move_resize (GdkWindow *window,
827 GdkWindowPrivate *private;
829 g_return_if_fail (window != NULL);
836 private = (GdkWindowPrivate*) window;
837 if (!private->destroyed)
839 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
841 if (private->window_type == GDK_WINDOW_CHILD)
845 private->width = width;
846 private->height = height;
852 gdk_window_reparent (GdkWindow *window,
853 GdkWindow *new_parent,
857 GdkWindowPrivate *window_private;
858 GdkWindowPrivate *parent_private;
859 GdkWindowPrivate *old_parent_private;
861 g_return_if_fail (window != NULL);
864 new_parent = (GdkWindow*) &gdk_root_parent;
866 window_private = (GdkWindowPrivate*) window;
867 old_parent_private = (GdkWindowPrivate*)window_private->parent;
868 parent_private = (GdkWindowPrivate*) new_parent;
870 if (!window_private->destroyed && !parent_private->destroyed)
871 XReparentWindow (window_private->xdisplay,
872 window_private->xwindow,
873 parent_private->xwindow,
876 window_private->parent = new_parent;
878 if (old_parent_private)
879 old_parent_private->children = g_list_remove (old_parent_private->children, window);
880 parent_private->children = g_list_prepend (parent_private->children, window);
885 gdk_window_clear (GdkWindow *window)
887 GdkWindowPrivate *private;
889 g_return_if_fail (window != NULL);
891 private = (GdkWindowPrivate*) window;
893 if (!private->destroyed)
894 XClearWindow (private->xdisplay, private->xwindow);
898 gdk_window_clear_area (GdkWindow *window,
904 GdkWindowPrivate *private;
906 g_return_if_fail (window != NULL);
908 private = (GdkWindowPrivate*) window;
910 if (!private->destroyed)
911 XClearArea (private->xdisplay, private->xwindow,
912 x, y, width, height, False);
916 gdk_window_clear_area_e (GdkWindow *window,
922 GdkWindowPrivate *private;
924 g_return_if_fail (window != NULL);
926 private = (GdkWindowPrivate*) window;
928 if (!private->destroyed)
929 XClearArea (private->xdisplay, private->xwindow,
930 x, y, width, height, True);
934 gdk_window_copy_area (GdkWindow *window,
938 GdkWindow *source_window,
944 GdkWindowPrivate *src_private;
945 GdkWindowPrivate *dest_private;
946 GdkGCPrivate *gc_private;
948 g_return_if_fail (window != NULL);
949 g_return_if_fail (gc != NULL);
951 if (source_window == NULL)
952 source_window = window;
954 src_private = (GdkWindowPrivate*) source_window;
955 dest_private = (GdkWindowPrivate*) window;
956 gc_private = (GdkGCPrivate*) gc;
958 if (!src_private->destroyed && !dest_private->destroyed)
960 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
969 gdk_window_raise (GdkWindow *window)
971 GdkWindowPrivate *private;
973 g_return_if_fail (window != NULL);
975 private = (GdkWindowPrivate*) window;
977 if (!private->destroyed)
978 XRaiseWindow (private->xdisplay, private->xwindow);
982 gdk_window_lower (GdkWindow *window)
984 GdkWindowPrivate *private;
986 g_return_if_fail (window != NULL);
988 private = (GdkWindowPrivate*) window;
990 if (!private->destroyed)
991 XLowerWindow (private->xdisplay, private->xwindow);
995 gdk_window_set_user_data (GdkWindow *window,
998 g_return_if_fail (window != NULL);
1000 window->user_data = user_data;
1004 gdk_window_set_hints (GdkWindow *window,
1013 GdkWindowPrivate *private;
1014 XSizeHints size_hints;
1016 g_return_if_fail (window != NULL);
1018 private = (GdkWindowPrivate*) window;
1019 if (private->destroyed)
1022 size_hints.flags = 0;
1024 if (flags & GDK_HINT_POS)
1026 size_hints.flags |= PPosition;
1031 if (flags & GDK_HINT_MIN_SIZE)
1033 size_hints.flags |= PMinSize;
1034 size_hints.min_width = min_width;
1035 size_hints.min_height = min_height;
1038 if (flags & GDK_HINT_MAX_SIZE)
1040 size_hints.flags |= PMaxSize;
1041 size_hints.max_width = max_width;
1042 size_hints.max_height = max_height;
1046 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1050 gdk_window_set_geometry_hints (GdkWindow *window,
1051 GdkGeometry *geometry,
1052 GdkWindowHints geom_mask)
1054 GdkWindowPrivate *private;
1055 XSizeHints size_hints;
1057 g_return_if_fail (window != NULL);
1059 private = (GdkWindowPrivate*) window;
1060 if (private->destroyed)
1063 size_hints.flags = 0;
1065 if (geom_mask & GDK_HINT_POS)
1066 size_hints.flags |= PPosition;
1068 if (geom_mask & GDK_HINT_MIN_SIZE)
1070 size_hints.flags |= PMinSize;
1071 size_hints.min_width = geometry->min_width;
1072 size_hints.min_height = geometry->min_height;
1075 if (geom_mask & GDK_HINT_MAX_SIZE)
1077 size_hints.flags |= PMaxSize;
1078 size_hints.max_width = geometry->max_width;
1079 size_hints.max_height = geometry->max_height;
1082 if (geom_mask & GDK_HINT_BASE_SIZE)
1084 size_hints.flags |= PBaseSize;
1085 size_hints.base_width = geometry->base_width;
1086 size_hints.base_height = geometry->base_height;
1089 if (geom_mask & GDK_HINT_RESIZE_INC)
1091 size_hints.flags |= PResizeInc;
1092 size_hints.width_inc = geometry->width_inc;
1093 size_hints.height_inc = geometry->height_inc;
1096 if (geom_mask & GDK_HINT_ASPECT)
1098 size_hints.flags |= PAspect;
1099 if (geometry->min_aspect <= 1)
1101 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1102 size_hints.min_aspect.y = G_MAXINT;
1106 size_hints.min_aspect.x = G_MAXINT;
1107 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1109 if (geometry->max_aspect <= 1)
1111 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1112 size_hints.max_aspect.y = G_MAXINT;
1116 size_hints.max_aspect.x = G_MAXINT;
1117 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1122 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1126 gdk_window_set_title (GdkWindow *window,
1129 GdkWindowPrivate *private;
1131 g_return_if_fail (window != NULL);
1133 private = (GdkWindowPrivate*) window;
1134 if (!private->destroyed)
1135 XmbSetWMProperties (private->xdisplay, private->xwindow,
1136 title, title, NULL, 0, NULL, NULL, NULL);
1140 gdk_window_set_role (GdkWindow *window,
1143 GdkWindowPrivate *private;
1145 g_return_if_fail (window != NULL);
1147 private = (GdkWindowPrivate*) window;
1150 XChangeProperty (private->xdisplay, private->xwindow,
1151 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1152 8, PropModeReplace, role, strlen(role));
1154 XDeleteProperty (private->xdisplay, private->xwindow,
1155 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1159 gdk_window_set_transient_for (GdkWindow *window,
1162 GdkWindowPrivate *private;
1163 GdkWindowPrivate *parent_private;
1165 g_return_if_fail (window != NULL);
1167 private = (GdkWindowPrivate*) window;
1168 parent_private = (GdkWindowPrivate*) parent;
1170 if (!private->destroyed && !parent_private->destroyed)
1171 XSetTransientForHint (private->xdisplay,
1172 private->xwindow, parent_private->xwindow);
1176 gdk_window_set_background (GdkWindow *window,
1179 GdkWindowPrivate *private;
1181 g_return_if_fail (window != NULL);
1183 private = (GdkWindowPrivate*) window;
1184 if (!private->destroyed)
1185 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1189 gdk_window_set_back_pixmap (GdkWindow *window,
1191 gint parent_relative)
1193 GdkWindowPrivate *window_private;
1194 GdkPixmapPrivate *pixmap_private;
1197 g_return_if_fail (window != NULL);
1199 window_private = (GdkWindowPrivate*) window;
1200 pixmap_private = (GdkPixmapPrivate*) pixmap;
1203 xpixmap = pixmap_private->xwindow;
1207 if (parent_relative)
1208 xpixmap = ParentRelative;
1210 if (!window_private->destroyed)
1211 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1215 gdk_window_set_cursor (GdkWindow *window,
1218 GdkWindowPrivate *window_private;
1219 GdkCursorPrivate *cursor_private;
1222 g_return_if_fail (window != NULL);
1224 window_private = (GdkWindowPrivate*) window;
1225 cursor_private = (GdkCursorPrivate*) cursor;
1230 xcursor = cursor_private->xcursor;
1232 if (!window_private->destroyed)
1233 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1237 gdk_window_set_colormap (GdkWindow *window,
1238 GdkColormap *colormap)
1240 GdkWindowPrivate *window_private;
1241 GdkColormapPrivate *colormap_private;
1243 g_return_if_fail (window != NULL);
1244 g_return_if_fail (colormap != NULL);
1246 window_private = (GdkWindowPrivate*) window;
1247 colormap_private = (GdkColormapPrivate*) colormap;
1249 if (!window_private->destroyed)
1251 XSetWindowColormap (window_private->xdisplay,
1252 window_private->xwindow,
1253 colormap_private->xcolormap);
1255 if (window_private->colormap)
1256 gdk_colormap_unref (window_private->colormap);
1257 window_private->colormap = colormap;
1258 gdk_colormap_ref (window_private->colormap);
1260 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1261 gdk_window_add_colormap_windows (window);
1266 gdk_window_get_user_data (GdkWindow *window,
1269 g_return_if_fail (window != NULL);
1271 *data = window->user_data;
1275 gdk_window_get_geometry (GdkWindow *window,
1282 GdkWindowPrivate *window_private;
1288 guint tborder_width;
1292 window = (GdkWindow*) &gdk_root_parent;
1294 window_private = (GdkWindowPrivate*) window;
1296 if (!window_private->destroyed)
1298 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1299 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1315 gdk_window_get_position (GdkWindow *window,
1319 GdkWindowPrivate *window_private;
1321 g_return_if_fail (window != NULL);
1323 window_private = (GdkWindowPrivate*) window;
1326 *x = window_private->x;
1328 *y = window_private->y;
1332 gdk_window_get_size (GdkWindow *window,
1336 GdkWindowPrivate *window_private;
1338 g_return_if_fail (window != NULL);
1340 window_private = (GdkWindowPrivate*) window;
1343 *width = window_private->width;
1345 *height = window_private->height;
1349 gdk_window_get_visual (GdkWindow *window)
1351 GdkWindowPrivate *window_private;
1352 XWindowAttributes window_attributes;
1354 g_return_val_if_fail (window != NULL, NULL);
1356 window_private = (GdkWindowPrivate*) window;
1357 /* Huh? ->parent is never set for a pixmap. We should just return
1360 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1361 window_private = (GdkWindowPrivate*) window_private->parent;
1363 if (window_private && !window_private->destroyed)
1365 if (window_private->colormap == NULL)
1367 XGetWindowAttributes (window_private->xdisplay,
1368 window_private->xwindow,
1369 &window_attributes);
1370 return gdk_visual_lookup (window_attributes.visual);
1373 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1380 gdk_window_get_colormap (GdkWindow *window)
1382 GdkWindowPrivate *window_private;
1383 XWindowAttributes window_attributes;
1385 g_return_val_if_fail (window != NULL, NULL);
1386 window_private = (GdkWindowPrivate*) window;
1388 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1389 if (!window_private->destroyed)
1391 if (window_private->colormap == NULL)
1393 XGetWindowAttributes (window_private->xdisplay,
1394 window_private->xwindow,
1395 &window_attributes);
1396 return gdk_colormap_lookup (window_attributes.colormap);
1399 return window_private->colormap;
1406 gdk_window_get_type (GdkWindow *window)
1408 GdkWindowPrivate *window_private;
1410 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1412 window_private = (GdkWindowPrivate*) window;
1413 return window_private->window_type;
1417 gdk_window_get_origin (GdkWindow *window,
1421 GdkWindowPrivate *private;
1427 g_return_val_if_fail (window != NULL, 0);
1429 private = (GdkWindowPrivate*) window;
1431 if (!private->destroyed)
1433 return_val = XTranslateCoordinates (private->xdisplay,
1452 gdk_window_get_deskrelative_origin (GdkWindow *window,
1456 GdkWindowPrivate *private;
1457 gboolean return_val = FALSE;
1458 gint num_children, format_return;
1459 Window win, *child, parent, root;
1463 static Atom atom = 0;
1464 gulong number_return, bytes_after_return;
1465 guchar *data_return;
1467 g_return_val_if_fail (window != NULL, 0);
1469 private = (GdkWindowPrivate*) window;
1471 if (!private->destroyed)
1474 atom = XInternAtom(private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1475 win = private->xwindow;
1477 while (XQueryTree(private->xdisplay, win, &root, &parent,
1478 &child, (unsigned int *)&num_children))
1480 if ((child) && (num_children > 0))
1492 XGetWindowProperty(private->xdisplay, win, atom, 0, 0,
1493 False, XA_CARDINAL, &type_return, &format_return,
1494 &number_return, &bytes_after_return, &data_return);
1495 if (type_return == XA_CARDINAL)
1502 return_val = XTranslateCoordinates (private->xdisplay,
1518 gdk_window_get_root_origin (GdkWindow *window,
1522 GdkWindowPrivate *private;
1527 unsigned int nchildren;
1529 g_return_if_fail (window != NULL);
1531 private = (GdkWindowPrivate*) window;
1536 if (private->destroyed)
1539 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1540 private = (GdkWindowPrivate*) private->parent;
1541 if (private->destroyed)
1544 xparent = private->xwindow;
1548 if (!XQueryTree (private->xdisplay, xwindow,
1550 &children, &nchildren))
1556 while (xparent != root);
1558 if (xparent == root)
1560 unsigned int ww, wh, wb, wd;
1563 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1574 gdk_window_get_pointer (GdkWindow *window,
1577 GdkModifierType *mask)
1579 GdkWindowPrivate *private;
1580 GdkWindow *return_val;
1586 unsigned int xmask = 0;
1589 window = (GdkWindow*) &gdk_root_parent;
1591 private = (GdkWindowPrivate*) window;
1594 if (!private->destroyed &&
1595 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1596 &rootx, &rooty, &winx, &winy, &xmask))
1599 return_val = gdk_window_lookup (child);
1613 gdk_window_at_pointer (gint *win_x,
1616 GdkWindowPrivate *private;
1620 Window xwindow_last = 0;
1621 int rootx = -1, rooty = -1;
1625 private = &gdk_root_parent;
1627 xwindow = private->xwindow;
1629 XGrabServer (private->xdisplay);
1632 xwindow_last = xwindow;
1633 XQueryPointer (private->xdisplay,
1640 XUngrabServer (private->xdisplay);
1642 window = gdk_window_lookup (xwindow_last);
1645 *win_x = window ? winx : -1;
1647 *win_y = window ? winy : -1;
1653 gdk_window_get_parent (GdkWindow *window)
1655 g_return_val_if_fail (window != NULL, NULL);
1657 return ((GdkWindowPrivate*) window)->parent;
1661 gdk_window_get_toplevel (GdkWindow *window)
1663 GdkWindowPrivate *private;
1665 g_return_val_if_fail (window != NULL, NULL);
1667 private = (GdkWindowPrivate*) window;
1669 while (private->window_type == GDK_WINDOW_CHILD)
1671 window = ((GdkWindowPrivate*) window)->parent;
1672 private = (GdkWindowPrivate*) window;
1679 gdk_window_get_children (GdkWindow *window)
1681 GdkWindowPrivate *private;
1687 unsigned int nchildren;
1690 g_return_val_if_fail (window != NULL, NULL);
1692 private = (GdkWindowPrivate*) window;
1693 if (private->destroyed)
1696 XQueryTree (private->xdisplay, private->xwindow,
1697 &root, &parent, &xchildren, &nchildren);
1703 for (i = 0; i < nchildren; i++)
1705 child = gdk_window_lookup (xchildren[i]);
1707 children = g_list_prepend (children, child);
1718 gdk_window_get_events (GdkWindow *window)
1720 GdkWindowPrivate *private;
1721 XWindowAttributes attrs;
1722 GdkEventMask event_mask;
1725 g_return_val_if_fail (window != NULL, 0);
1727 private = (GdkWindowPrivate*) window;
1728 if (private->destroyed)
1731 XGetWindowAttributes (gdk_display, private->xwindow,
1735 for (i = 0; i < gdk_nevent_masks; i++)
1737 if (attrs.your_event_mask & gdk_event_mask_table[i])
1738 event_mask |= 1 << (i + 1);
1745 gdk_window_set_events (GdkWindow *window,
1746 GdkEventMask event_mask)
1748 GdkWindowPrivate *private;
1752 g_return_if_fail (window != NULL);
1754 private = (GdkWindowPrivate*) window;
1755 if (private->destroyed)
1758 xevent_mask = StructureNotifyMask;
1759 for (i = 0; i < gdk_nevent_masks; i++)
1761 if (event_mask & (1 << (i + 1)))
1762 xevent_mask |= gdk_event_mask_table[i];
1765 XSelectInput (gdk_display, private->xwindow,
1770 gdk_window_add_colormap_windows (GdkWindow *window)
1772 GdkWindow *toplevel;
1773 GdkWindowPrivate *toplevel_private;
1774 GdkWindowPrivate *window_private;
1775 Window *old_windows;
1776 Window *new_windows;
1779 g_return_if_fail (window != NULL);
1781 toplevel = gdk_window_get_toplevel (window);
1782 toplevel_private = (GdkWindowPrivate*) toplevel;
1783 window_private = (GdkWindowPrivate*) window;
1784 if (window_private->destroyed)
1788 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1789 toplevel_private->xwindow,
1790 &old_windows, &count))
1795 for (i = 0; i < count; i++)
1796 if (old_windows[i] == window_private->xwindow)
1798 XFree (old_windows);
1802 new_windows = g_new (Window, count + 1);
1804 for (i = 0; i < count; i++)
1805 new_windows[i] = old_windows[i];
1806 new_windows[count] = window_private->xwindow;
1808 XSetWMColormapWindows (toplevel_private->xdisplay,
1809 toplevel_private->xwindow,
1810 new_windows, count + 1);
1812 g_free (new_windows);
1814 XFree (old_windows);
1818 gdk_window_have_shape_ext (void)
1820 enum { UNKNOWN, NO, YES };
1821 static gint have_shape = UNKNOWN;
1823 if (have_shape == UNKNOWN)
1826 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1832 return (have_shape == YES);
1836 * This needs the X11 shape extension.
1837 * If not available, shaped windows will look
1838 * ugly, but programs still work. Stefan Wille
1841 gdk_window_shape_combine_mask (GdkWindow *window,
1845 GdkWindowPrivate *window_private;
1848 g_return_if_fail (window != NULL);
1850 #ifdef HAVE_SHAPE_EXT
1851 window_private = (GdkWindowPrivate*) window;
1852 if (window_private->destroyed)
1855 if (gdk_window_have_shape_ext())
1859 GdkWindowPrivate *pixmap_private;
1861 pixmap_private = (GdkWindowPrivate*) mask;
1862 pixmap = (Pixmap) pixmap_private->xwindow;
1871 XShapeCombineMask (window_private->xdisplay,
1872 window_private->xwindow,
1878 #endif /* HAVE_SHAPE_EXT */
1882 gdk_window_add_filter (GdkWindow *window,
1883 GdkFilterFunc function,
1886 GdkWindowPrivate *private;
1888 GdkEventFilter *filter;
1890 private = (GdkWindowPrivate*) window;
1891 if (private && private->destroyed)
1895 tmp_list = private->filters;
1897 tmp_list = gdk_default_filters;
1901 filter = (GdkEventFilter *)tmp_list->data;
1902 if ((filter->function == function) && (filter->data == data))
1904 tmp_list = tmp_list->next;
1907 filter = g_new (GdkEventFilter, 1);
1908 filter->function = function;
1909 filter->data = data;
1912 private->filters = g_list_append (private->filters, filter);
1914 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1918 gdk_window_remove_filter (GdkWindow *window,
1919 GdkFilterFunc function,
1922 GdkWindowPrivate *private;
1923 GList *tmp_list, *node;
1924 GdkEventFilter *filter;
1926 private = (GdkWindowPrivate*) window;
1929 tmp_list = private->filters;
1931 tmp_list = gdk_default_filters;
1935 filter = (GdkEventFilter *)tmp_list->data;
1937 tmp_list = tmp_list->next;
1939 if ((filter->function == function) && (filter->data == data))
1942 private->filters = g_list_remove_link (private->filters, node);
1944 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1945 g_list_free_1 (node);
1954 gdk_window_set_override_redirect(GdkWindow *window,
1955 gboolean override_redirect)
1957 GdkWindowPrivate *private;
1958 XSetWindowAttributes attr;
1960 g_return_if_fail (window != NULL);
1961 private = (GdkWindowPrivate*) window;
1962 if (private->destroyed)
1965 attr.override_redirect = (override_redirect == FALSE)?False:True;
1966 XChangeWindowAttributes(gdk_display,
1967 ((GdkWindowPrivate *)window)->xwindow,
1973 gdk_window_set_icon (GdkWindow *window,
1974 GdkWindow *icon_window,
1979 GdkWindowPrivate *window_private;
1980 GdkWindowPrivate *private;
1982 g_return_if_fail (window != NULL);
1983 window_private = (GdkWindowPrivate*) window;
1984 if (window_private->destroyed)
1989 if (icon_window != NULL)
1991 private = (GdkWindowPrivate *)icon_window;
1992 wm_hints.flags |= IconWindowHint;
1993 wm_hints.icon_window = private->xwindow;
1998 private = (GdkWindowPrivate *)pixmap;
1999 wm_hints.flags |= IconPixmapHint;
2000 wm_hints.icon_pixmap = private->xwindow;
2005 private = (GdkWindowPrivate *)mask;
2006 wm_hints.flags |= IconMaskHint;
2007 wm_hints.icon_mask = private->xwindow;
2010 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2014 gdk_window_set_icon_name (GdkWindow *window,
2017 GdkWindowPrivate *window_private;
2018 XTextProperty property;
2021 g_return_if_fail (window != NULL);
2022 window_private = (GdkWindowPrivate*) window;
2023 if (window_private->destroyed)
2025 res = XmbTextListToTextProperty (window_private->xdisplay,
2026 &name, 1, XStdICCTextStyle,
2030 g_warning("Error converting icon name to text property: %d\n", res);
2034 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2038 XFree (property.value);
2042 gdk_window_set_group (GdkWindow *window,
2046 GdkWindowPrivate *window_private;
2047 GdkWindowPrivate *private;
2049 g_return_if_fail (window != NULL);
2050 g_return_if_fail (leader != NULL);
2051 window_private = (GdkWindowPrivate*) window;
2052 if (window_private->destroyed)
2055 private = (GdkWindowPrivate *)leader;
2056 wm_hints.flags = WindowGroupHint;
2057 wm_hints.window_group = private->xwindow;
2059 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2063 gdk_window_set_mwm_hints (GdkWindow *window,
2064 MotifWmHints *new_hints)
2066 static Atom hints_atom = None;
2067 MotifWmHints *hints;
2073 GdkWindowPrivate *window_private;
2075 g_return_if_fail (window != NULL);
2076 window_private = (GdkWindowPrivate*) window;
2077 if (window_private->destroyed)
2081 hints_atom = XInternAtom (window_private->xdisplay,
2082 _XA_MOTIF_WM_HINTS, FALSE);
2084 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2085 hints_atom, 0, sizeof(MotifWmHints)/4,
2086 False, AnyPropertyType, &type, &format, &nitems,
2087 &bytes_after, (guchar **)&hints);
2093 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2095 hints->flags |= MWM_HINTS_FUNCTIONS;
2096 hints->functions = new_hints->functions;
2098 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2100 hints->flags |= MWM_HINTS_DECORATIONS;
2101 hints->decorations = new_hints->decorations;
2105 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2106 hints_atom, hints_atom, 32, PropModeReplace,
2107 (guchar *)hints, sizeof(MotifWmHints)/4);
2109 if (hints != new_hints)
2114 gdk_window_set_decorations (GdkWindow *window,
2115 GdkWMDecoration decorations)
2119 hints.flags = MWM_HINTS_DECORATIONS;
2120 hints.decorations = decorations;
2122 gdk_window_set_mwm_hints (window, &hints);
2126 gdk_window_set_functions (GdkWindow *window,
2127 GdkWMFunction functions)
2131 hints.flags = MWM_HINTS_FUNCTIONS;
2132 hints.functions = functions;
2134 gdk_window_set_mwm_hints (window, &hints);
2138 gdk_window_get_toplevels (void)
2140 GList *new_list = NULL;
2143 tmp_list = gdk_root_parent.children;
2146 new_list = g_list_prepend (new_list, tmp_list->data);
2147 tmp_list = tmp_list->next;
2154 * propagate the shapes from all child windows of a GDK window to the parent
2155 * window. Shamelessly ripped from Enlightenment's code
2164 struct _gdk_span *next;
2168 gdk_add_to_span(struct _gdk_span **s, int x, int xx)
2170 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2177 /* scan the spans for this line */
2180 /* -- -> new span */
2181 /* == -> existing span */
2182 /* ## -> spans intersect */
2183 /* if we are in the middle of spanning the span into the line */
2186 /* case: ---- ==== */
2187 if (xx < ptr1->start - 1)
2189 /* ends before next span - extend to here */
2193 /* case: ----##=== */
2194 else if (xx <= ptr1->end)
2196 /* crosses into next span - delete next span and append */
2197 ss->end = ptr1->end;
2198 ss->next = ptr1->next;
2202 /* case: ---###--- */
2205 /* overlaps next span - delete and keep checking */
2206 ss->next = ptr1->next;
2211 /* otherwise havent started spanning it in yet */
2214 /* case: ---- ==== */
2215 if (xx < ptr1->start - 1)
2217 /* insert span here in list */
2218 noo = g_malloc(sizeof(struct _gdk_span));
2232 /* case: ----##=== */
2233 else if ((x < ptr1->start) && (xx <= ptr1->end))
2235 /* expand this span to the left point of the new one */
2239 /* case: ===###=== */
2240 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2242 /* throw the span away */
2245 /* case: ---###--- */
2246 else if ((x < ptr1->start) && (xx > ptr1->end))
2253 /* case: ===##---- */
2254 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2260 /* case: ==== ---- */
2261 /* case handled by next loop iteration - first case */
2266 /* it started in the middle but spans beyond your current list */
2272 /* it does not start inside a span or in the middle, so add it to the end */
2273 noo = g_malloc(sizeof(struct _gdk_span));
2281 noo->next = ptr2->next;
2294 gdk_add_rectangles (Display *disp, Window win, struct _gdk_span **spans,
2295 gint basew, gint baseh, gint x, gint y)
2298 gint x1, y1, x2, y2;
2302 rl = XShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord);
2305 /* go through all clip rects in this window's shape */
2306 for (k = 0; k < rn; k++)
2308 /* for each clip rect, add it to each line's spans */
2310 x2 = x + rl[k].x + (rl[k].width - 1);
2312 y2 = y + rl[k].y + (rl[k].height - 1);
2321 for (a = y1; a <= y2; a++)
2324 gdk_add_to_span(&spans[a], x1, x2);
2332 gdk_propagate_shapes(Display *disp, Window win, gboolean merge)
2334 Window rt, par, *list = NULL;
2335 gint i, j, num = 0, num_rects = 0;
2339 XRectangle *rects = NULL;
2340 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2341 XWindowAttributes xatt;
2343 XGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d);
2348 spans = g_malloc(sizeof(struct _gdk_span *) * h);
2350 for (i = 0; i < h; i++)
2352 XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num);
2355 /* go through all child windows and create/insert spans */
2356 for (i = 0; i < num; i++)
2358 if (XGetWindowAttributes(disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2359 if (XGetGeometry(disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2360 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2363 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2365 /* go through the spans list and build a list of rects */
2366 rects = g_malloc(sizeof(XRectangle) * 256);
2368 for (i = 0; i < baseh; i++)
2371 /* go through the line for all spans */
2374 rects[num_rects].x = ptr1->start;
2375 rects[num_rects].y = i;
2376 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2377 rects[num_rects].height = 1;
2379 /* if there are more lines */
2381 /* while contigous rects (same start/end coords) exist */
2382 while ((contig) && (j < baseh))
2384 /* search next line for spans matching this one */
2390 /* if we have an exact span match set contig */
2391 if ((ptr2->start == ptr1->start) &&
2392 (ptr2->end == ptr1->end))
2395 /* remove the span - not needed */
2398 ptr3->next = ptr2->next;
2404 spans[j] = ptr2->next;
2410 /* gone past the span point no point looking */
2411 else if (ptr2->start < ptr1->start)
2419 /* if a contiguous span was found increase the rect h */
2422 rects[num_rects].height++;
2426 /* up the rect count */
2428 /* every 256 new rects increase the rect array */
2429 if ((num_rects % 256) == 0)
2430 rects = g_realloc(rects, sizeof(XRectangle) * (num_rects + 256));
2434 /* set the rects as the shape mask */
2437 XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects,
2438 ShapeSet, YXSorted);
2443 /* free up all the spans we made */
2444 for (i = 0; i < baseh; i++)
2458 gdk_window_set_child_shapes (GdkWindow *window)
2460 GdkWindowPrivate *private;
2462 g_return_if_fail (window != NULL);
2464 #ifdef HAVE_SHAPE_EXT
2465 private = (GdkWindowPrivate*) window;
2466 if (private->destroyed)
2469 if (gdk_window_have_shape_ext())
2470 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2475 gdk_window_merge_child_shapes (GdkWindow *window)
2477 GdkWindowPrivate *private;
2479 g_return_if_fail (window != NULL);
2481 #ifdef HAVE_SHAPE_EXT
2482 private = (GdkWindowPrivate*) window;
2483 if (private->destroyed)
2486 if (gdk_window_have_shape_ext())
2487 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2491 /*************************************************************
2492 * gdk_window_is_visible:
2493 * Check if the given window is mapped.
2497 * is the window mapped
2498 *************************************************************/
2501 gdk_window_is_visible (GdkWindow *window)
2503 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2505 g_return_val_if_fail (window != NULL, FALSE);
2507 return private->mapped;
2510 /*************************************************************
2511 * gdk_window_is_viewable:
2512 * Check if the window and all ancestors of the window
2513 * are mapped. (This is not necessarily "viewable" in
2514 * the X sense, since we only check as far as we have
2515 * GDK window parents, not to the root window)
2519 * is the window viewable
2520 *************************************************************/
2523 gdk_window_is_viewable (GdkWindow *window)
2525 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2527 g_return_val_if_fail (window != NULL, FALSE);
2529 while (private && (private != &gdk_root_parent))
2531 if (!private->mapped)
2534 private = (GdkWindowPrivate *)private->parent;
2541 gdk_drawable_set_data (GdkDrawable *drawable,
2544 GDestroyNotify destroy_func)
2546 g_dataset_set_data_full (drawable, key, data, destroy_func);