1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
34 #include "gdkprivate.h"
43 #include <X11/extensions/shape.h>
46 const int gdk_event_mask_table[20] =
50 PointerMotionHintMask,
55 ButtonPressMask | OwnerGrabButtonMask,
56 ButtonReleaseMask | OwnerGrabButtonMask,
67 SubstructureNotifyMask
69 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
71 /* Forward declarations */
72 static gboolean gdk_window_gravity_works (void);
73 static void gdk_window_set_static_win_gravity (GdkWindow *window,
75 static gboolean gdk_window_have_shape_ext (void);
77 /* internal function created for and used by gdk_window_xid_at_coords */
79 gdk_window_xid_at (Window base,
88 GdkWindowPrivate *private;
91 Window child = 0, parent_win = 0, root_win = 0;
93 unsigned int ww, wh, wb, wd, num;
96 window = (GdkWindow*) &gdk_root_parent;
97 private = (GdkWindowPrivate*) window;
98 disp = private->xdisplay;
99 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
106 (x < (int) (wx + ww)) &&
107 (y < (int) (wy + wh))))
110 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
115 for (i = num - 1; ; i--)
117 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
119 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
134 * The following fucntion by The Rasterman <raster@redhat.com>
135 * This function returns the X Window ID in which the x y location is in
136 * (x and y being relative to the root window), excluding any windows listed
137 * in the GList excludes (this is a list of X Window ID's - gpointer being
140 * This is primarily designed for internal gdk use - for DND for example
141 * when using a shaped icon window as the drag object - you exclude the
142 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
143 * You can get back an X Window ID as to what X Window ID is infact under
144 * those X,Y co-ordinates.
147 gdk_window_xid_at_coords (gint x,
153 GdkWindowPrivate *private;
156 Window root, child = 0, parent_win = 0, root_win = 0;
160 window = (GdkWindow*) &gdk_root_parent;
161 private = (GdkWindowPrivate*) window;
162 disp = private->xdisplay;
163 root = private->xwindow;
164 num = g_list_length (excludes);
167 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
169 XUngrabServer (disp);
177 XWindowAttributes xwa;
179 XGetWindowAttributes (disp, list [i], &xwa);
181 if (xwa.map_state != IsViewable)
184 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
187 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
192 if (!g_list_find (excludes, (gpointer *) child))
195 XUngrabServer (disp);
202 XUngrabServer (disp);
208 XUngrabServer (disp);
213 gdk_window_init (void)
215 XWindowAttributes xattributes;
218 unsigned int border_width;
222 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
223 &x, &y, &width, &height, &border_width, &depth);
224 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
226 gdk_root_parent.xwindow = gdk_root_window;
227 gdk_root_parent.xdisplay = gdk_display;
228 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
229 gdk_root_parent.window.user_data = NULL;
230 gdk_root_parent.width = width;
231 gdk_root_parent.height = height;
232 gdk_root_parent.children = NULL;
233 gdk_root_parent.colormap = NULL;
234 gdk_root_parent.ref_count = 1;
236 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
239 static GdkAtom wm_client_leader_atom = GDK_NONE;
242 gdk_window_new (GdkWindow *parent,
243 GdkWindowAttr *attributes,
244 gint attributes_mask)
247 GdkWindowPrivate *private;
248 GdkWindowPrivate *parent_private;
250 Display *parent_display;
253 XSetWindowAttributes xattributes;
254 long xattributes_mask;
255 XSizeHints size_hints;
257 XClassHint *class_hint;
263 g_return_val_if_fail (attributes != NULL, NULL);
266 parent = (GdkWindow*) &gdk_root_parent;
268 parent_private = (GdkWindowPrivate*) parent;
269 if (parent_private->destroyed)
272 xparent = parent_private->xwindow;
273 parent_display = parent_private->xdisplay;
275 private = g_new (GdkWindowPrivate, 1);
276 window = (GdkWindow*) private;
278 private->parent = parent;
280 private->xdisplay = parent_display;
281 private->destroyed = FALSE;
282 private->mapped = FALSE;
283 private->guffaw_gravity = FALSE;
284 private->resize_count = 0;
285 private->ref_count = 1;
286 xattributes_mask = 0;
288 if (attributes_mask & GDK_WA_X)
293 if (attributes_mask & GDK_WA_Y)
300 private->width = (attributes->width > 1) ? (attributes->width) : (1);
301 private->height = (attributes->height > 1) ? (attributes->height) : (1);
302 private->window_type = attributes->window_type;
303 private->extension_events = FALSE;
305 private->filters = NULL;
306 private->children = NULL;
308 window->user_data = NULL;
310 if (attributes_mask & GDK_WA_VISUAL)
311 visual = attributes->visual;
313 visual = gdk_visual_get_system ();
314 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
316 xattributes.event_mask = StructureNotifyMask;
317 for (i = 0; i < gdk_nevent_masks; i++)
319 if (attributes->event_mask & (1 << (i + 1)))
320 xattributes.event_mask |= gdk_event_mask_table[i];
323 if (xattributes.event_mask)
324 xattributes_mask |= CWEventMask;
326 if (attributes_mask & GDK_WA_NOREDIR)
328 xattributes.override_redirect =
329 (attributes->override_redirect == FALSE)?False:True;
330 xattributes_mask |= CWOverrideRedirect;
333 xattributes.override_redirect = False;
335 if (parent_private && parent_private->guffaw_gravity)
337 xattributes.win_gravity = StaticGravity;
338 xattributes_mask |= CWWinGravity;
341 if (attributes->wclass == GDK_INPUT_OUTPUT)
344 depth = visual->depth;
346 if (attributes_mask & GDK_WA_COLORMAP)
347 private->colormap = attributes->colormap;
350 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
351 private->colormap = gdk_colormap_get_system ();
353 private->colormap = gdk_colormap_new (visual, False);
356 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
357 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
358 xattributes_mask |= CWBorderPixel | CWBackPixel;
360 switch (private->window_type)
362 case GDK_WINDOW_TOPLEVEL:
363 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
364 xattributes_mask |= CWColormap;
366 xparent = gdk_root_window;
369 case GDK_WINDOW_CHILD:
370 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
371 xattributes_mask |= CWColormap;
374 case GDK_WINDOW_DIALOG:
375 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
376 xattributes_mask |= CWColormap;
378 xparent = gdk_root_window;
381 case GDK_WINDOW_TEMP:
382 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
383 xattributes_mask |= CWColormap;
385 xparent = gdk_root_window;
387 xattributes.save_under = True;
388 xattributes.override_redirect = True;
389 xattributes.cursor = None;
390 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
392 case GDK_WINDOW_ROOT:
393 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
395 case GDK_WINDOW_PIXMAP:
396 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
404 private->colormap = NULL;
407 private->xwindow = XCreateWindow (private->xdisplay, xparent,
408 x, y, private->width, private->height,
409 0, depth, class, xvisual,
410 xattributes_mask, &xattributes);
411 gdk_window_ref (window);
412 gdk_xid_table_insert (&private->xwindow, window);
414 if (private->colormap)
415 gdk_colormap_ref (private->colormap);
417 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
418 (attributes->cursor) :
422 parent_private->children = g_list_prepend (parent_private->children, window);
424 switch (private->window_type)
426 case GDK_WINDOW_DIALOG:
427 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
428 case GDK_WINDOW_TOPLEVEL:
429 case GDK_WINDOW_TEMP:
430 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
432 case GDK_WINDOW_CHILD:
433 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
434 (private->colormap != gdk_colormap_get_system ()) &&
435 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
437 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
438 gdk_window_add_colormap_windows (window);
447 size_hints.flags = PSize;
448 size_hints.width = private->width;
449 size_hints.height = private->height;
451 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
452 wm_hints.window_group = gdk_leader_window;
453 wm_hints.input = True;
454 wm_hints.initial_state = NormalState;
456 /* FIXME: Is there any point in doing this? Do any WM's pay
457 * attention to PSize, and even if they do, is this the
460 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
462 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
464 if (!wm_client_leader_atom)
465 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
467 XChangeProperty (private->xdisplay, private->xwindow,
468 wm_client_leader_atom,
469 XA_WINDOW, 32, PropModeReplace,
470 (guchar*) &gdk_leader_window, 1);
472 if (attributes_mask & GDK_WA_TITLE)
473 title = attributes->title;
475 title = g_get_prgname ();
477 XmbSetWMProperties (private->xdisplay, private->xwindow,
482 if (attributes_mask & GDK_WA_WMCLASS)
484 class_hint = XAllocClassHint ();
485 class_hint->res_name = attributes->wmclass_name;
486 class_hint->res_class = attributes->wmclass_class;
487 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
496 gdk_window_foreign_new (guint32 anid)
499 GdkWindowPrivate *private;
500 GdkWindowPrivate *parent_private;
501 XWindowAttributes attrs;
503 Window *children = NULL;
507 gdk_error_trap_push ();
508 result = XGetWindowAttributes (gdk_display, anid, &attrs);
509 if (gdk_error_trap_pop () || !result)
512 /* FIXME: This is pretty expensive. Maybe the caller should supply
514 gdk_error_trap_push ();
515 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
516 if (gdk_error_trap_pop () || !result)
519 private = g_new (GdkWindowPrivate, 1);
520 window = (GdkWindow*) private;
524 private->parent = gdk_xid_table_lookup (parent);
526 parent_private = (GdkWindowPrivate *)private->parent;
529 parent_private->children = g_list_prepend (parent_private->children, window);
531 private->xwindow = anid;
532 private->xdisplay = gdk_display;
533 private->x = attrs.x;
534 private->y = attrs.y;
535 private->width = attrs.width;
536 private->height = attrs.height;
537 private->resize_count = 0;
538 private->ref_count = 1;
539 private->window_type = GDK_WINDOW_FOREIGN;
540 private->destroyed = FALSE;
541 private->mapped = (attrs.map_state != IsUnmapped);
542 private->guffaw_gravity = FALSE;
543 private->extension_events = 0;
545 private->colormap = NULL;
547 private->filters = NULL;
548 private->children = NULL;
550 window->user_data = NULL;
552 gdk_window_ref (window);
553 gdk_xid_table_insert (&private->xwindow, window);
558 /* Call this function when you want a window and all its children to
559 * disappear. When xdestroy is true, a request to destroy the XWindow
560 * is sent out. When it is false, it is assumed that the XWindow has
561 * been or will be destroyed by destroying some ancestor of this
565 gdk_window_internal_destroy (GdkWindow *window,
567 gboolean our_destroy)
569 GdkWindowPrivate *private;
570 GdkWindowPrivate *temp_private;
571 GdkWindow *temp_window;
575 g_return_if_fail (window != NULL);
577 private = (GdkWindowPrivate*) window;
579 switch (private->window_type)
581 case GDK_WINDOW_TOPLEVEL:
582 case GDK_WINDOW_CHILD:
583 case GDK_WINDOW_DIALOG:
584 case GDK_WINDOW_TEMP:
585 case GDK_WINDOW_FOREIGN:
586 if (!private->destroyed)
590 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
591 if (parent_private->children)
592 parent_private->children = g_list_remove (parent_private->children, window);
595 if (private->window_type != GDK_WINDOW_FOREIGN)
597 children = tmp = private->children;
598 private->children = NULL;
602 temp_window = tmp->data;
605 temp_private = (GdkWindowPrivate*) temp_window;
607 gdk_window_internal_destroy (temp_window, FALSE,
611 g_list_free (children);
614 if (private->extension_events != 0)
615 gdk_input_window_destroy (window);
617 if (private->filters)
619 tmp = private->filters;
627 g_list_free (private->filters);
628 private->filters = NULL;
631 if (private->window_type == GDK_WINDOW_FOREIGN)
633 if (our_destroy && (private->parent != NULL))
635 /* It's somebody elses window, but in our heirarchy,
636 * so reparent it to the root window, and then send
637 * it a delete event, as if we were a WM
639 XClientMessageEvent xevent;
641 gdk_error_trap_push ();
642 gdk_window_hide (window);
643 gdk_window_reparent (window, NULL, 0, 0);
645 xevent.type = ClientMessage;
646 xevent.window = private->xwindow;
647 xevent.message_type = gdk_wm_protocols;
649 xevent.data.l[0] = gdk_wm_delete_window;
650 xevent.data.l[1] = CurrentTime;
652 XSendEvent (private->xdisplay, private->xwindow,
653 False, 0, (XEvent *)&xevent);
655 gdk_error_trap_pop ();
659 XDestroyWindow (private->xdisplay, private->xwindow);
661 if (private->colormap)
662 gdk_colormap_unref (private->colormap);
664 private->mapped = FALSE;
665 private->destroyed = TRUE;
669 case GDK_WINDOW_ROOT:
670 g_error ("attempted to destroy root window");
673 case GDK_WINDOW_PIXMAP:
674 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
679 /* Like internal_destroy, but also destroys the reference created by
683 gdk_window_destroy (GdkWindow *window)
685 gdk_window_internal_destroy (window, TRUE, TRUE);
686 gdk_window_unref (window);
689 /* This function is called when the XWindow is really gone. */
692 gdk_window_destroy_notify (GdkWindow *window)
694 GdkWindowPrivate *private;
696 g_return_if_fail (window != NULL);
698 private = (GdkWindowPrivate*) window;
700 if (!private->destroyed)
702 if (private->window_type != GDK_WINDOW_FOREIGN)
703 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
705 gdk_window_internal_destroy (window, FALSE, FALSE);
708 gdk_xid_table_remove (private->xwindow);
709 gdk_window_unref (window);
713 gdk_window_ref (GdkWindow *window)
715 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
716 g_return_val_if_fail (window != NULL, NULL);
718 private->ref_count += 1;
723 gdk_window_unref (GdkWindow *window)
725 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
726 g_return_if_fail (window != NULL);
727 g_return_if_fail (private->ref_count > 0);
729 private->ref_count -= 1;
730 if (private->ref_count == 0)
732 if (!private->destroyed)
734 if (private->window_type == GDK_WINDOW_FOREIGN)
735 gdk_xid_table_remove (private->xwindow);
737 g_warning ("losing last reference to undestroyed window\n");
739 g_dataset_destroy (window);
745 gdk_window_show (GdkWindow *window)
747 GdkWindowPrivate *private;
749 g_return_if_fail (window != NULL);
751 private = (GdkWindowPrivate*) window;
752 if (!private->destroyed)
754 private->mapped = TRUE;
755 XRaiseWindow (private->xdisplay, private->xwindow);
756 XMapWindow (private->xdisplay, private->xwindow);
761 gdk_window_hide (GdkWindow *window)
763 GdkWindowPrivate *private;
765 g_return_if_fail (window != NULL);
767 private = (GdkWindowPrivate*) window;
768 if (!private->destroyed)
770 private->mapped = FALSE;
771 XUnmapWindow (private->xdisplay, private->xwindow);
776 gdk_window_withdraw (GdkWindow *window)
778 GdkWindowPrivate *private;
780 g_return_if_fail (window != NULL);
782 private = (GdkWindowPrivate*) window;
783 if (!private->destroyed)
784 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
788 gdk_window_move (GdkWindow *window,
792 GdkWindowPrivate *private;
794 g_return_if_fail (window != NULL);
796 private = (GdkWindowPrivate*) window;
797 if (!private->destroyed)
799 XMoveWindow (private->xdisplay, private->xwindow, x, y);
801 if (private->window_type == GDK_WINDOW_CHILD)
810 gdk_window_resize (GdkWindow *window,
814 GdkWindowPrivate *private;
816 g_return_if_fail (window != NULL);
823 private = (GdkWindowPrivate*) window;
825 if (!private->destroyed &&
826 ((private->resize_count > 0) ||
827 (private->width != (guint16) width) ||
828 (private->height != (guint16) height)))
830 XResizeWindow (private->xdisplay, private->xwindow, width, height);
831 private->resize_count += 1;
833 if (private->window_type == GDK_WINDOW_CHILD)
835 private->width = width;
836 private->height = height;
842 gdk_window_move_resize (GdkWindow *window,
848 GdkWindowPrivate *private;
850 g_return_if_fail (window != NULL);
857 private = (GdkWindowPrivate*) window;
858 if (!private->destroyed)
860 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
862 if (private->guffaw_gravity)
864 GList *tmp_list = private->children;
867 GdkWindowPrivate *child_private = tmp_list->data;
869 child_private->x -= x - private->x;
870 child_private->y -= y - private->y;
872 tmp_list = tmp_list->next;
876 if (private->window_type == GDK_WINDOW_CHILD)
880 private->width = width;
881 private->height = height;
887 gdk_window_reparent (GdkWindow *window,
888 GdkWindow *new_parent,
892 GdkWindowPrivate *window_private;
893 GdkWindowPrivate *parent_private;
894 GdkWindowPrivate *old_parent_private;
896 g_return_if_fail (window != NULL);
899 new_parent = (GdkWindow*) &gdk_root_parent;
901 window_private = (GdkWindowPrivate*) window;
902 old_parent_private = (GdkWindowPrivate*)window_private->parent;
903 parent_private = (GdkWindowPrivate*) new_parent;
905 if (!window_private->destroyed && !parent_private->destroyed)
906 XReparentWindow (window_private->xdisplay,
907 window_private->xwindow,
908 parent_private->xwindow,
911 window_private->parent = new_parent;
913 if (old_parent_private)
914 old_parent_private->children = g_list_remove (old_parent_private->children, window);
916 if ((old_parent_private &&
917 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
918 (!old_parent_private && parent_private->guffaw_gravity))
919 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
921 parent_private->children = g_list_prepend (parent_private->children, window);
925 gdk_window_clear (GdkWindow *window)
927 GdkWindowPrivate *private;
929 g_return_if_fail (window != NULL);
931 private = (GdkWindowPrivate*) window;
933 if (!private->destroyed)
934 XClearWindow (private->xdisplay, private->xwindow);
938 gdk_window_clear_area (GdkWindow *window,
944 GdkWindowPrivate *private;
946 g_return_if_fail (window != NULL);
948 private = (GdkWindowPrivate*) window;
950 if (!private->destroyed)
951 XClearArea (private->xdisplay, private->xwindow,
952 x, y, width, height, False);
956 gdk_window_clear_area_e (GdkWindow *window,
962 GdkWindowPrivate *private;
964 g_return_if_fail (window != NULL);
966 private = (GdkWindowPrivate*) window;
968 if (!private->destroyed)
969 XClearArea (private->xdisplay, private->xwindow,
970 x, y, width, height, True);
974 gdk_window_copy_area (GdkWindow *window,
978 GdkWindow *source_window,
984 GdkWindowPrivate *src_private;
985 GdkWindowPrivate *dest_private;
986 GdkGCPrivate *gc_private;
988 g_return_if_fail (window != NULL);
989 g_return_if_fail (gc != NULL);
991 if (source_window == NULL)
992 source_window = window;
994 src_private = (GdkWindowPrivate*) source_window;
995 dest_private = (GdkWindowPrivate*) window;
996 gc_private = (GdkGCPrivate*) gc;
998 if (!src_private->destroyed && !dest_private->destroyed)
1000 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
1009 gdk_window_raise (GdkWindow *window)
1011 GdkWindowPrivate *private;
1013 g_return_if_fail (window != NULL);
1015 private = (GdkWindowPrivate*) window;
1017 if (!private->destroyed)
1018 XRaiseWindow (private->xdisplay, private->xwindow);
1022 gdk_window_lower (GdkWindow *window)
1024 GdkWindowPrivate *private;
1026 g_return_if_fail (window != NULL);
1028 private = (GdkWindowPrivate*) window;
1030 if (!private->destroyed)
1031 XLowerWindow (private->xdisplay, private->xwindow);
1035 gdk_window_set_user_data (GdkWindow *window,
1038 g_return_if_fail (window != NULL);
1040 window->user_data = user_data;
1044 gdk_window_set_hints (GdkWindow *window,
1053 GdkWindowPrivate *private;
1054 XSizeHints size_hints;
1056 g_return_if_fail (window != NULL);
1058 private = (GdkWindowPrivate*) window;
1059 if (private->destroyed)
1062 size_hints.flags = 0;
1064 if (flags & GDK_HINT_POS)
1066 size_hints.flags |= PPosition;
1071 if (flags & GDK_HINT_MIN_SIZE)
1073 size_hints.flags |= PMinSize;
1074 size_hints.min_width = min_width;
1075 size_hints.min_height = min_height;
1078 if (flags & GDK_HINT_MAX_SIZE)
1080 size_hints.flags |= PMaxSize;
1081 size_hints.max_width = max_width;
1082 size_hints.max_height = max_height;
1085 /* FIXME: Would it be better to delete this property of
1086 * flags == 0? It would save space on the server
1088 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1092 gdk_window_set_geometry_hints (GdkWindow *window,
1093 GdkGeometry *geometry,
1094 GdkWindowHints geom_mask)
1096 GdkWindowPrivate *private;
1097 XSizeHints size_hints;
1099 g_return_if_fail (window != NULL);
1101 private = (GdkWindowPrivate*) window;
1102 if (private->destroyed)
1105 size_hints.flags = 0;
1107 if (geom_mask & GDK_HINT_POS)
1109 size_hints.flags |= PPosition;
1110 /* We need to initialize the following obsolete fields because KWM
1111 * apparently uses these fields if they are non-zero.
1118 if (geom_mask & GDK_HINT_MIN_SIZE)
1120 size_hints.flags |= PMinSize;
1121 size_hints.min_width = geometry->min_width;
1122 size_hints.min_height = geometry->min_height;
1125 if (geom_mask & GDK_HINT_MAX_SIZE)
1127 size_hints.flags |= PMaxSize;
1128 size_hints.max_width = MAX (geometry->max_width, 1);
1129 size_hints.max_height = MAX (geometry->max_height, 1);
1132 if (geom_mask & GDK_HINT_BASE_SIZE)
1134 size_hints.flags |= PBaseSize;
1135 size_hints.base_width = geometry->base_width;
1136 size_hints.base_height = geometry->base_height;
1139 if (geom_mask & GDK_HINT_RESIZE_INC)
1141 size_hints.flags |= PResizeInc;
1142 size_hints.width_inc = geometry->width_inc;
1143 size_hints.height_inc = geometry->height_inc;
1146 if (geom_mask & GDK_HINT_ASPECT)
1148 size_hints.flags |= PAspect;
1149 if (geometry->min_aspect <= 1)
1151 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1152 size_hints.min_aspect.y = 65536;
1156 size_hints.min_aspect.x = 65536;
1157 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1159 if (geometry->max_aspect <= 1)
1161 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1162 size_hints.max_aspect.y = 65536;
1166 size_hints.max_aspect.x = 65536;
1167 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1171 /* FIXME: Would it be better to delete this property of
1172 * geom_mask == 0? It would save space on the server
1174 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1178 gdk_window_set_title (GdkWindow *window,
1181 GdkWindowPrivate *private;
1183 g_return_if_fail (window != NULL);
1185 private = (GdkWindowPrivate*) window;
1186 if (!private->destroyed)
1187 XmbSetWMProperties (private->xdisplay, private->xwindow,
1188 title, title, NULL, 0, NULL, NULL, NULL);
1192 gdk_window_set_role (GdkWindow *window,
1195 GdkWindowPrivate *private;
1197 g_return_if_fail (window != NULL);
1199 private = (GdkWindowPrivate*) window;
1202 XChangeProperty (private->xdisplay, private->xwindow,
1203 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1204 8, PropModeReplace, role, strlen (role));
1206 XDeleteProperty (private->xdisplay, private->xwindow,
1207 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1211 gdk_window_set_transient_for (GdkWindow *window,
1214 GdkWindowPrivate *private;
1215 GdkWindowPrivate *parent_private;
1217 g_return_if_fail (window != NULL);
1219 private = (GdkWindowPrivate*) window;
1220 parent_private = (GdkWindowPrivate*) parent;
1222 if (!private->destroyed && !parent_private->destroyed)
1223 XSetTransientForHint (private->xdisplay,
1224 private->xwindow, parent_private->xwindow);
1228 gdk_window_set_background (GdkWindow *window,
1231 GdkWindowPrivate *private;
1233 g_return_if_fail (window != NULL);
1235 private = (GdkWindowPrivate*) window;
1236 if (!private->destroyed)
1237 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1241 gdk_window_set_back_pixmap (GdkWindow *window,
1243 gint parent_relative)
1245 GdkWindowPrivate *window_private;
1246 GdkPixmapPrivate *pixmap_private;
1249 g_return_if_fail (window != NULL);
1251 window_private = (GdkWindowPrivate*) window;
1252 pixmap_private = (GdkPixmapPrivate*) pixmap;
1255 xpixmap = pixmap_private->xwindow;
1259 if (parent_relative)
1260 xpixmap = ParentRelative;
1262 if (!window_private->destroyed)
1263 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1267 gdk_window_set_cursor (GdkWindow *window,
1270 GdkWindowPrivate *window_private;
1271 GdkCursorPrivate *cursor_private;
1274 g_return_if_fail (window != NULL);
1276 window_private = (GdkWindowPrivate*) window;
1277 cursor_private = (GdkCursorPrivate*) cursor;
1282 xcursor = cursor_private->xcursor;
1284 if (!window_private->destroyed)
1285 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1289 gdk_window_set_colormap (GdkWindow *window,
1290 GdkColormap *colormap)
1292 GdkWindowPrivate *window_private;
1293 GdkColormapPrivate *colormap_private;
1295 g_return_if_fail (window != NULL);
1296 g_return_if_fail (colormap != NULL);
1298 window_private = (GdkWindowPrivate*) window;
1299 colormap_private = (GdkColormapPrivate*) colormap;
1301 if (!window_private->destroyed)
1303 XSetWindowColormap (window_private->xdisplay,
1304 window_private->xwindow,
1305 colormap_private->xcolormap);
1307 if (window_private->colormap)
1308 gdk_colormap_unref (window_private->colormap);
1309 window_private->colormap = colormap;
1310 gdk_colormap_ref (window_private->colormap);
1312 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1313 gdk_window_add_colormap_windows (window);
1318 gdk_window_get_user_data (GdkWindow *window,
1321 g_return_if_fail (window != NULL);
1323 *data = window->user_data;
1327 gdk_window_get_geometry (GdkWindow *window,
1334 GdkWindowPrivate *window_private;
1340 guint tborder_width;
1344 window = (GdkWindow*) &gdk_root_parent;
1346 window_private = (GdkWindowPrivate*) window;
1348 if (!window_private->destroyed)
1350 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1351 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1367 gdk_window_get_position (GdkWindow *window,
1371 GdkWindowPrivate *window_private;
1373 g_return_if_fail (window != NULL);
1375 window_private = (GdkWindowPrivate*) window;
1378 *x = window_private->x;
1380 *y = window_private->y;
1384 gdk_window_get_size (GdkWindow *window,
1388 GdkWindowPrivate *window_private;
1390 g_return_if_fail (window != NULL);
1392 window_private = (GdkWindowPrivate*) window;
1395 *width = window_private->width;
1397 *height = window_private->height;
1401 gdk_window_get_visual (GdkWindow *window)
1403 GdkWindowPrivate *window_private;
1404 XWindowAttributes window_attributes;
1406 g_return_val_if_fail (window != NULL, NULL);
1408 window_private = (GdkWindowPrivate*) window;
1409 /* Huh? ->parent is never set for a pixmap. We should just return
1412 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1413 window_private = (GdkWindowPrivate*) window_private->parent;
1415 if (window_private && !window_private->destroyed)
1417 if (window_private->colormap == NULL)
1419 XGetWindowAttributes (window_private->xdisplay,
1420 window_private->xwindow,
1421 &window_attributes);
1422 return gdk_visual_lookup (window_attributes.visual);
1425 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1432 gdk_window_get_colormap (GdkWindow *window)
1434 GdkWindowPrivate *window_private;
1435 XWindowAttributes window_attributes;
1437 g_return_val_if_fail (window != NULL, NULL);
1438 window_private = (GdkWindowPrivate*) window;
1440 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1441 if (!window_private->destroyed)
1443 if (window_private->colormap == NULL)
1445 XGetWindowAttributes (window_private->xdisplay,
1446 window_private->xwindow,
1447 &window_attributes);
1448 return gdk_colormap_lookup (window_attributes.colormap);
1451 return window_private->colormap;
1458 gdk_window_get_type (GdkWindow *window)
1460 GdkWindowPrivate *window_private;
1462 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1464 window_private = (GdkWindowPrivate*) window;
1465 return window_private->window_type;
1469 gdk_window_get_origin (GdkWindow *window,
1473 GdkWindowPrivate *private;
1479 g_return_val_if_fail (window != NULL, 0);
1481 private = (GdkWindowPrivate*) window;
1483 if (!private->destroyed)
1485 return_val = XTranslateCoordinates (private->xdisplay,
1504 gdk_window_get_deskrelative_origin (GdkWindow *window,
1508 GdkWindowPrivate *private;
1509 gboolean return_val = FALSE;
1510 gint num_children, format_return;
1511 Window win, *child, parent, root;
1515 static Atom atom = 0;
1516 gulong number_return, bytes_after_return;
1517 guchar *data_return;
1519 g_return_val_if_fail (window != NULL, 0);
1521 private = (GdkWindowPrivate*) window;
1523 if (!private->destroyed)
1526 atom = XInternAtom (private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1527 win = private->xwindow;
1529 while (XQueryTree (private->xdisplay, win, &root, &parent,
1530 &child, (unsigned int *)&num_children))
1532 if ((child) && (num_children > 0))
1544 XGetWindowProperty (private->xdisplay, win, atom, 0, 0,
1545 False, XA_CARDINAL, &type_return, &format_return,
1546 &number_return, &bytes_after_return, &data_return);
1547 if (type_return == XA_CARDINAL)
1549 XFree (data_return);
1554 return_val = XTranslateCoordinates (private->xdisplay,
1570 gdk_window_get_root_origin (GdkWindow *window,
1574 GdkWindowPrivate *private;
1579 unsigned int nchildren;
1581 g_return_if_fail (window != NULL);
1583 private = (GdkWindowPrivate*) window;
1588 if (private->destroyed)
1591 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1592 private = (GdkWindowPrivate*) private->parent;
1593 if (private->destroyed)
1596 xparent = private->xwindow;
1600 if (!XQueryTree (private->xdisplay, xwindow,
1602 &children, &nchildren))
1608 while (xparent != root);
1610 if (xparent == root)
1612 unsigned int ww, wh, wb, wd;
1615 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1626 gdk_window_get_pointer (GdkWindow *window,
1629 GdkModifierType *mask)
1631 GdkWindowPrivate *private;
1632 GdkWindow *return_val;
1638 unsigned int xmask = 0;
1641 window = (GdkWindow*) &gdk_root_parent;
1643 private = (GdkWindowPrivate*) window;
1646 if (!private->destroyed &&
1647 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1648 &rootx, &rooty, &winx, &winy, &xmask))
1651 return_val = gdk_window_lookup (child);
1665 gdk_window_at_pointer (gint *win_x,
1668 GdkWindowPrivate *private;
1672 Window xwindow_last = 0;
1673 int rootx = -1, rooty = -1;
1677 private = &gdk_root_parent;
1679 xwindow = private->xwindow;
1681 XGrabServer (private->xdisplay);
1684 xwindow_last = xwindow;
1685 XQueryPointer (private->xdisplay,
1692 XUngrabServer (private->xdisplay);
1694 window = gdk_window_lookup (xwindow_last);
1697 *win_x = window ? winx : -1;
1699 *win_y = window ? winy : -1;
1705 gdk_window_get_parent (GdkWindow *window)
1707 g_return_val_if_fail (window != NULL, NULL);
1709 return ((GdkWindowPrivate*) window)->parent;
1713 gdk_window_get_toplevel (GdkWindow *window)
1715 GdkWindowPrivate *private;
1717 g_return_val_if_fail (window != NULL, NULL);
1719 private = (GdkWindowPrivate*) window;
1721 while (private->window_type == GDK_WINDOW_CHILD)
1723 window = ((GdkWindowPrivate*) window)->parent;
1724 private = (GdkWindowPrivate*) window;
1731 gdk_window_get_children (GdkWindow *window)
1733 GdkWindowPrivate *private;
1739 unsigned int nchildren;
1742 g_return_val_if_fail (window != NULL, NULL);
1744 private = (GdkWindowPrivate*) window;
1745 if (private->destroyed)
1748 XQueryTree (private->xdisplay, private->xwindow,
1749 &root, &parent, &xchildren, &nchildren);
1755 for (i = 0; i < nchildren; i++)
1757 child = gdk_window_lookup (xchildren[i]);
1759 children = g_list_prepend (children, child);
1770 gdk_window_get_events (GdkWindow *window)
1772 GdkWindowPrivate *private;
1773 XWindowAttributes attrs;
1774 GdkEventMask event_mask;
1777 g_return_val_if_fail (window != NULL, 0);
1779 private = (GdkWindowPrivate*) window;
1780 if (private->destroyed)
1783 XGetWindowAttributes (gdk_display, private->xwindow,
1787 for (i = 0; i < gdk_nevent_masks; i++)
1789 if (attrs.your_event_mask & gdk_event_mask_table[i])
1790 event_mask |= 1 << (i + 1);
1797 gdk_window_set_events (GdkWindow *window,
1798 GdkEventMask event_mask)
1800 GdkWindowPrivate *private;
1804 g_return_if_fail (window != NULL);
1806 private = (GdkWindowPrivate*) window;
1807 if (private->destroyed)
1810 xevent_mask = StructureNotifyMask;
1811 for (i = 0; i < gdk_nevent_masks; i++)
1813 if (event_mask & (1 << (i + 1)))
1814 xevent_mask |= gdk_event_mask_table[i];
1817 XSelectInput (gdk_display, private->xwindow,
1822 gdk_window_add_colormap_windows (GdkWindow *window)
1824 GdkWindow *toplevel;
1825 GdkWindowPrivate *toplevel_private;
1826 GdkWindowPrivate *window_private;
1827 Window *old_windows;
1828 Window *new_windows;
1831 g_return_if_fail (window != NULL);
1833 toplevel = gdk_window_get_toplevel (window);
1834 toplevel_private = (GdkWindowPrivate*) toplevel;
1835 window_private = (GdkWindowPrivate*) window;
1836 if (window_private->destroyed)
1840 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1841 toplevel_private->xwindow,
1842 &old_windows, &count))
1847 for (i = 0; i < count; i++)
1848 if (old_windows[i] == window_private->xwindow)
1850 XFree (old_windows);
1854 new_windows = g_new (Window, count + 1);
1856 for (i = 0; i < count; i++)
1857 new_windows[i] = old_windows[i];
1858 new_windows[count] = window_private->xwindow;
1860 XSetWMColormapWindows (toplevel_private->xdisplay,
1861 toplevel_private->xwindow,
1862 new_windows, count + 1);
1864 g_free (new_windows);
1866 XFree (old_windows);
1870 gdk_window_have_shape_ext (void)
1872 enum { UNKNOWN, NO, YES };
1873 static gint have_shape = UNKNOWN;
1875 if (have_shape == UNKNOWN)
1878 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1884 return (have_shape == YES);
1888 * This needs the X11 shape extension.
1889 * If not available, shaped windows will look
1890 * ugly, but programs still work. Stefan Wille
1893 gdk_window_shape_combine_mask (GdkWindow *window,
1897 GdkWindowPrivate *window_private;
1900 g_return_if_fail (window != NULL);
1902 #ifdef HAVE_SHAPE_EXT
1903 window_private = (GdkWindowPrivate*) window;
1904 if (window_private->destroyed)
1907 if (gdk_window_have_shape_ext ())
1911 GdkWindowPrivate *pixmap_private;
1913 pixmap_private = (GdkWindowPrivate*) mask;
1914 pixmap = (Pixmap) pixmap_private->xwindow;
1923 XShapeCombineMask (window_private->xdisplay,
1924 window_private->xwindow,
1930 #endif /* HAVE_SHAPE_EXT */
1934 gdk_window_add_filter (GdkWindow *window,
1935 GdkFilterFunc function,
1938 GdkWindowPrivate *private;
1940 GdkEventFilter *filter;
1942 private = (GdkWindowPrivate*) window;
1943 if (private && private->destroyed)
1947 tmp_list = private->filters;
1949 tmp_list = gdk_default_filters;
1953 filter = (GdkEventFilter *)tmp_list->data;
1954 if ((filter->function == function) && (filter->data == data))
1956 tmp_list = tmp_list->next;
1959 filter = g_new (GdkEventFilter, 1);
1960 filter->function = function;
1961 filter->data = data;
1964 private->filters = g_list_append (private->filters, filter);
1966 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1970 gdk_window_remove_filter (GdkWindow *window,
1971 GdkFilterFunc function,
1974 GdkWindowPrivate *private;
1975 GList *tmp_list, *node;
1976 GdkEventFilter *filter;
1978 private = (GdkWindowPrivate*) window;
1981 tmp_list = private->filters;
1983 tmp_list = gdk_default_filters;
1987 filter = (GdkEventFilter *)tmp_list->data;
1989 tmp_list = tmp_list->next;
1991 if ((filter->function == function) && (filter->data == data))
1994 private->filters = g_list_remove_link (private->filters, node);
1996 gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
1997 g_list_free_1 (node);
2006 gdk_window_set_override_redirect (GdkWindow *window,
2007 gboolean override_redirect)
2009 GdkWindowPrivate *private;
2010 XSetWindowAttributes attr;
2012 g_return_if_fail (window != NULL);
2013 private = (GdkWindowPrivate*) window;
2014 if (private->destroyed)
2017 attr.override_redirect = (override_redirect == FALSE)?False:True;
2018 XChangeWindowAttributes (gdk_display,
2019 ((GdkWindowPrivate *)window)->xwindow,
2025 gdk_window_set_icon (GdkWindow *window,
2026 GdkWindow *icon_window,
2031 GdkWindowPrivate *window_private;
2032 GdkWindowPrivate *private;
2034 g_return_if_fail (window != NULL);
2035 window_private = (GdkWindowPrivate*) window;
2036 if (window_private->destroyed)
2039 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2041 wm_hints = XAllocWMHints ();
2043 if (icon_window != NULL)
2045 private = (GdkWindowPrivate *)icon_window;
2046 wm_hints->flags |= IconWindowHint;
2047 wm_hints->icon_window = private->xwindow;
2052 private = (GdkWindowPrivate *)pixmap;
2053 wm_hints->flags |= IconPixmapHint;
2054 wm_hints->icon_pixmap = private->xwindow;
2059 private = (GdkWindowPrivate *)mask;
2060 wm_hints->flags |= IconMaskHint;
2061 wm_hints->icon_mask = private->xwindow;
2064 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2069 gdk_window_set_icon_name (GdkWindow *window,
2072 GdkWindowPrivate *window_private;
2073 XTextProperty property;
2076 g_return_if_fail (window != NULL);
2077 window_private = (GdkWindowPrivate*) window;
2078 if (window_private->destroyed)
2080 res = XmbTextListToTextProperty (window_private->xdisplay,
2081 &name, 1, XStdICCTextStyle,
2085 g_warning ("Error converting icon name to text property: %d\n", res);
2089 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2093 XFree (property.value);
2097 gdk_window_set_group (GdkWindow *window,
2101 GdkWindowPrivate *window_private;
2102 GdkWindowPrivate *private;
2104 g_return_if_fail (window != NULL);
2105 g_return_if_fail (leader != NULL);
2106 window_private = (GdkWindowPrivate*) window;
2107 if (window_private->destroyed)
2110 private = (GdkWindowPrivate *)leader;
2112 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2114 wm_hints = XAllocWMHints ();
2116 wm_hints->flags |= WindowGroupHint;
2117 wm_hints->window_group = private->xwindow;
2119 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2124 gdk_window_set_mwm_hints (GdkWindow *window,
2125 MotifWmHints *new_hints)
2127 static Atom hints_atom = None;
2128 MotifWmHints *hints;
2134 GdkWindowPrivate *window_private;
2136 g_return_if_fail (window != NULL);
2137 window_private = (GdkWindowPrivate*) window;
2138 if (window_private->destroyed)
2142 hints_atom = XInternAtom (window_private->xdisplay,
2143 _XA_MOTIF_WM_HINTS, FALSE);
2145 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2146 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2147 False, AnyPropertyType, &type, &format, &nitems,
2148 &bytes_after, (guchar **)&hints);
2154 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2156 hints->flags |= MWM_HINTS_FUNCTIONS;
2157 hints->functions = new_hints->functions;
2159 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2161 hints->flags |= MWM_HINTS_DECORATIONS;
2162 hints->decorations = new_hints->decorations;
2166 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2167 hints_atom, hints_atom, 32, PropModeReplace,
2168 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
2170 if (hints != new_hints)
2175 gdk_window_set_decorations (GdkWindow *window,
2176 GdkWMDecoration decorations)
2180 hints.flags = MWM_HINTS_DECORATIONS;
2181 hints.decorations = decorations;
2183 gdk_window_set_mwm_hints (window, &hints);
2187 gdk_window_set_functions (GdkWindow *window,
2188 GdkWMFunction functions)
2192 hints.flags = MWM_HINTS_FUNCTIONS;
2193 hints.functions = functions;
2195 gdk_window_set_mwm_hints (window, &hints);
2199 gdk_window_get_toplevels (void)
2201 GList *new_list = NULL;
2204 tmp_list = gdk_root_parent.children;
2207 new_list = g_list_prepend (new_list, tmp_list->data);
2208 tmp_list = tmp_list->next;
2215 * propagate the shapes from all child windows of a GDK window to the parent
2216 * window. Shamelessly ripped from Enlightenment's code
2225 struct _gdk_span *next;
2229 gdk_add_to_span (struct _gdk_span **s,
2233 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2240 /* scan the spans for this line */
2243 /* -- -> new span */
2244 /* == -> existing span */
2245 /* ## -> spans intersect */
2246 /* if we are in the middle of spanning the span into the line */
2249 /* case: ---- ==== */
2250 if (xx < ptr1->start - 1)
2252 /* ends before next span - extend to here */
2256 /* case: ----##=== */
2257 else if (xx <= ptr1->end)
2259 /* crosses into next span - delete next span and append */
2260 ss->end = ptr1->end;
2261 ss->next = ptr1->next;
2265 /* case: ---###--- */
2268 /* overlaps next span - delete and keep checking */
2269 ss->next = ptr1->next;
2274 /* otherwise havent started spanning it in yet */
2277 /* case: ---- ==== */
2278 if (xx < ptr1->start - 1)
2280 /* insert span here in list */
2281 noo = g_malloc (sizeof (struct _gdk_span));
2295 /* case: ----##=== */
2296 else if ((x < ptr1->start) && (xx <= ptr1->end))
2298 /* expand this span to the left point of the new one */
2302 /* case: ===###=== */
2303 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2305 /* throw the span away */
2308 /* case: ---###--- */
2309 else if ((x < ptr1->start) && (xx > ptr1->end))
2316 /* case: ===##---- */
2317 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2323 /* case: ==== ---- */
2324 /* case handled by next loop iteration - first case */
2329 /* it started in the middle but spans beyond your current list */
2335 /* it does not start inside a span or in the middle, so add it to the end */
2336 noo = g_malloc (sizeof (struct _gdk_span));
2344 noo->next = ptr2->next;
2357 gdk_add_rectangles (Display *disp,
2359 struct _gdk_span **spans,
2366 gint x1, y1, x2, y2;
2370 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2373 /* go through all clip rects in this window's shape */
2374 for (k = 0; k < rn; k++)
2376 /* for each clip rect, add it to each line's spans */
2378 x2 = x + rl[k].x + (rl[k].width - 1);
2380 y2 = y + rl[k].y + (rl[k].height - 1);
2389 for (a = y1; a <= y2; a++)
2392 gdk_add_to_span (&spans[a], x1, x2);
2400 gdk_propagate_shapes (Display *disp,
2404 Window rt, par, *list = NULL;
2405 gint i, j, num = 0, num_rects = 0;
2409 XRectangle *rects = NULL;
2410 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2411 XWindowAttributes xatt;
2413 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2418 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2420 for (i = 0; i < h; i++)
2422 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2425 /* go through all child windows and create/insert spans */
2426 for (i = 0; i < num; i++)
2428 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2429 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2430 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2433 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2435 /* go through the spans list and build a list of rects */
2436 rects = g_malloc (sizeof (XRectangle) * 256);
2438 for (i = 0; i < baseh; i++)
2441 /* go through the line for all spans */
2444 rects[num_rects].x = ptr1->start;
2445 rects[num_rects].y = i;
2446 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2447 rects[num_rects].height = 1;
2449 /* if there are more lines */
2451 /* while contigous rects (same start/end coords) exist */
2452 while ((contig) && (j < baseh))
2454 /* search next line for spans matching this one */
2460 /* if we have an exact span match set contig */
2461 if ((ptr2->start == ptr1->start) &&
2462 (ptr2->end == ptr1->end))
2465 /* remove the span - not needed */
2468 ptr3->next = ptr2->next;
2474 spans[j] = ptr2->next;
2480 /* gone past the span point no point looking */
2481 else if (ptr2->start < ptr1->start)
2489 /* if a contiguous span was found increase the rect h */
2492 rects[num_rects].height++;
2496 /* up the rect count */
2498 /* every 256 new rects increase the rect array */
2499 if ((num_rects % 256) == 0)
2500 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2504 /* set the rects as the shape mask */
2507 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2508 ShapeSet, YXSorted);
2513 /* free up all the spans we made */
2514 for (i = 0; i < baseh; i++)
2528 gdk_window_set_child_shapes (GdkWindow *window)
2530 GdkWindowPrivate *private;
2532 g_return_if_fail (window != NULL);
2534 #ifdef HAVE_SHAPE_EXT
2535 private = (GdkWindowPrivate*) window;
2536 if (private->destroyed)
2539 if (gdk_window_have_shape_ext ())
2540 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2545 gdk_window_merge_child_shapes (GdkWindow *window)
2547 GdkWindowPrivate *private;
2549 g_return_if_fail (window != NULL);
2551 #ifdef HAVE_SHAPE_EXT
2552 private = (GdkWindowPrivate*) window;
2553 if (private->destroyed)
2556 if (gdk_window_have_shape_ext ())
2557 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2561 /*************************************************************
2562 * gdk_window_is_visible:
2563 * Check if the given window is mapped.
2567 * is the window mapped
2568 *************************************************************/
2571 gdk_window_is_visible (GdkWindow *window)
2573 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2575 g_return_val_if_fail (window != NULL, FALSE);
2577 return private->mapped;
2580 /*************************************************************
2581 * gdk_window_is_viewable:
2582 * Check if the window and all ancestors of the window
2583 * are mapped. (This is not necessarily "viewable" in
2584 * the X sense, since we only check as far as we have
2585 * GDK window parents, not to the root window)
2589 * is the window viewable
2590 *************************************************************/
2593 gdk_window_is_viewable (GdkWindow *window)
2595 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2597 g_return_val_if_fail (window != NULL, FALSE);
2600 (private != &gdk_root_parent) &&
2601 (private->window_type != GDK_WINDOW_FOREIGN))
2603 if (!private->mapped)
2606 private = (GdkWindowPrivate *)private->parent;
2613 gdk_drawable_set_data (GdkDrawable *drawable,
2616 GDestroyNotify destroy_func)
2618 g_dataset_set_data_full (drawable, key, data, destroy_func);
2622 /* Support for windows that can be guffaw-scrolled
2623 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2627 gdk_window_gravity_works (void)
2629 enum { UNKNOWN, NO, YES };
2630 static gint gravity_works = UNKNOWN;
2632 if (gravity_works == UNKNOWN)
2639 /* This particular server apparently has a bug so that the test
2640 * works but the actual code crashes it
2642 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2643 (VendorRelease (gdk_display) == 3400))
2649 attr.window_type = GDK_WINDOW_TEMP;
2650 attr.wclass = GDK_INPUT_OUTPUT;
2655 attr.event_mask = 0;
2657 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2659 attr.window_type = GDK_WINDOW_CHILD;
2660 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2662 gdk_window_set_static_win_gravity (child, TRUE);
2664 gdk_window_resize (parent, 100, 110);
2665 gdk_window_move (parent, 0, -10);
2666 gdk_window_move_resize (parent, 0, 0, 100, 100);
2668 gdk_window_resize (parent, 100, 110);
2669 gdk_window_move (parent, 0, -10);
2670 gdk_window_move_resize (parent, 0, 0, 100, 100);
2672 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2674 gdk_window_destroy (parent);
2675 gdk_window_destroy (child);
2677 gravity_works = ((y == -20) ? YES : NO);
2680 return (gravity_works == YES);
2684 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2686 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2687 XSetWindowAttributes xattributes;
2689 g_return_if_fail (window != NULL);
2691 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2692 XChangeWindowAttributes (private->xdisplay,
2694 CWBitGravity, &xattributes);
2698 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2700 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2701 XSetWindowAttributes xattributes;
2703 g_return_if_fail (window != NULL);
2705 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2707 XChangeWindowAttributes (private->xdisplay,
2709 CWWinGravity, &xattributes);
2712 /*************************************************************
2713 * gdk_window_set_static_gravities:
2714 * Set the bit gravity of the given window to static,
2715 * and flag it so all children get static subwindow
2718 * window: window for which to set static gravity
2719 * use_static: Whether to turn static gravity on or off.
2721 * Does the XServer support static gravity?
2722 *************************************************************/
2725 gdk_window_set_static_gravities (GdkWindow *window,
2726 gboolean use_static)
2728 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2731 g_return_val_if_fail (window != NULL, FALSE);
2733 if (!use_static == !private->guffaw_gravity)
2736 if (use_static && !gdk_window_gravity_works ())
2739 private->guffaw_gravity = use_static;
2741 gdk_window_set_static_bit_gravity (window, use_static);
2743 tmp_list = private->children;
2746 gdk_window_set_static_win_gravity (window, use_static);
2748 tmp_list = tmp_list->next;