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 /* Forward declarations */
73 static gboolean gdk_window_gravity_works (void);
74 static void gdk_window_set_static_win_gravity (GdkWindow *window,
76 static gboolean gdk_window_have_shape_ext (void);
78 /* internal function created for and used by gdk_window_xid_at_coords */
80 gdk_window_xid_at (Window base,
89 GdkWindowPrivate *private;
92 Window child = 0, parent_win = 0, root_win = 0;
94 unsigned int ww, wh, wb, wd, num;
97 window = (GdkWindow*) &gdk_root_parent;
98 private = (GdkWindowPrivate*) window;
99 disp = private->xdisplay;
100 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
107 (x < (int) (wx + ww)) &&
108 (y < (int) (wy + wh))))
111 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
116 for (i = num - 1; ; i--)
118 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
120 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
135 * The following fucntion by The Rasterman <raster@redhat.com>
136 * This function returns the X Window ID in which the x y location is in
137 * (x and y being relative to the root window), excluding any windows listed
138 * in the GList excludes (this is a list of X Window ID's - gpointer being
141 * This is primarily designed for internal gdk use - for DND for example
142 * when using a shaped icon window as the drag object - you exclude the
143 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
144 * You can get back an X Window ID as to what X Window ID is infact under
145 * those X,Y co-ordinates.
148 gdk_window_xid_at_coords (gint x,
154 GdkWindowPrivate *private;
157 Window root, child = 0, parent_win = 0, root_win = 0;
161 window = (GdkWindow*) &gdk_root_parent;
162 private = (GdkWindowPrivate*) window;
163 disp = private->xdisplay;
164 root = private->xwindow;
165 num = g_list_length (excludes);
168 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
178 XWindowAttributes xwa;
180 XGetWindowAttributes (disp, list [i], &xwa);
182 if (xwa.map_state != IsViewable)
185 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
188 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
193 if (!g_list_find (excludes, (gpointer *) child))
196 XUngrabServer (disp);
203 XUngrabServer (disp);
209 XUngrabServer (disp);
214 gdk_window_init (void)
216 XWindowAttributes xattributes;
219 unsigned int border_width;
223 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
224 &x, &y, &width, &height, &border_width, &depth);
225 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
227 gdk_root_parent.xwindow = gdk_root_window;
228 gdk_root_parent.xdisplay = gdk_display;
229 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
230 gdk_root_parent.window.user_data = NULL;
231 gdk_root_parent.width = width;
232 gdk_root_parent.height = height;
233 gdk_root_parent.children = NULL;
234 gdk_root_parent.colormap = NULL;
235 gdk_root_parent.ref_count = 1;
237 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
240 static GdkAtom wm_client_leader_atom = GDK_NONE;
243 gdk_window_new (GdkWindow *parent,
244 GdkWindowAttr *attributes,
245 gint attributes_mask)
248 GdkWindowPrivate *private;
249 GdkWindowPrivate *parent_private;
251 Display *parent_display;
254 XSetWindowAttributes xattributes;
255 long xattributes_mask;
256 XSizeHints size_hints;
258 XClassHint *class_hint;
264 g_return_val_if_fail (attributes != NULL, NULL);
267 parent = (GdkWindow*) &gdk_root_parent;
269 parent_private = (GdkWindowPrivate*) parent;
270 if (parent_private->destroyed)
273 xparent = parent_private->xwindow;
274 parent_display = parent_private->xdisplay;
276 private = g_new (GdkWindowPrivate, 1);
277 window = (GdkWindow*) private;
279 private->parent = parent;
281 private->xdisplay = parent_display;
282 private->destroyed = FALSE;
283 private->mapped = FALSE;
284 private->guffaw_gravity = FALSE;
285 private->resize_count = 0;
286 private->ref_count = 1;
287 xattributes_mask = 0;
289 if (attributes_mask & GDK_WA_X)
294 if (attributes_mask & GDK_WA_Y)
301 private->width = (attributes->width > 1) ? (attributes->width) : (1);
302 private->height = (attributes->height > 1) ? (attributes->height) : (1);
303 private->window_type = attributes->window_type;
304 private->extension_events = FALSE;
306 private->filters = NULL;
307 private->children = NULL;
309 window->user_data = NULL;
311 if (attributes_mask & GDK_WA_VISUAL)
312 visual = attributes->visual;
314 visual = gdk_visual_get_system ();
315 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
317 xattributes.event_mask = StructureNotifyMask;
318 for (i = 0; i < gdk_nevent_masks; i++)
320 if (attributes->event_mask & (1 << (i + 1)))
321 xattributes.event_mask |= gdk_event_mask_table[i];
324 if (xattributes.event_mask)
325 xattributes_mask |= CWEventMask;
327 if (attributes_mask & GDK_WA_NOREDIR)
329 xattributes.override_redirect =
330 (attributes->override_redirect == FALSE)?False:True;
331 xattributes_mask |= CWOverrideRedirect;
334 xattributes.override_redirect = False;
336 if (parent_private && parent_private->guffaw_gravity)
338 xattributes.win_gravity = StaticGravity;
339 xattributes_mask |= CWWinGravity;
342 if (attributes->wclass == GDK_INPUT_OUTPUT)
345 depth = visual->depth;
347 if (attributes_mask & GDK_WA_COLORMAP)
348 private->colormap = attributes->colormap;
351 if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
352 private->colormap = gdk_colormap_get_system ();
354 private->colormap = gdk_colormap_new (visual, False);
357 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
358 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
359 xattributes_mask |= CWBorderPixel | CWBackPixel;
361 switch (private->window_type)
363 case GDK_WINDOW_TOPLEVEL:
364 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
365 xattributes_mask |= CWColormap;
367 xparent = gdk_root_window;
370 case GDK_WINDOW_CHILD:
371 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
372 xattributes_mask |= CWColormap;
375 case GDK_WINDOW_DIALOG:
376 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
377 xattributes_mask |= CWColormap;
379 xparent = gdk_root_window;
382 case GDK_WINDOW_TEMP:
383 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
384 xattributes_mask |= CWColormap;
386 xparent = gdk_root_window;
388 xattributes.save_under = True;
389 xattributes.override_redirect = True;
390 xattributes.cursor = None;
391 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
393 case GDK_WINDOW_ROOT:
394 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
396 case GDK_WINDOW_PIXMAP:
397 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
405 private->colormap = NULL;
408 private->xwindow = XCreateWindow (private->xdisplay, xparent,
409 x, y, private->width, private->height,
410 0, depth, class, xvisual,
411 xattributes_mask, &xattributes);
412 gdk_window_ref (window);
413 gdk_xid_table_insert (&private->xwindow, window);
415 if (private->colormap)
416 gdk_colormap_ref (private->colormap);
418 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
419 (attributes->cursor) :
423 parent_private->children = g_list_prepend (parent_private->children, window);
425 switch (private->window_type)
427 case GDK_WINDOW_DIALOG:
428 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
429 case GDK_WINDOW_TOPLEVEL:
430 case GDK_WINDOW_TEMP:
431 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
433 case GDK_WINDOW_CHILD:
434 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
435 (private->colormap != gdk_colormap_get_system ()) &&
436 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
438 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
439 gdk_window_add_colormap_windows (window);
448 size_hints.flags = PSize;
449 size_hints.width = private->width;
450 size_hints.height = private->height;
452 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
453 wm_hints.window_group = gdk_leader_window;
454 wm_hints.input = True;
455 wm_hints.initial_state = NormalState;
457 /* FIXME: Is there any point in doing this? Do any WM's pay
458 * attention to PSize, and even if they do, is this the
461 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
463 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
465 if (!wm_client_leader_atom)
466 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
468 XChangeProperty (private->xdisplay, private->xwindow,
469 wm_client_leader_atom,
470 XA_WINDOW, 32, PropModeReplace,
471 (guchar*) &gdk_leader_window, 1);
473 if (attributes_mask & GDK_WA_TITLE)
474 title = attributes->title;
476 title = g_get_prgname ();
478 XmbSetWMProperties (private->xdisplay, private->xwindow,
483 if (attributes_mask & GDK_WA_WMCLASS)
485 class_hint = XAllocClassHint ();
486 class_hint->res_name = attributes->wmclass_name;
487 class_hint->res_class = attributes->wmclass_class;
488 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
497 gdk_window_foreign_new (guint32 anid)
500 GdkWindowPrivate *private;
501 GdkWindowPrivate *parent_private;
502 XWindowAttributes attrs;
504 Window *children = NULL;
507 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
508 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
512 private = g_new (GdkWindowPrivate, 1);
513 window = (GdkWindow*) private;
515 /* FIXME: This is pretty expensive. Maybe the caller should supply
517 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
521 private->parent = gdk_xid_table_lookup (parent);
523 parent_private = (GdkWindowPrivate *)private->parent;
526 parent_private->children = g_list_prepend (parent_private->children, window);
528 private->xwindow = anid;
529 private->xdisplay = gdk_display;
530 private->x = attrs.x;
531 private->y = attrs.y;
532 private->width = attrs.width;
533 private->height = attrs.height;
534 private->resize_count = 0;
535 private->ref_count = 1;
536 private->window_type = GDK_WINDOW_FOREIGN;
537 private->destroyed = FALSE;
538 private->mapped = (attrs.map_state != IsUnmapped);
539 private->guffaw_gravity = FALSE;
540 private->extension_events = 0;
542 private->colormap = NULL;
544 private->filters = NULL;
545 private->children = NULL;
547 window->user_data = NULL;
549 gdk_window_ref (window);
550 gdk_xid_table_insert (&private->xwindow, window);
555 /* Call this function when you want a window and all its children to
556 * disappear. When xdestroy is true, a request to destroy the XWindow
557 * is sent out. When it is false, it is assumed that the XWindow has
558 * been or will be destroyed by destroying some ancestor of this
562 gdk_window_internal_destroy (GdkWindow *window,
564 gboolean our_destroy)
566 GdkWindowPrivate *private;
567 GdkWindowPrivate *temp_private;
568 GdkWindow *temp_window;
572 g_return_if_fail (window != NULL);
574 private = (GdkWindowPrivate*) window;
576 switch (private->window_type)
578 case GDK_WINDOW_TOPLEVEL:
579 case GDK_WINDOW_CHILD:
580 case GDK_WINDOW_DIALOG:
581 case GDK_WINDOW_TEMP:
582 case GDK_WINDOW_FOREIGN:
583 if (!private->destroyed)
587 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
588 if (parent_private->children)
589 parent_private->children = g_list_remove (parent_private->children, window);
592 if (private->window_type != GDK_WINDOW_FOREIGN)
594 children = tmp = private->children;
595 private->children = NULL;
599 temp_window = tmp->data;
602 temp_private = (GdkWindowPrivate*) temp_window;
604 gdk_window_internal_destroy (temp_window, FALSE,
608 g_list_free (children);
611 if (private->extension_events != 0)
612 gdk_input_window_destroy (window);
614 if (private->filters)
616 tmp = private->filters;
624 g_list_free (private->filters);
625 private->filters = NULL;
628 if (private->window_type == GDK_WINDOW_FOREIGN)
630 if (our_destroy && (private->parent != NULL))
632 /* It's somebody elses window, but in our heirarchy,
633 * so reparent it to the root window, and then send
634 * it a delete event, as if we were a WM
636 XClientMessageEvent xevent;
638 gdk_window_hide (window);
639 gdk_window_reparent (window, NULL, 0, 0);
641 xevent.type = ClientMessage;
642 xevent.window = private->xwindow;
643 xevent.message_type = gdk_wm_protocols;
645 xevent.data.l[0] = gdk_wm_delete_window;
646 xevent.data.l[1] = CurrentTime;
648 XSendEvent (private->xdisplay, private->xwindow,
649 False, 0, (XEvent *)&xevent);
653 XDestroyWindow (private->xdisplay, private->xwindow);
655 if (private->colormap)
656 gdk_colormap_unref (private->colormap);
658 private->mapped = FALSE;
659 private->destroyed = TRUE;
663 case GDK_WINDOW_ROOT:
664 g_error ("attempted to destroy root window");
667 case GDK_WINDOW_PIXMAP:
668 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
673 /* Like internal_destroy, but also destroys the reference created by
677 gdk_window_destroy (GdkWindow *window)
679 gdk_window_internal_destroy (window, TRUE, TRUE);
680 gdk_window_unref (window);
683 /* This function is called when the XWindow is really gone. */
686 gdk_window_destroy_notify (GdkWindow *window)
688 GdkWindowPrivate *private;
690 g_return_if_fail (window != NULL);
692 private = (GdkWindowPrivate*) window;
694 if (!private->destroyed)
696 if (private->window_type == GDK_WINDOW_FOREIGN)
697 gdk_window_internal_destroy (window, FALSE, FALSE);
699 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
702 gdk_xid_table_remove (private->xwindow);
703 gdk_window_unref (window);
707 gdk_window_ref (GdkWindow *window)
709 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
710 g_return_val_if_fail (window != NULL, NULL);
712 private->ref_count += 1;
717 gdk_window_unref (GdkWindow *window)
719 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
720 g_return_if_fail (window != NULL);
722 private->ref_count -= 1;
723 if (private->ref_count == 0)
725 if (!private->destroyed)
727 if (private->window_type == GDK_WINDOW_FOREIGN)
728 gdk_xid_table_remove (private->xwindow);
730 g_warning ("losing last reference to undestroyed window\n");
732 g_dataset_destroy (window);
738 gdk_window_show (GdkWindow *window)
740 GdkWindowPrivate *private;
742 g_return_if_fail (window != NULL);
744 private = (GdkWindowPrivate*) window;
745 if (!private->destroyed && !private->mapped)
747 private->mapped = TRUE;
748 XRaiseWindow (private->xdisplay, private->xwindow);
749 XMapWindow (private->xdisplay, private->xwindow);
754 gdk_window_hide (GdkWindow *window)
756 GdkWindowPrivate *private;
758 g_return_if_fail (window != NULL);
760 private = (GdkWindowPrivate*) window;
761 if (!private->destroyed && private->mapped)
763 private->mapped = FALSE;
764 XUnmapWindow (private->xdisplay, private->xwindow);
769 gdk_window_withdraw (GdkWindow *window)
771 GdkWindowPrivate *private;
773 g_return_if_fail (window != NULL);
775 private = (GdkWindowPrivate*) window;
776 if (!private->destroyed)
777 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
781 gdk_window_move (GdkWindow *window,
785 GdkWindowPrivate *private;
787 g_return_if_fail (window != NULL);
789 private = (GdkWindowPrivate*) window;
790 if (!private->destroyed)
792 XMoveWindow (private->xdisplay, private->xwindow, x, y);
794 if (private->window_type == GDK_WINDOW_CHILD)
803 gdk_window_resize (GdkWindow *window,
807 GdkWindowPrivate *private;
809 g_return_if_fail (window != NULL);
816 private = (GdkWindowPrivate*) window;
818 if (!private->destroyed &&
819 ((private->resize_count > 0) ||
820 (private->width != (guint16) width) ||
821 (private->height != (guint16) height)))
823 XResizeWindow (private->xdisplay, private->xwindow, width, height);
824 private->resize_count += 1;
826 if (private->window_type == GDK_WINDOW_CHILD)
828 private->width = width;
829 private->height = height;
835 gdk_window_move_resize (GdkWindow *window,
841 GdkWindowPrivate *private;
843 g_return_if_fail (window != NULL);
850 private = (GdkWindowPrivate*) window;
851 if (!private->destroyed)
853 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
855 if (private->window_type == GDK_WINDOW_CHILD)
859 private->width = width;
860 private->height = height;
866 gdk_window_reparent (GdkWindow *window,
867 GdkWindow *new_parent,
871 GdkWindowPrivate *window_private;
872 GdkWindowPrivate *parent_private;
873 GdkWindowPrivate *old_parent_private;
875 g_return_if_fail (window != NULL);
878 new_parent = (GdkWindow*) &gdk_root_parent;
880 window_private = (GdkWindowPrivate*) window;
881 old_parent_private = (GdkWindowPrivate*)window_private->parent;
882 parent_private = (GdkWindowPrivate*) new_parent;
884 if (!window_private->destroyed && !parent_private->destroyed)
885 XReparentWindow (window_private->xdisplay,
886 window_private->xwindow,
887 parent_private->xwindow,
890 window_private->parent = new_parent;
892 if (old_parent_private)
893 old_parent_private->children = g_list_remove (old_parent_private->children, window);
895 if ((old_parent_private &&
896 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
897 (!old_parent_private && parent_private->guffaw_gravity))
898 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
900 parent_private->children = g_list_prepend (parent_private->children, window);
904 gdk_window_clear (GdkWindow *window)
906 GdkWindowPrivate *private;
908 g_return_if_fail (window != NULL);
910 private = (GdkWindowPrivate*) window;
912 if (!private->destroyed)
913 XClearWindow (private->xdisplay, private->xwindow);
917 gdk_window_clear_area (GdkWindow *window,
923 GdkWindowPrivate *private;
925 g_return_if_fail (window != NULL);
927 private = (GdkWindowPrivate*) window;
929 if (!private->destroyed)
930 XClearArea (private->xdisplay, private->xwindow,
931 x, y, width, height, False);
935 gdk_window_clear_area_e (GdkWindow *window,
941 GdkWindowPrivate *private;
943 g_return_if_fail (window != NULL);
945 private = (GdkWindowPrivate*) window;
947 if (!private->destroyed)
948 XClearArea (private->xdisplay, private->xwindow,
949 x, y, width, height, True);
953 gdk_window_copy_area (GdkWindow *window,
957 GdkWindow *source_window,
963 GdkWindowPrivate *src_private;
964 GdkWindowPrivate *dest_private;
965 GdkGCPrivate *gc_private;
967 g_return_if_fail (window != NULL);
968 g_return_if_fail (gc != NULL);
970 if (source_window == NULL)
971 source_window = window;
973 src_private = (GdkWindowPrivate*) source_window;
974 dest_private = (GdkWindowPrivate*) window;
975 gc_private = (GdkGCPrivate*) gc;
977 if (!src_private->destroyed && !dest_private->destroyed)
979 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
988 gdk_window_raise (GdkWindow *window)
990 GdkWindowPrivate *private;
992 g_return_if_fail (window != NULL);
994 private = (GdkWindowPrivate*) window;
996 if (!private->destroyed)
997 XRaiseWindow (private->xdisplay, private->xwindow);
1001 gdk_window_lower (GdkWindow *window)
1003 GdkWindowPrivate *private;
1005 g_return_if_fail (window != NULL);
1007 private = (GdkWindowPrivate*) window;
1009 if (!private->destroyed)
1010 XLowerWindow (private->xdisplay, private->xwindow);
1014 gdk_window_set_user_data (GdkWindow *window,
1017 g_return_if_fail (window != NULL);
1019 window->user_data = user_data;
1023 gdk_window_set_hints (GdkWindow *window,
1032 GdkWindowPrivate *private;
1033 XSizeHints size_hints;
1035 g_return_if_fail (window != NULL);
1037 private = (GdkWindowPrivate*) window;
1038 if (private->destroyed)
1041 size_hints.flags = 0;
1043 if (flags & GDK_HINT_POS)
1045 size_hints.flags |= PPosition;
1050 if (flags & GDK_HINT_MIN_SIZE)
1052 size_hints.flags |= PMinSize;
1053 size_hints.min_width = min_width;
1054 size_hints.min_height = min_height;
1057 if (flags & GDK_HINT_MAX_SIZE)
1059 size_hints.flags |= PMaxSize;
1060 size_hints.max_width = max_width;
1061 size_hints.max_height = max_height;
1065 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1069 gdk_window_set_geometry_hints (GdkWindow *window,
1070 GdkGeometry *geometry,
1071 GdkWindowHints geom_mask)
1073 GdkWindowPrivate *private;
1074 XSizeHints size_hints;
1076 g_return_if_fail (window != NULL);
1078 private = (GdkWindowPrivate*) window;
1079 if (private->destroyed)
1082 size_hints.flags = 0;
1084 if (geom_mask & GDK_HINT_POS)
1085 size_hints.flags |= PPosition;
1087 if (geom_mask & GDK_HINT_MIN_SIZE)
1089 size_hints.flags |= PMinSize;
1090 size_hints.min_width = geometry->min_width;
1091 size_hints.min_height = geometry->min_height;
1094 if (geom_mask & GDK_HINT_MAX_SIZE)
1096 size_hints.flags |= PMaxSize;
1097 size_hints.max_width = geometry->max_width;
1098 size_hints.max_height = geometry->max_height;
1101 if (geom_mask & GDK_HINT_BASE_SIZE)
1103 size_hints.flags |= PBaseSize;
1104 size_hints.base_width = geometry->base_width;
1105 size_hints.base_height = geometry->base_height;
1108 if (geom_mask & GDK_HINT_RESIZE_INC)
1110 size_hints.flags |= PResizeInc;
1111 size_hints.width_inc = geometry->width_inc;
1112 size_hints.height_inc = geometry->height_inc;
1115 if (geom_mask & GDK_HINT_ASPECT)
1117 size_hints.flags |= PAspect;
1118 if (geometry->min_aspect <= 1)
1120 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1121 size_hints.min_aspect.y = G_MAXINT;
1125 size_hints.min_aspect.x = G_MAXINT;
1126 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1128 if (geometry->max_aspect <= 1)
1130 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1131 size_hints.max_aspect.y = G_MAXINT;
1135 size_hints.max_aspect.x = G_MAXINT;
1136 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1141 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1145 gdk_window_set_title (GdkWindow *window,
1148 GdkWindowPrivate *private;
1150 g_return_if_fail (window != NULL);
1152 private = (GdkWindowPrivate*) window;
1153 if (!private->destroyed)
1154 XmbSetWMProperties (private->xdisplay, private->xwindow,
1155 title, title, NULL, 0, NULL, NULL, NULL);
1159 gdk_window_set_role (GdkWindow *window,
1162 GdkWindowPrivate *private;
1164 g_return_if_fail (window != NULL);
1166 private = (GdkWindowPrivate*) window;
1169 XChangeProperty (private->xdisplay, private->xwindow,
1170 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1171 8, PropModeReplace, role, strlen(role));
1173 XDeleteProperty (private->xdisplay, private->xwindow,
1174 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1178 gdk_window_set_transient_for (GdkWindow *window,
1181 GdkWindowPrivate *private;
1182 GdkWindowPrivate *parent_private;
1184 g_return_if_fail (window != NULL);
1186 private = (GdkWindowPrivate*) window;
1187 parent_private = (GdkWindowPrivate*) parent;
1189 if (!private->destroyed && !parent_private->destroyed)
1190 XSetTransientForHint (private->xdisplay,
1191 private->xwindow, parent_private->xwindow);
1195 gdk_window_set_background (GdkWindow *window,
1198 GdkWindowPrivate *private;
1200 g_return_if_fail (window != NULL);
1202 private = (GdkWindowPrivate*) window;
1203 if (!private->destroyed)
1204 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1208 gdk_window_set_back_pixmap (GdkWindow *window,
1210 gint parent_relative)
1212 GdkWindowPrivate *window_private;
1213 GdkPixmapPrivate *pixmap_private;
1216 g_return_if_fail (window != NULL);
1218 window_private = (GdkWindowPrivate*) window;
1219 pixmap_private = (GdkPixmapPrivate*) pixmap;
1222 xpixmap = pixmap_private->xwindow;
1226 if (parent_relative)
1227 xpixmap = ParentRelative;
1229 if (!window_private->destroyed)
1230 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1234 gdk_window_set_cursor (GdkWindow *window,
1237 GdkWindowPrivate *window_private;
1238 GdkCursorPrivate *cursor_private;
1241 g_return_if_fail (window != NULL);
1243 window_private = (GdkWindowPrivate*) window;
1244 cursor_private = (GdkCursorPrivate*) cursor;
1249 xcursor = cursor_private->xcursor;
1251 if (!window_private->destroyed)
1252 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1256 gdk_window_set_colormap (GdkWindow *window,
1257 GdkColormap *colormap)
1259 GdkWindowPrivate *window_private;
1260 GdkColormapPrivate *colormap_private;
1262 g_return_if_fail (window != NULL);
1263 g_return_if_fail (colormap != NULL);
1265 window_private = (GdkWindowPrivate*) window;
1266 colormap_private = (GdkColormapPrivate*) colormap;
1268 if (!window_private->destroyed)
1270 XSetWindowColormap (window_private->xdisplay,
1271 window_private->xwindow,
1272 colormap_private->xcolormap);
1274 if (window_private->colormap)
1275 gdk_colormap_unref (window_private->colormap);
1276 window_private->colormap = colormap;
1277 gdk_colormap_ref (window_private->colormap);
1279 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1280 gdk_window_add_colormap_windows (window);
1285 gdk_window_get_user_data (GdkWindow *window,
1288 g_return_if_fail (window != NULL);
1290 *data = window->user_data;
1294 gdk_window_get_geometry (GdkWindow *window,
1301 GdkWindowPrivate *window_private;
1307 guint tborder_width;
1311 window = (GdkWindow*) &gdk_root_parent;
1313 window_private = (GdkWindowPrivate*) window;
1315 if (!window_private->destroyed)
1317 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1318 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1334 gdk_window_get_position (GdkWindow *window,
1338 GdkWindowPrivate *window_private;
1340 g_return_if_fail (window != NULL);
1342 window_private = (GdkWindowPrivate*) window;
1345 *x = window_private->x;
1347 *y = window_private->y;
1351 gdk_window_get_size (GdkWindow *window,
1355 GdkWindowPrivate *window_private;
1357 g_return_if_fail (window != NULL);
1359 window_private = (GdkWindowPrivate*) window;
1362 *width = window_private->width;
1364 *height = window_private->height;
1368 gdk_window_get_visual (GdkWindow *window)
1370 GdkWindowPrivate *window_private;
1371 XWindowAttributes window_attributes;
1373 g_return_val_if_fail (window != NULL, NULL);
1375 window_private = (GdkWindowPrivate*) window;
1376 /* Huh? ->parent is never set for a pixmap. We should just return
1379 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1380 window_private = (GdkWindowPrivate*) window_private->parent;
1382 if (window_private && !window_private->destroyed)
1384 if (window_private->colormap == NULL)
1386 XGetWindowAttributes (window_private->xdisplay,
1387 window_private->xwindow,
1388 &window_attributes);
1389 return gdk_visual_lookup (window_attributes.visual);
1392 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1399 gdk_window_get_colormap (GdkWindow *window)
1401 GdkWindowPrivate *window_private;
1402 XWindowAttributes window_attributes;
1404 g_return_val_if_fail (window != NULL, NULL);
1405 window_private = (GdkWindowPrivate*) window;
1407 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1408 if (!window_private->destroyed)
1410 if (window_private->colormap == NULL)
1412 XGetWindowAttributes (window_private->xdisplay,
1413 window_private->xwindow,
1414 &window_attributes);
1415 return gdk_colormap_lookup (window_attributes.colormap);
1418 return window_private->colormap;
1425 gdk_window_get_type (GdkWindow *window)
1427 GdkWindowPrivate *window_private;
1429 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1431 window_private = (GdkWindowPrivate*) window;
1432 return window_private->window_type;
1436 gdk_window_get_origin (GdkWindow *window,
1440 GdkWindowPrivate *private;
1446 g_return_val_if_fail (window != NULL, 0);
1448 private = (GdkWindowPrivate*) window;
1450 if (!private->destroyed)
1452 return_val = XTranslateCoordinates (private->xdisplay,
1471 gdk_window_get_deskrelative_origin (GdkWindow *window,
1475 GdkWindowPrivate *private;
1476 gboolean return_val = FALSE;
1477 gint num_children, format_return;
1478 Window win, *child, parent, root;
1482 static Atom atom = 0;
1483 gulong number_return, bytes_after_return;
1484 guchar *data_return;
1486 g_return_val_if_fail (window != NULL, 0);
1488 private = (GdkWindowPrivate*) window;
1490 if (!private->destroyed)
1493 atom = XInternAtom(private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1494 win = private->xwindow;
1496 while (XQueryTree(private->xdisplay, win, &root, &parent,
1497 &child, (unsigned int *)&num_children))
1499 if ((child) && (num_children > 0))
1511 XGetWindowProperty(private->xdisplay, win, atom, 0, 0,
1512 False, XA_CARDINAL, &type_return, &format_return,
1513 &number_return, &bytes_after_return, &data_return);
1514 if (type_return == XA_CARDINAL)
1521 return_val = XTranslateCoordinates (private->xdisplay,
1537 gdk_window_get_root_origin (GdkWindow *window,
1541 GdkWindowPrivate *private;
1546 unsigned int nchildren;
1548 g_return_if_fail (window != NULL);
1550 private = (GdkWindowPrivate*) window;
1555 if (private->destroyed)
1558 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1559 private = (GdkWindowPrivate*) private->parent;
1560 if (private->destroyed)
1563 xparent = private->xwindow;
1567 if (!XQueryTree (private->xdisplay, xwindow,
1569 &children, &nchildren))
1575 while (xparent != root);
1577 if (xparent == root)
1579 unsigned int ww, wh, wb, wd;
1582 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1593 gdk_window_get_pointer (GdkWindow *window,
1596 GdkModifierType *mask)
1598 GdkWindowPrivate *private;
1599 GdkWindow *return_val;
1605 unsigned int xmask = 0;
1608 window = (GdkWindow*) &gdk_root_parent;
1610 private = (GdkWindowPrivate*) window;
1613 if (!private->destroyed &&
1614 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1615 &rootx, &rooty, &winx, &winy, &xmask))
1618 return_val = gdk_window_lookup (child);
1632 gdk_window_at_pointer (gint *win_x,
1635 GdkWindowPrivate *private;
1639 Window xwindow_last = 0;
1640 int rootx = -1, rooty = -1;
1644 private = &gdk_root_parent;
1646 xwindow = private->xwindow;
1648 XGrabServer (private->xdisplay);
1651 xwindow_last = xwindow;
1652 XQueryPointer (private->xdisplay,
1659 XUngrabServer (private->xdisplay);
1661 window = gdk_window_lookup (xwindow_last);
1664 *win_x = window ? winx : -1;
1666 *win_y = window ? winy : -1;
1672 gdk_window_get_parent (GdkWindow *window)
1674 g_return_val_if_fail (window != NULL, NULL);
1676 return ((GdkWindowPrivate*) window)->parent;
1680 gdk_window_get_toplevel (GdkWindow *window)
1682 GdkWindowPrivate *private;
1684 g_return_val_if_fail (window != NULL, NULL);
1686 private = (GdkWindowPrivate*) window;
1688 while (private->window_type == GDK_WINDOW_CHILD)
1690 window = ((GdkWindowPrivate*) window)->parent;
1691 private = (GdkWindowPrivate*) window;
1698 gdk_window_get_children (GdkWindow *window)
1700 GdkWindowPrivate *private;
1706 unsigned int nchildren;
1709 g_return_val_if_fail (window != NULL, NULL);
1711 private = (GdkWindowPrivate*) window;
1712 if (private->destroyed)
1715 XQueryTree (private->xdisplay, private->xwindow,
1716 &root, &parent, &xchildren, &nchildren);
1722 for (i = 0; i < nchildren; i++)
1724 child = gdk_window_lookup (xchildren[i]);
1726 children = g_list_prepend (children, child);
1737 gdk_window_get_events (GdkWindow *window)
1739 GdkWindowPrivate *private;
1740 XWindowAttributes attrs;
1741 GdkEventMask event_mask;
1744 g_return_val_if_fail (window != NULL, 0);
1746 private = (GdkWindowPrivate*) window;
1747 if (private->destroyed)
1750 XGetWindowAttributes (gdk_display, private->xwindow,
1754 for (i = 0; i < gdk_nevent_masks; i++)
1756 if (attrs.your_event_mask & gdk_event_mask_table[i])
1757 event_mask |= 1 << (i + 1);
1764 gdk_window_set_events (GdkWindow *window,
1765 GdkEventMask event_mask)
1767 GdkWindowPrivate *private;
1771 g_return_if_fail (window != NULL);
1773 private = (GdkWindowPrivate*) window;
1774 if (private->destroyed)
1777 xevent_mask = StructureNotifyMask;
1778 for (i = 0; i < gdk_nevent_masks; i++)
1780 if (event_mask & (1 << (i + 1)))
1781 xevent_mask |= gdk_event_mask_table[i];
1784 XSelectInput (gdk_display, private->xwindow,
1789 gdk_window_add_colormap_windows (GdkWindow *window)
1791 GdkWindow *toplevel;
1792 GdkWindowPrivate *toplevel_private;
1793 GdkWindowPrivate *window_private;
1794 Window *old_windows;
1795 Window *new_windows;
1798 g_return_if_fail (window != NULL);
1800 toplevel = gdk_window_get_toplevel (window);
1801 toplevel_private = (GdkWindowPrivate*) toplevel;
1802 window_private = (GdkWindowPrivate*) window;
1803 if (window_private->destroyed)
1807 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1808 toplevel_private->xwindow,
1809 &old_windows, &count))
1814 for (i = 0; i < count; i++)
1815 if (old_windows[i] == window_private->xwindow)
1817 XFree (old_windows);
1821 new_windows = g_new (Window, count + 1);
1823 for (i = 0; i < count; i++)
1824 new_windows[i] = old_windows[i];
1825 new_windows[count] = window_private->xwindow;
1827 XSetWMColormapWindows (toplevel_private->xdisplay,
1828 toplevel_private->xwindow,
1829 new_windows, count + 1);
1831 g_free (new_windows);
1833 XFree (old_windows);
1837 gdk_window_have_shape_ext (void)
1839 enum { UNKNOWN, NO, YES };
1840 static gint have_shape = UNKNOWN;
1842 if (have_shape == UNKNOWN)
1845 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1851 return (have_shape == YES);
1855 * This needs the X11 shape extension.
1856 * If not available, shaped windows will look
1857 * ugly, but programs still work. Stefan Wille
1860 gdk_window_shape_combine_mask (GdkWindow *window,
1864 GdkWindowPrivate *window_private;
1867 g_return_if_fail (window != NULL);
1869 #ifdef HAVE_SHAPE_EXT
1870 window_private = (GdkWindowPrivate*) window;
1871 if (window_private->destroyed)
1874 if (gdk_window_have_shape_ext())
1878 GdkWindowPrivate *pixmap_private;
1880 pixmap_private = (GdkWindowPrivate*) mask;
1881 pixmap = (Pixmap) pixmap_private->xwindow;
1890 XShapeCombineMask (window_private->xdisplay,
1891 window_private->xwindow,
1897 #endif /* HAVE_SHAPE_EXT */
1901 gdk_window_add_filter (GdkWindow *window,
1902 GdkFilterFunc function,
1905 GdkWindowPrivate *private;
1907 GdkEventFilter *filter;
1909 private = (GdkWindowPrivate*) window;
1910 if (private && private->destroyed)
1914 tmp_list = private->filters;
1916 tmp_list = gdk_default_filters;
1920 filter = (GdkEventFilter *)tmp_list->data;
1921 if ((filter->function == function) && (filter->data == data))
1923 tmp_list = tmp_list->next;
1926 filter = g_new (GdkEventFilter, 1);
1927 filter->function = function;
1928 filter->data = data;
1931 private->filters = g_list_append (private->filters, filter);
1933 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1937 gdk_window_remove_filter (GdkWindow *window,
1938 GdkFilterFunc function,
1941 GdkWindowPrivate *private;
1942 GList *tmp_list, *node;
1943 GdkEventFilter *filter;
1945 private = (GdkWindowPrivate*) window;
1948 tmp_list = private->filters;
1950 tmp_list = gdk_default_filters;
1954 filter = (GdkEventFilter *)tmp_list->data;
1956 tmp_list = tmp_list->next;
1958 if ((filter->function == function) && (filter->data == data))
1961 private->filters = g_list_remove_link (private->filters, node);
1963 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1964 g_list_free_1 (node);
1973 gdk_window_set_override_redirect(GdkWindow *window,
1974 gboolean override_redirect)
1976 GdkWindowPrivate *private;
1977 XSetWindowAttributes attr;
1979 g_return_if_fail (window != NULL);
1980 private = (GdkWindowPrivate*) window;
1981 if (private->destroyed)
1984 attr.override_redirect = (override_redirect == FALSE)?False:True;
1985 XChangeWindowAttributes(gdk_display,
1986 ((GdkWindowPrivate *)window)->xwindow,
1992 gdk_window_set_icon (GdkWindow *window,
1993 GdkWindow *icon_window,
1998 GdkWindowPrivate *window_private;
1999 GdkWindowPrivate *private;
2001 g_return_if_fail (window != NULL);
2002 window_private = (GdkWindowPrivate*) window;
2003 if (window_private->destroyed)
2008 if (icon_window != NULL)
2010 private = (GdkWindowPrivate *)icon_window;
2011 wm_hints.flags |= IconWindowHint;
2012 wm_hints.icon_window = private->xwindow;
2017 private = (GdkWindowPrivate *)pixmap;
2018 wm_hints.flags |= IconPixmapHint;
2019 wm_hints.icon_pixmap = private->xwindow;
2024 private = (GdkWindowPrivate *)mask;
2025 wm_hints.flags |= IconMaskHint;
2026 wm_hints.icon_mask = private->xwindow;
2029 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2033 gdk_window_set_icon_name (GdkWindow *window,
2036 GdkWindowPrivate *window_private;
2037 XTextProperty property;
2040 g_return_if_fail (window != NULL);
2041 window_private = (GdkWindowPrivate*) window;
2042 if (window_private->destroyed)
2044 res = XmbTextListToTextProperty (window_private->xdisplay,
2045 &name, 1, XStdICCTextStyle,
2049 g_warning("Error converting icon name to text property: %d\n", res);
2053 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2057 XFree (property.value);
2061 gdk_window_set_group (GdkWindow *window,
2065 GdkWindowPrivate *window_private;
2066 GdkWindowPrivate *private;
2068 g_return_if_fail (window != NULL);
2069 g_return_if_fail (leader != NULL);
2070 window_private = (GdkWindowPrivate*) window;
2071 if (window_private->destroyed)
2074 private = (GdkWindowPrivate *)leader;
2075 wm_hints.flags = WindowGroupHint;
2076 wm_hints.window_group = private->xwindow;
2078 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2082 gdk_window_set_mwm_hints (GdkWindow *window,
2083 MotifWmHints *new_hints)
2085 static Atom hints_atom = None;
2086 MotifWmHints *hints;
2092 GdkWindowPrivate *window_private;
2094 g_return_if_fail (window != NULL);
2095 window_private = (GdkWindowPrivate*) window;
2096 if (window_private->destroyed)
2100 hints_atom = XInternAtom (window_private->xdisplay,
2101 _XA_MOTIF_WM_HINTS, FALSE);
2103 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2104 hints_atom, 0, sizeof(MotifWmHints)/4,
2105 False, AnyPropertyType, &type, &format, &nitems,
2106 &bytes_after, (guchar **)&hints);
2112 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2114 hints->flags |= MWM_HINTS_FUNCTIONS;
2115 hints->functions = new_hints->functions;
2117 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2119 hints->flags |= MWM_HINTS_DECORATIONS;
2120 hints->decorations = new_hints->decorations;
2124 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2125 hints_atom, hints_atom, 32, PropModeReplace,
2126 (guchar *)hints, sizeof(MotifWmHints)/4);
2128 if (hints != new_hints)
2133 gdk_window_set_decorations (GdkWindow *window,
2134 GdkWMDecoration decorations)
2138 hints.flags = MWM_HINTS_DECORATIONS;
2139 hints.decorations = decorations;
2141 gdk_window_set_mwm_hints (window, &hints);
2145 gdk_window_set_functions (GdkWindow *window,
2146 GdkWMFunction functions)
2150 hints.flags = MWM_HINTS_FUNCTIONS;
2151 hints.functions = functions;
2153 gdk_window_set_mwm_hints (window, &hints);
2157 gdk_window_get_toplevels (void)
2159 GList *new_list = NULL;
2162 tmp_list = gdk_root_parent.children;
2165 new_list = g_list_prepend (new_list, tmp_list->data);
2166 tmp_list = tmp_list->next;
2173 * propagate the shapes from all child windows of a GDK window to the parent
2174 * window. Shamelessly ripped from Enlightenment's code
2183 struct _gdk_span *next;
2187 gdk_add_to_span(struct _gdk_span **s, int x, int xx)
2189 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2196 /* scan the spans for this line */
2199 /* -- -> new span */
2200 /* == -> existing span */
2201 /* ## -> spans intersect */
2202 /* if we are in the middle of spanning the span into the line */
2205 /* case: ---- ==== */
2206 if (xx < ptr1->start - 1)
2208 /* ends before next span - extend to here */
2212 /* case: ----##=== */
2213 else if (xx <= ptr1->end)
2215 /* crosses into next span - delete next span and append */
2216 ss->end = ptr1->end;
2217 ss->next = ptr1->next;
2221 /* case: ---###--- */
2224 /* overlaps next span - delete and keep checking */
2225 ss->next = ptr1->next;
2230 /* otherwise havent started spanning it in yet */
2233 /* case: ---- ==== */
2234 if (xx < ptr1->start - 1)
2236 /* insert span here in list */
2237 noo = g_malloc(sizeof(struct _gdk_span));
2251 /* case: ----##=== */
2252 else if ((x < ptr1->start) && (xx <= ptr1->end))
2254 /* expand this span to the left point of the new one */
2258 /* case: ===###=== */
2259 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2261 /* throw the span away */
2264 /* case: ---###--- */
2265 else if ((x < ptr1->start) && (xx > ptr1->end))
2272 /* case: ===##---- */
2273 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2279 /* case: ==== ---- */
2280 /* case handled by next loop iteration - first case */
2285 /* it started in the middle but spans beyond your current list */
2291 /* it does not start inside a span or in the middle, so add it to the end */
2292 noo = g_malloc(sizeof(struct _gdk_span));
2300 noo->next = ptr2->next;
2313 gdk_add_rectangles (Display *disp, Window win, struct _gdk_span **spans,
2314 gint basew, gint baseh, gint x, gint y)
2317 gint x1, y1, x2, y2;
2321 rl = XShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord);
2324 /* go through all clip rects in this window's shape */
2325 for (k = 0; k < rn; k++)
2327 /* for each clip rect, add it to each line's spans */
2329 x2 = x + rl[k].x + (rl[k].width - 1);
2331 y2 = y + rl[k].y + (rl[k].height - 1);
2340 for (a = y1; a <= y2; a++)
2343 gdk_add_to_span(&spans[a], x1, x2);
2351 gdk_propagate_shapes(Display *disp, Window win, gboolean merge)
2353 Window rt, par, *list = NULL;
2354 gint i, j, num = 0, num_rects = 0;
2358 XRectangle *rects = NULL;
2359 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2360 XWindowAttributes xatt;
2362 XGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d);
2367 spans = g_malloc(sizeof(struct _gdk_span *) * h);
2369 for (i = 0; i < h; i++)
2371 XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num);
2374 /* go through all child windows and create/insert spans */
2375 for (i = 0; i < num; i++)
2377 if (XGetWindowAttributes(disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2378 if (XGetGeometry(disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2379 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2382 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2384 /* go through the spans list and build a list of rects */
2385 rects = g_malloc(sizeof(XRectangle) * 256);
2387 for (i = 0; i < baseh; i++)
2390 /* go through the line for all spans */
2393 rects[num_rects].x = ptr1->start;
2394 rects[num_rects].y = i;
2395 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2396 rects[num_rects].height = 1;
2398 /* if there are more lines */
2400 /* while contigous rects (same start/end coords) exist */
2401 while ((contig) && (j < baseh))
2403 /* search next line for spans matching this one */
2409 /* if we have an exact span match set contig */
2410 if ((ptr2->start == ptr1->start) &&
2411 (ptr2->end == ptr1->end))
2414 /* remove the span - not needed */
2417 ptr3->next = ptr2->next;
2423 spans[j] = ptr2->next;
2429 /* gone past the span point no point looking */
2430 else if (ptr2->start < ptr1->start)
2438 /* if a contiguous span was found increase the rect h */
2441 rects[num_rects].height++;
2445 /* up the rect count */
2447 /* every 256 new rects increase the rect array */
2448 if ((num_rects % 256) == 0)
2449 rects = g_realloc(rects, sizeof(XRectangle) * (num_rects + 256));
2453 /* set the rects as the shape mask */
2456 XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects,
2457 ShapeSet, YXSorted);
2462 /* free up all the spans we made */
2463 for (i = 0; i < baseh; i++)
2477 gdk_window_set_child_shapes (GdkWindow *window)
2479 GdkWindowPrivate *private;
2481 g_return_if_fail (window != NULL);
2483 #ifdef HAVE_SHAPE_EXT
2484 private = (GdkWindowPrivate*) window;
2485 if (private->destroyed)
2488 if (gdk_window_have_shape_ext())
2489 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2494 gdk_window_merge_child_shapes (GdkWindow *window)
2496 GdkWindowPrivate *private;
2498 g_return_if_fail (window != NULL);
2500 #ifdef HAVE_SHAPE_EXT
2501 private = (GdkWindowPrivate*) window;
2502 if (private->destroyed)
2505 if (gdk_window_have_shape_ext())
2506 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2510 /*************************************************************
2511 * gdk_window_is_visible:
2512 * Check if the given window is mapped.
2516 * is the window mapped
2517 *************************************************************/
2520 gdk_window_is_visible (GdkWindow *window)
2522 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2524 g_return_val_if_fail (window != NULL, FALSE);
2526 return private->mapped;
2529 /*************************************************************
2530 * gdk_window_is_viewable:
2531 * Check if the window and all ancestors of the window
2532 * are mapped. (This is not necessarily "viewable" in
2533 * the X sense, since we only check as far as we have
2534 * GDK window parents, not to the root window)
2538 * is the window viewable
2539 *************************************************************/
2542 gdk_window_is_viewable (GdkWindow *window)
2544 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2546 g_return_val_if_fail (window != NULL, FALSE);
2549 (private != &gdk_root_parent) &&
2550 (private->window_type != GDK_WINDOW_FOREIGN))
2552 if (!private->mapped)
2555 private = (GdkWindowPrivate *)private->parent;
2562 gdk_drawable_set_data (GdkDrawable *drawable,
2565 GDestroyNotify destroy_func)
2567 g_dataset_set_data_full (drawable, key, data, destroy_func);
2571 /* Support for windows that can be guffaw-scrolled
2572 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2576 gdk_window_gravity_works (void)
2578 enum { UNKNOWN, NO, YES };
2579 static gint gravity_works = UNKNOWN;
2581 if (gravity_works == UNKNOWN)
2588 /* This particular server apparently has a bug so that the test
2589 * works but the actual code crashes it
2591 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2592 (VendorRelease (gdk_display) == 3400))
2598 attr.window_type = GDK_WINDOW_TEMP;
2599 attr.wclass = GDK_INPUT_OUTPUT;
2604 attr.event_mask = 0;
2606 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2608 attr.window_type = GDK_WINDOW_CHILD;
2609 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2611 gdk_window_set_static_win_gravity (child, TRUE);
2613 gdk_window_resize (parent, 100, 110);
2614 gdk_window_move (parent, 0, -10);
2615 gdk_window_move_resize (parent, 0, 0, 100, 100);
2617 gdk_window_resize (parent, 100, 110);
2618 gdk_window_move (parent, 0, -10);
2619 gdk_window_move_resize (parent, 0, 0, 100, 100);
2621 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2623 gdk_window_destroy (parent);
2624 gdk_window_destroy (child);
2626 gravity_works = ((y == -20) ? YES : NO);
2629 return (gravity_works == YES);
2633 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2635 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2636 XSetWindowAttributes xattributes;
2638 g_return_if_fail (window != NULL);
2640 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2641 XChangeWindowAttributes (private->xdisplay,
2643 CWBitGravity, &xattributes);
2647 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2649 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2650 XSetWindowAttributes xattributes;
2652 g_return_if_fail (window != NULL);
2654 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2656 XChangeWindowAttributes (private->xdisplay,
2658 CWWinGravity, &xattributes);
2661 /*************************************************************
2662 * gdk_window_set_static_gravities:
2663 * Set the bit gravity of the given window to static,
2664 * and flag it so all children get static subwindow
2667 * window: window for which to set static gravity
2668 * use_static: Whether to turn static gravity on or off.
2670 * Does the XServer support static gravity?
2671 *************************************************************/
2674 gdk_window_set_static_gravities (GdkWindow *window,
2675 gboolean use_static)
2677 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2680 g_return_val_if_fail (window != NULL, FALSE);
2682 if (!use_static == !private->guffaw_gravity)
2685 if (use_static && !gdk_window_gravity_works ())
2688 private->guffaw_gravity = use_static;
2690 gdk_window_set_static_bit_gravity (window, use_static);
2692 tmp_list = private->children;
2695 gdk_window_set_static_win_gravity (window, use_static);
2697 tmp_list = tmp_list->next;