1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
34 #include "gdkwindow.h"
35 #include "gdkinputprivate.h"
36 #include "gdkprivate.h"
45 #include <X11/extensions/shape.h>
48 const int gdk_event_mask_table[20] =
52 PointerMotionHintMask,
57 ButtonPressMask | OwnerGrabButtonMask,
58 ButtonReleaseMask | OwnerGrabButtonMask,
69 SubstructureNotifyMask
71 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
73 /* Forward declarations */
74 static gboolean gdk_window_gravity_works (void);
75 static void gdk_window_set_static_win_gravity (GdkWindow *window,
77 static gboolean gdk_window_have_shape_ext (void);
79 /* internal function created for and used by gdk_window_xid_at_coords */
81 gdk_window_xid_at (Window base,
90 GdkWindowPrivate *private;
93 Window child = 0, parent_win = 0, root_win = 0;
95 unsigned int ww, wh, wb, wd, num;
98 window = (GdkWindow*) &gdk_root_parent;
99 private = (GdkWindowPrivate*) window;
100 disp = private->xdisplay;
101 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
108 (x < (int) (wx + ww)) &&
109 (y < (int) (wy + wh))))
112 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
117 for (i = num - 1; ; i--)
119 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
121 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
136 * The following fucntion by The Rasterman <raster@redhat.com>
137 * This function returns the X Window ID in which the x y location is in
138 * (x and y being relative to the root window), excluding any windows listed
139 * in the GList excludes (this is a list of X Window ID's - gpointer being
142 * This is primarily designed for internal gdk use - for DND for example
143 * when using a shaped icon window as the drag object - you exclude the
144 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
145 * You can get back an X Window ID as to what X Window ID is infact under
146 * those X,Y co-ordinates.
149 gdk_window_xid_at_coords (gint x,
155 GdkWindowPrivate *private;
158 Window root, child = 0, parent_win = 0, root_win = 0;
162 window = (GdkWindow*) &gdk_root_parent;
163 private = (GdkWindowPrivate*) window;
164 disp = private->xdisplay;
165 root = private->xwindow;
166 num = g_list_length (excludes);
169 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
171 XUngrabServer (disp);
179 XWindowAttributes xwa;
181 XGetWindowAttributes (disp, list [i], &xwa);
183 if (xwa.map_state != IsViewable)
186 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
189 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
194 if (!g_list_find (excludes, (gpointer *) child))
197 XUngrabServer (disp);
204 XUngrabServer (disp);
210 XUngrabServer (disp);
215 gdk_window_init (void)
217 XWindowAttributes xattributes;
220 unsigned int border_width;
224 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
225 &x, &y, &width, &height, &border_width, &depth);
226 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
228 gdk_root_parent.xwindow = gdk_root_window;
229 gdk_root_parent.xdisplay = gdk_display;
230 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
231 gdk_root_parent.window.user_data = NULL;
232 gdk_root_parent.width = width;
233 gdk_root_parent.height = height;
234 gdk_root_parent.children = NULL;
235 gdk_root_parent.colormap = NULL;
236 gdk_root_parent.ref_count = 1;
238 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
241 static GdkAtom wm_client_leader_atom = GDK_NONE;
244 gdk_window_new (GdkWindow *parent,
245 GdkWindowAttr *attributes,
246 gint attributes_mask)
249 GdkWindowPrivate *private;
250 GdkWindowPrivate *parent_private;
252 Display *parent_display;
255 XSetWindowAttributes xattributes;
256 long xattributes_mask;
257 XSizeHints size_hints;
259 XClassHint *class_hint;
265 g_return_val_if_fail (attributes != NULL, NULL);
268 parent = (GdkWindow*) &gdk_root_parent;
270 parent_private = (GdkWindowPrivate*) parent;
271 if (parent_private->destroyed)
274 xparent = parent_private->xwindow;
275 parent_display = parent_private->xdisplay;
277 private = g_new (GdkWindowPrivate, 1);
278 window = (GdkWindow*) private;
280 private->parent = parent;
282 private->xdisplay = parent_display;
283 private->destroyed = FALSE;
284 private->mapped = FALSE;
285 private->guffaw_gravity = FALSE;
286 private->resize_count = 0;
287 private->ref_count = 1;
288 xattributes_mask = 0;
290 if (attributes_mask & GDK_WA_X)
295 if (attributes_mask & GDK_WA_Y)
302 private->width = (attributes->width > 1) ? (attributes->width) : (1);
303 private->height = (attributes->height > 1) ? (attributes->height) : (1);
304 private->window_type = attributes->window_type;
305 private->extension_events = FALSE;
307 private->filters = NULL;
308 private->children = NULL;
310 window->user_data = NULL;
312 if (attributes_mask & GDK_WA_VISUAL)
313 visual = attributes->visual;
315 visual = gdk_visual_get_system ();
316 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
318 xattributes.event_mask = StructureNotifyMask;
319 for (i = 0; i < gdk_nevent_masks; i++)
321 if (attributes->event_mask & (1 << (i + 1)))
322 xattributes.event_mask |= gdk_event_mask_table[i];
325 if (xattributes.event_mask)
326 xattributes_mask |= CWEventMask;
328 if (attributes_mask & GDK_WA_NOREDIR)
330 xattributes.override_redirect =
331 (attributes->override_redirect == FALSE)?False:True;
332 xattributes_mask |= CWOverrideRedirect;
335 xattributes.override_redirect = False;
337 if (parent_private && parent_private->guffaw_gravity)
339 xattributes.win_gravity = StaticGravity;
340 xattributes_mask |= CWWinGravity;
343 if (attributes->wclass == GDK_INPUT_OUTPUT)
346 depth = visual->depth;
348 if (attributes_mask & GDK_WA_COLORMAP)
349 private->colormap = attributes->colormap;
352 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
353 private->colormap = gdk_colormap_get_system ();
355 private->colormap = gdk_colormap_new (visual, False);
358 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
359 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
360 xattributes_mask |= CWBorderPixel | CWBackPixel;
362 switch (private->window_type)
364 case GDK_WINDOW_TOPLEVEL:
365 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
366 xattributes_mask |= CWColormap;
368 xparent = gdk_root_window;
371 case GDK_WINDOW_CHILD:
372 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
373 xattributes_mask |= CWColormap;
376 case GDK_WINDOW_DIALOG:
377 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
378 xattributes_mask |= CWColormap;
380 xparent = gdk_root_window;
383 case GDK_WINDOW_TEMP:
384 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
385 xattributes_mask |= CWColormap;
387 xparent = gdk_root_window;
389 xattributes.save_under = True;
390 xattributes.override_redirect = True;
391 xattributes.cursor = None;
392 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
394 case GDK_WINDOW_ROOT:
395 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
397 case GDK_WINDOW_PIXMAP:
398 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
406 private->colormap = NULL;
409 private->xwindow = XCreateWindow (private->xdisplay, xparent,
410 x, y, private->width, private->height,
411 0, depth, class, xvisual,
412 xattributes_mask, &xattributes);
413 gdk_window_ref (window);
414 gdk_xid_table_insert (&private->xwindow, window);
416 if (private->colormap)
417 gdk_colormap_ref (private->colormap);
419 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
420 (attributes->cursor) :
424 parent_private->children = g_list_prepend (parent_private->children, window);
426 switch (private->window_type)
428 case GDK_WINDOW_DIALOG:
429 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
430 case GDK_WINDOW_TOPLEVEL:
431 case GDK_WINDOW_TEMP:
432 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
434 case GDK_WINDOW_CHILD:
435 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
436 (private->colormap != gdk_colormap_get_system ()) &&
437 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
439 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
440 gdk_window_add_colormap_windows (window);
449 size_hints.flags = PSize;
450 size_hints.width = private->width;
451 size_hints.height = private->height;
453 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
454 wm_hints.window_group = gdk_leader_window;
455 wm_hints.input = True;
456 wm_hints.initial_state = NormalState;
458 /* FIXME: Is there any point in doing this? Do any WM's pay
459 * attention to PSize, and even if they do, is this the
462 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
464 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
466 if (!wm_client_leader_atom)
467 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
469 XChangeProperty (private->xdisplay, private->xwindow,
470 wm_client_leader_atom,
471 XA_WINDOW, 32, PropModeReplace,
472 (guchar*) &gdk_leader_window, 1);
474 if (attributes_mask & GDK_WA_TITLE)
475 title = attributes->title;
477 title = g_get_prgname ();
479 XmbSetWMProperties (private->xdisplay, private->xwindow,
484 if (attributes_mask & GDK_WA_WMCLASS)
486 class_hint = XAllocClassHint ();
487 class_hint->res_name = attributes->wmclass_name;
488 class_hint->res_class = attributes->wmclass_class;
489 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
498 gdk_window_foreign_new (guint32 anid)
501 GdkWindowPrivate *private;
502 GdkWindowPrivate *parent_private;
503 XWindowAttributes attrs;
505 Window *children = NULL;
509 gdk_error_trap_push ();
510 result = XGetWindowAttributes (gdk_display, anid, &attrs);
511 if (gdk_error_trap_pop () || !result)
514 /* FIXME: This is pretty expensive. Maybe the caller should supply
516 gdk_error_trap_push ();
517 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
518 if (gdk_error_trap_pop () || !result)
521 private = g_new (GdkWindowPrivate, 1);
522 window = (GdkWindow*) private;
526 private->parent = gdk_xid_table_lookup (parent);
528 parent_private = (GdkWindowPrivate *)private->parent;
531 parent_private->children = g_list_prepend (parent_private->children, window);
533 private->xwindow = anid;
534 private->xdisplay = gdk_display;
535 private->x = attrs.x;
536 private->y = attrs.y;
537 private->width = attrs.width;
538 private->height = attrs.height;
539 private->resize_count = 0;
540 private->ref_count = 1;
541 private->window_type = GDK_WINDOW_FOREIGN;
542 private->destroyed = FALSE;
543 private->mapped = (attrs.map_state != IsUnmapped);
544 private->guffaw_gravity = FALSE;
545 private->extension_events = 0;
547 private->colormap = NULL;
549 private->filters = NULL;
550 private->children = NULL;
552 window->user_data = NULL;
554 gdk_window_ref (window);
555 gdk_xid_table_insert (&private->xwindow, window);
560 /* Call this function when you want a window and all its children to
561 * disappear. When xdestroy is true, a request to destroy the XWindow
562 * is sent out. When it is false, it is assumed that the XWindow has
563 * been or will be destroyed by destroying some ancestor of this
567 gdk_window_internal_destroy (GdkWindow *window,
569 gboolean our_destroy)
571 GdkWindowPrivate *private;
572 GdkWindowPrivate *temp_private;
573 GdkWindow *temp_window;
577 g_return_if_fail (window != NULL);
579 private = (GdkWindowPrivate*) window;
581 switch (private->window_type)
583 case GDK_WINDOW_TOPLEVEL:
584 case GDK_WINDOW_CHILD:
585 case GDK_WINDOW_DIALOG:
586 case GDK_WINDOW_TEMP:
587 case GDK_WINDOW_FOREIGN:
588 if (!private->destroyed)
592 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
593 if (parent_private->children)
594 parent_private->children = g_list_remove (parent_private->children, window);
597 if (private->window_type != GDK_WINDOW_FOREIGN)
599 children = tmp = private->children;
600 private->children = NULL;
604 temp_window = tmp->data;
607 temp_private = (GdkWindowPrivate*) temp_window;
609 gdk_window_internal_destroy (temp_window, FALSE,
613 g_list_free (children);
616 if (private->extension_events != 0)
617 gdk_input_window_destroy (window);
619 if (private->filters)
621 tmp = private->filters;
629 g_list_free (private->filters);
630 private->filters = NULL;
633 if (private->window_type == GDK_WINDOW_FOREIGN)
635 if (our_destroy && (private->parent != NULL))
637 /* It's somebody elses window, but in our heirarchy,
638 * so reparent it to the root window, and then send
639 * it a delete event, as if we were a WM
641 XClientMessageEvent xevent;
643 gdk_error_trap_push ();
644 gdk_window_hide (window);
645 gdk_window_reparent (window, NULL, 0, 0);
647 xevent.type = ClientMessage;
648 xevent.window = private->xwindow;
649 xevent.message_type = gdk_wm_protocols;
651 xevent.data.l[0] = gdk_wm_delete_window;
652 xevent.data.l[1] = CurrentTime;
654 XSendEvent (private->xdisplay, private->xwindow,
655 False, 0, (XEvent *)&xevent);
657 gdk_error_trap_pop ();
661 XDestroyWindow (private->xdisplay, private->xwindow);
663 if (private->colormap)
664 gdk_colormap_unref (private->colormap);
666 private->mapped = FALSE;
667 private->destroyed = TRUE;
671 case GDK_WINDOW_ROOT:
672 g_error ("attempted to destroy root window");
675 case GDK_WINDOW_PIXMAP:
676 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
681 /* Like internal_destroy, but also destroys the reference created by
685 gdk_window_destroy (GdkWindow *window)
687 gdk_window_internal_destroy (window, TRUE, TRUE);
688 gdk_window_unref (window);
691 /* This function is called when the XWindow is really gone. */
694 gdk_window_destroy_notify (GdkWindow *window)
696 GdkWindowPrivate *private;
698 g_return_if_fail (window != NULL);
700 private = (GdkWindowPrivate*) window;
702 if (!private->destroyed)
704 if (private->window_type != GDK_WINDOW_FOREIGN)
705 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
707 gdk_window_internal_destroy (window, FALSE, FALSE);
710 gdk_xid_table_remove (private->xwindow);
711 gdk_window_unref (window);
715 gdk_window_ref (GdkWindow *window)
717 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
718 g_return_val_if_fail (window != NULL, NULL);
720 private->ref_count += 1;
725 gdk_window_unref (GdkWindow *window)
727 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
728 g_return_if_fail (window != NULL);
729 g_return_if_fail (private->ref_count > 0);
731 private->ref_count -= 1;
732 if (private->ref_count == 0)
734 if (!private->destroyed)
736 if (private->window_type == GDK_WINDOW_FOREIGN)
737 gdk_xid_table_remove (private->xwindow);
739 g_warning ("losing last reference to undestroyed window\n");
741 g_dataset_destroy (window);
747 gdk_window_show (GdkWindow *window)
749 GdkWindowPrivate *private;
751 g_return_if_fail (window != NULL);
753 private = (GdkWindowPrivate*) window;
754 if (!private->destroyed)
756 private->mapped = TRUE;
757 XRaiseWindow (private->xdisplay, private->xwindow);
758 XMapWindow (private->xdisplay, private->xwindow);
763 gdk_window_hide (GdkWindow *window)
765 GdkWindowPrivate *private;
767 g_return_if_fail (window != NULL);
769 private = (GdkWindowPrivate*) window;
770 if (!private->destroyed)
772 private->mapped = FALSE;
773 XUnmapWindow (private->xdisplay, private->xwindow);
778 gdk_window_withdraw (GdkWindow *window)
780 GdkWindowPrivate *private;
782 g_return_if_fail (window != NULL);
784 private = (GdkWindowPrivate*) window;
785 if (!private->destroyed)
786 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
790 gdk_window_move (GdkWindow *window,
794 GdkWindowPrivate *private;
796 g_return_if_fail (window != NULL);
798 private = (GdkWindowPrivate*) window;
799 if (!private->destroyed)
801 XMoveWindow (private->xdisplay, private->xwindow, x, y);
803 if (private->window_type == GDK_WINDOW_CHILD)
812 gdk_window_resize (GdkWindow *window,
816 GdkWindowPrivate *private;
818 g_return_if_fail (window != NULL);
825 private = (GdkWindowPrivate*) window;
827 if (!private->destroyed &&
828 ((private->resize_count > 0) ||
829 (private->width != (guint16) width) ||
830 (private->height != (guint16) height)))
832 XResizeWindow (private->xdisplay, private->xwindow, width, height);
833 private->resize_count += 1;
835 if (private->window_type == GDK_WINDOW_CHILD)
837 private->width = width;
838 private->height = height;
844 gdk_window_move_resize (GdkWindow *window,
850 GdkWindowPrivate *private;
852 g_return_if_fail (window != NULL);
859 private = (GdkWindowPrivate*) window;
860 if (!private->destroyed)
862 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
864 if (private->guffaw_gravity)
866 GList *tmp_list = private->children;
869 GdkWindowPrivate *child_private = tmp_list->data;
871 child_private->x -= x - private->x;
872 child_private->y -= y - private->y;
874 tmp_list = tmp_list->next;
878 if (private->window_type == GDK_WINDOW_CHILD)
882 private->width = width;
883 private->height = height;
889 gdk_window_reparent (GdkWindow *window,
890 GdkWindow *new_parent,
894 GdkWindowPrivate *window_private;
895 GdkWindowPrivate *parent_private;
896 GdkWindowPrivate *old_parent_private;
898 g_return_if_fail (window != NULL);
901 new_parent = (GdkWindow*) &gdk_root_parent;
903 window_private = (GdkWindowPrivate*) window;
904 old_parent_private = (GdkWindowPrivate*)window_private->parent;
905 parent_private = (GdkWindowPrivate*) new_parent;
907 if (!window_private->destroyed && !parent_private->destroyed)
908 XReparentWindow (window_private->xdisplay,
909 window_private->xwindow,
910 parent_private->xwindow,
913 window_private->parent = new_parent;
915 if (old_parent_private)
916 old_parent_private->children = g_list_remove (old_parent_private->children, window);
918 if ((old_parent_private &&
919 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
920 (!old_parent_private && parent_private->guffaw_gravity))
921 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
923 parent_private->children = g_list_prepend (parent_private->children, window);
927 gdk_window_clear (GdkWindow *window)
929 GdkWindowPrivate *private;
931 g_return_if_fail (window != NULL);
933 private = (GdkWindowPrivate*) window;
935 if (!private->destroyed)
936 XClearWindow (private->xdisplay, private->xwindow);
940 gdk_window_clear_area (GdkWindow *window,
946 GdkWindowPrivate *private;
948 g_return_if_fail (window != NULL);
950 private = (GdkWindowPrivate*) window;
952 if (!private->destroyed)
953 XClearArea (private->xdisplay, private->xwindow,
954 x, y, width, height, False);
958 gdk_window_clear_area_e (GdkWindow *window,
964 GdkWindowPrivate *private;
966 g_return_if_fail (window != NULL);
968 private = (GdkWindowPrivate*) window;
970 if (!private->destroyed)
971 XClearArea (private->xdisplay, private->xwindow,
972 x, y, width, height, True);
976 gdk_window_copy_area (GdkWindow *window,
980 GdkWindow *source_window,
986 GdkWindowPrivate *src_private;
987 GdkWindowPrivate *dest_private;
988 GdkGCPrivate *gc_private;
990 g_return_if_fail (window != NULL);
991 g_return_if_fail (gc != NULL);
993 if (source_window == NULL)
994 source_window = window;
996 src_private = (GdkWindowPrivate*) source_window;
997 dest_private = (GdkWindowPrivate*) window;
998 gc_private = (GdkGCPrivate*) gc;
1000 if (!src_private->destroyed && !dest_private->destroyed)
1002 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
1011 gdk_window_raise (GdkWindow *window)
1013 GdkWindowPrivate *private;
1015 g_return_if_fail (window != NULL);
1017 private = (GdkWindowPrivate*) window;
1019 if (!private->destroyed)
1020 XRaiseWindow (private->xdisplay, private->xwindow);
1024 gdk_window_lower (GdkWindow *window)
1026 GdkWindowPrivate *private;
1028 g_return_if_fail (window != NULL);
1030 private = (GdkWindowPrivate*) window;
1032 if (!private->destroyed)
1033 XLowerWindow (private->xdisplay, private->xwindow);
1037 gdk_window_set_user_data (GdkWindow *window,
1040 g_return_if_fail (window != NULL);
1042 window->user_data = user_data;
1046 gdk_window_set_hints (GdkWindow *window,
1055 GdkWindowPrivate *private;
1056 XSizeHints size_hints;
1058 g_return_if_fail (window != NULL);
1060 private = (GdkWindowPrivate*) window;
1061 if (private->destroyed)
1064 size_hints.flags = 0;
1066 if (flags & GDK_HINT_POS)
1068 size_hints.flags |= PPosition;
1073 if (flags & GDK_HINT_MIN_SIZE)
1075 size_hints.flags |= PMinSize;
1076 size_hints.min_width = min_width;
1077 size_hints.min_height = min_height;
1080 if (flags & GDK_HINT_MAX_SIZE)
1082 size_hints.flags |= PMaxSize;
1083 size_hints.max_width = max_width;
1084 size_hints.max_height = max_height;
1087 /* FIXME: Would it be better to delete this property of
1088 * flags == 0? It would save space on the server
1090 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1094 gdk_window_set_geometry_hints (GdkWindow *window,
1095 GdkGeometry *geometry,
1096 GdkWindowHints geom_mask)
1098 GdkWindowPrivate *private;
1099 XSizeHints size_hints;
1101 g_return_if_fail (window != NULL);
1103 private = (GdkWindowPrivate*) window;
1104 if (private->destroyed)
1107 size_hints.flags = 0;
1109 if (geom_mask & GDK_HINT_POS)
1111 size_hints.flags |= PPosition;
1112 /* We need to initialize the following obsolete fields because KWM
1113 * apparently uses these fields if they are non-zero.
1120 if (geom_mask & GDK_HINT_MIN_SIZE)
1122 size_hints.flags |= PMinSize;
1123 size_hints.min_width = geometry->min_width;
1124 size_hints.min_height = geometry->min_height;
1127 if (geom_mask & GDK_HINT_MAX_SIZE)
1129 size_hints.flags |= PMaxSize;
1130 size_hints.max_width = MAX (geometry->max_width, 1);
1131 size_hints.max_height = MAX (geometry->max_height, 1);
1134 if (geom_mask & GDK_HINT_BASE_SIZE)
1136 size_hints.flags |= PBaseSize;
1137 size_hints.base_width = geometry->base_width;
1138 size_hints.base_height = geometry->base_height;
1141 if (geom_mask & GDK_HINT_RESIZE_INC)
1143 size_hints.flags |= PResizeInc;
1144 size_hints.width_inc = geometry->width_inc;
1145 size_hints.height_inc = geometry->height_inc;
1148 if (geom_mask & GDK_HINT_ASPECT)
1150 size_hints.flags |= PAspect;
1151 if (geometry->min_aspect <= 1)
1153 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1154 size_hints.min_aspect.y = 65536;
1158 size_hints.min_aspect.x = 65536;
1159 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1161 if (geometry->max_aspect <= 1)
1163 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1164 size_hints.max_aspect.y = 65536;
1168 size_hints.max_aspect.x = 65536;
1169 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1173 /* FIXME: Would it be better to delete this property of
1174 * geom_mask == 0? It would save space on the server
1176 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1180 gdk_window_set_title (GdkWindow *window,
1183 GdkWindowPrivate *private;
1185 g_return_if_fail (window != NULL);
1187 private = (GdkWindowPrivate*) window;
1188 if (!private->destroyed)
1189 XmbSetWMProperties (private->xdisplay, private->xwindow,
1190 title, title, NULL, 0, NULL, NULL, NULL);
1194 gdk_window_set_role (GdkWindow *window,
1197 GdkWindowPrivate *private;
1199 g_return_if_fail (window != NULL);
1201 private = (GdkWindowPrivate*) window;
1204 XChangeProperty (private->xdisplay, private->xwindow,
1205 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1206 8, PropModeReplace, role, strlen (role));
1208 XDeleteProperty (private->xdisplay, private->xwindow,
1209 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1213 gdk_window_set_transient_for (GdkWindow *window,
1216 GdkWindowPrivate *private;
1217 GdkWindowPrivate *parent_private;
1219 g_return_if_fail (window != NULL);
1221 private = (GdkWindowPrivate*) window;
1222 parent_private = (GdkWindowPrivate*) parent;
1224 if (!private->destroyed && !parent_private->destroyed)
1225 XSetTransientForHint (private->xdisplay,
1226 private->xwindow, parent_private->xwindow);
1230 gdk_window_set_background (GdkWindow *window,
1233 GdkWindowPrivate *private;
1235 g_return_if_fail (window != NULL);
1237 private = (GdkWindowPrivate*) window;
1238 if (!private->destroyed)
1239 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1243 gdk_window_set_back_pixmap (GdkWindow *window,
1245 gint parent_relative)
1247 GdkWindowPrivate *window_private;
1248 GdkPixmapPrivate *pixmap_private;
1251 g_return_if_fail (window != NULL);
1253 window_private = (GdkWindowPrivate*) window;
1254 pixmap_private = (GdkPixmapPrivate*) pixmap;
1257 xpixmap = pixmap_private->xwindow;
1261 if (parent_relative)
1262 xpixmap = ParentRelative;
1264 if (!window_private->destroyed)
1265 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1269 gdk_window_set_cursor (GdkWindow *window,
1272 GdkWindowPrivate *window_private;
1273 GdkCursorPrivate *cursor_private;
1276 g_return_if_fail (window != NULL);
1278 window_private = (GdkWindowPrivate*) window;
1279 cursor_private = (GdkCursorPrivate*) cursor;
1284 xcursor = cursor_private->xcursor;
1286 if (!window_private->destroyed)
1287 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1291 gdk_window_set_colormap (GdkWindow *window,
1292 GdkColormap *colormap)
1294 GdkWindowPrivate *window_private;
1295 GdkColormapPrivate *colormap_private;
1297 g_return_if_fail (window != NULL);
1298 g_return_if_fail (colormap != NULL);
1300 window_private = (GdkWindowPrivate*) window;
1301 colormap_private = (GdkColormapPrivate*) colormap;
1303 if (!window_private->destroyed)
1305 XSetWindowColormap (window_private->xdisplay,
1306 window_private->xwindow,
1307 colormap_private->xcolormap);
1309 if (window_private->colormap)
1310 gdk_colormap_unref (window_private->colormap);
1311 window_private->colormap = colormap;
1312 gdk_colormap_ref (window_private->colormap);
1314 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1315 gdk_window_add_colormap_windows (window);
1320 gdk_window_get_user_data (GdkWindow *window,
1323 g_return_if_fail (window != NULL);
1325 *data = window->user_data;
1329 gdk_window_get_geometry (GdkWindow *window,
1336 GdkWindowPrivate *window_private;
1342 guint tborder_width;
1346 window = (GdkWindow*) &gdk_root_parent;
1348 window_private = (GdkWindowPrivate*) window;
1350 if (!window_private->destroyed)
1352 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1353 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1369 gdk_window_get_position (GdkWindow *window,
1373 GdkWindowPrivate *window_private;
1375 g_return_if_fail (window != NULL);
1377 window_private = (GdkWindowPrivate*) window;
1380 *x = window_private->x;
1382 *y = window_private->y;
1386 gdk_window_get_size (GdkWindow *window,
1390 GdkWindowPrivate *window_private;
1392 g_return_if_fail (window != NULL);
1394 window_private = (GdkWindowPrivate*) window;
1397 *width = window_private->width;
1399 *height = window_private->height;
1403 gdk_window_get_visual (GdkWindow *window)
1405 GdkWindowPrivate *window_private;
1406 XWindowAttributes window_attributes;
1408 g_return_val_if_fail (window != NULL, NULL);
1410 window_private = (GdkWindowPrivate*) window;
1411 /* Huh? ->parent is never set for a pixmap. We should just return
1414 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1415 window_private = (GdkWindowPrivate*) window_private->parent;
1417 if (window_private && !window_private->destroyed)
1419 if (window_private->colormap == NULL)
1421 XGetWindowAttributes (window_private->xdisplay,
1422 window_private->xwindow,
1423 &window_attributes);
1424 return gdk_visual_lookup (window_attributes.visual);
1427 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1434 gdk_window_get_colormap (GdkWindow *window)
1436 GdkWindowPrivate *window_private;
1437 XWindowAttributes window_attributes;
1439 g_return_val_if_fail (window != NULL, NULL);
1440 window_private = (GdkWindowPrivate*) window;
1442 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1443 if (!window_private->destroyed)
1445 if (window_private->colormap == NULL)
1447 XGetWindowAttributes (window_private->xdisplay,
1448 window_private->xwindow,
1449 &window_attributes);
1450 return gdk_colormap_lookup (window_attributes.colormap);
1453 return window_private->colormap;
1460 gdk_window_get_type (GdkWindow *window)
1462 GdkWindowPrivate *window_private;
1464 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1466 window_private = (GdkWindowPrivate*) window;
1467 return window_private->window_type;
1471 gdk_window_get_origin (GdkWindow *window,
1475 GdkWindowPrivate *private;
1481 g_return_val_if_fail (window != NULL, 0);
1483 private = (GdkWindowPrivate*) window;
1485 if (!private->destroyed)
1487 return_val = XTranslateCoordinates (private->xdisplay,
1506 gdk_window_get_deskrelative_origin (GdkWindow *window,
1510 GdkWindowPrivate *private;
1511 gboolean return_val = FALSE;
1512 gint num_children, format_return;
1513 Window win, *child, parent, root;
1517 static Atom atom = 0;
1518 gulong number_return, bytes_after_return;
1519 guchar *data_return;
1521 g_return_val_if_fail (window != NULL, 0);
1523 private = (GdkWindowPrivate*) window;
1525 if (!private->destroyed)
1528 atom = XInternAtom (private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1529 win = private->xwindow;
1531 while (XQueryTree (private->xdisplay, win, &root, &parent,
1532 &child, (unsigned int *)&num_children))
1534 if ((child) && (num_children > 0))
1546 XGetWindowProperty (private->xdisplay, win, atom, 0, 0,
1547 False, XA_CARDINAL, &type_return, &format_return,
1548 &number_return, &bytes_after_return, &data_return);
1549 if (type_return == XA_CARDINAL)
1551 XFree (data_return);
1556 return_val = XTranslateCoordinates (private->xdisplay,
1572 gdk_window_get_root_origin (GdkWindow *window,
1576 GdkWindowPrivate *private;
1581 unsigned int nchildren;
1583 g_return_if_fail (window != NULL);
1585 private = (GdkWindowPrivate*) window;
1590 if (private->destroyed)
1593 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1594 private = (GdkWindowPrivate*) private->parent;
1595 if (private->destroyed)
1598 xparent = private->xwindow;
1602 if (!XQueryTree (private->xdisplay, xwindow,
1604 &children, &nchildren))
1610 while (xparent != root);
1612 if (xparent == root)
1614 unsigned int ww, wh, wb, wd;
1617 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1628 gdk_window_get_pointer (GdkWindow *window,
1631 GdkModifierType *mask)
1633 GdkWindowPrivate *private;
1634 GdkWindow *return_val;
1640 unsigned int xmask = 0;
1643 window = (GdkWindow*) &gdk_root_parent;
1645 private = (GdkWindowPrivate*) window;
1648 if (!private->destroyed &&
1649 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1650 &rootx, &rooty, &winx, &winy, &xmask))
1653 return_val = gdk_window_lookup (child);
1667 gdk_window_at_pointer (gint *win_x,
1670 GdkWindowPrivate *private;
1674 Window xwindow_last = 0;
1675 int rootx = -1, rooty = -1;
1679 private = &gdk_root_parent;
1681 xwindow = private->xwindow;
1683 XGrabServer (private->xdisplay);
1686 xwindow_last = xwindow;
1687 XQueryPointer (private->xdisplay,
1694 XUngrabServer (private->xdisplay);
1696 window = gdk_window_lookup (xwindow_last);
1699 *win_x = window ? winx : -1;
1701 *win_y = window ? winy : -1;
1707 gdk_window_get_parent (GdkWindow *window)
1709 g_return_val_if_fail (window != NULL, NULL);
1711 return ((GdkWindowPrivate*) window)->parent;
1715 gdk_window_get_toplevel (GdkWindow *window)
1717 GdkWindowPrivate *private;
1719 g_return_val_if_fail (window != NULL, NULL);
1721 private = (GdkWindowPrivate*) window;
1723 while (private->window_type == GDK_WINDOW_CHILD)
1725 window = ((GdkWindowPrivate*) window)->parent;
1726 private = (GdkWindowPrivate*) window;
1733 gdk_window_get_children (GdkWindow *window)
1735 GdkWindowPrivate *private;
1741 unsigned int nchildren;
1744 g_return_val_if_fail (window != NULL, NULL);
1746 private = (GdkWindowPrivate*) window;
1747 if (private->destroyed)
1750 XQueryTree (private->xdisplay, private->xwindow,
1751 &root, &parent, &xchildren, &nchildren);
1757 for (i = 0; i < nchildren; i++)
1759 child = gdk_window_lookup (xchildren[i]);
1761 children = g_list_prepend (children, child);
1772 gdk_window_get_events (GdkWindow *window)
1774 GdkWindowPrivate *private;
1775 XWindowAttributes attrs;
1776 GdkEventMask event_mask;
1779 g_return_val_if_fail (window != NULL, 0);
1781 private = (GdkWindowPrivate*) window;
1782 if (private->destroyed)
1785 XGetWindowAttributes (gdk_display, private->xwindow,
1789 for (i = 0; i < gdk_nevent_masks; i++)
1791 if (attrs.your_event_mask & gdk_event_mask_table[i])
1792 event_mask |= 1 << (i + 1);
1799 gdk_window_set_events (GdkWindow *window,
1800 GdkEventMask event_mask)
1802 GdkWindowPrivate *private;
1806 g_return_if_fail (window != NULL);
1808 private = (GdkWindowPrivate*) window;
1809 if (private->destroyed)
1812 xevent_mask = StructureNotifyMask;
1813 for (i = 0; i < gdk_nevent_masks; i++)
1815 if (event_mask & (1 << (i + 1)))
1816 xevent_mask |= gdk_event_mask_table[i];
1819 XSelectInput (gdk_display, private->xwindow,
1824 gdk_window_add_colormap_windows (GdkWindow *window)
1826 GdkWindow *toplevel;
1827 GdkWindowPrivate *toplevel_private;
1828 GdkWindowPrivate *window_private;
1829 Window *old_windows;
1830 Window *new_windows;
1833 g_return_if_fail (window != NULL);
1835 toplevel = gdk_window_get_toplevel (window);
1836 toplevel_private = (GdkWindowPrivate*) toplevel;
1837 window_private = (GdkWindowPrivate*) window;
1838 if (window_private->destroyed)
1842 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1843 toplevel_private->xwindow,
1844 &old_windows, &count))
1849 for (i = 0; i < count; i++)
1850 if (old_windows[i] == window_private->xwindow)
1852 XFree (old_windows);
1856 new_windows = g_new (Window, count + 1);
1858 for (i = 0; i < count; i++)
1859 new_windows[i] = old_windows[i];
1860 new_windows[count] = window_private->xwindow;
1862 XSetWMColormapWindows (toplevel_private->xdisplay,
1863 toplevel_private->xwindow,
1864 new_windows, count + 1);
1866 g_free (new_windows);
1868 XFree (old_windows);
1872 gdk_window_have_shape_ext (void)
1874 enum { UNKNOWN, NO, YES };
1875 static gint have_shape = UNKNOWN;
1877 if (have_shape == UNKNOWN)
1880 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1886 return (have_shape == YES);
1890 * This needs the X11 shape extension.
1891 * If not available, shaped windows will look
1892 * ugly, but programs still work. Stefan Wille
1895 gdk_window_shape_combine_mask (GdkWindow *window,
1899 GdkWindowPrivate *window_private;
1902 g_return_if_fail (window != NULL);
1904 #ifdef HAVE_SHAPE_EXT
1905 window_private = (GdkWindowPrivate*) window;
1906 if (window_private->destroyed)
1909 if (gdk_window_have_shape_ext ())
1913 GdkWindowPrivate *pixmap_private;
1915 pixmap_private = (GdkWindowPrivate*) mask;
1916 pixmap = (Pixmap) pixmap_private->xwindow;
1925 XShapeCombineMask (window_private->xdisplay,
1926 window_private->xwindow,
1932 #endif /* HAVE_SHAPE_EXT */
1936 gdk_window_add_filter (GdkWindow *window,
1937 GdkFilterFunc function,
1940 GdkWindowPrivate *private;
1942 GdkEventFilter *filter;
1944 private = (GdkWindowPrivate*) window;
1945 if (private && private->destroyed)
1949 tmp_list = private->filters;
1951 tmp_list = gdk_default_filters;
1955 filter = (GdkEventFilter *)tmp_list->data;
1956 if ((filter->function == function) && (filter->data == data))
1958 tmp_list = tmp_list->next;
1961 filter = g_new (GdkEventFilter, 1);
1962 filter->function = function;
1963 filter->data = data;
1966 private->filters = g_list_append (private->filters, filter);
1968 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1972 gdk_window_remove_filter (GdkWindow *window,
1973 GdkFilterFunc function,
1976 GdkWindowPrivate *private;
1977 GList *tmp_list, *node;
1978 GdkEventFilter *filter;
1980 private = (GdkWindowPrivate*) window;
1983 tmp_list = private->filters;
1985 tmp_list = gdk_default_filters;
1989 filter = (GdkEventFilter *)tmp_list->data;
1991 tmp_list = tmp_list->next;
1993 if ((filter->function == function) && (filter->data == data))
1996 private->filters = g_list_remove_link (private->filters, node);
1998 gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
1999 g_list_free_1 (node);
2008 gdk_window_set_override_redirect (GdkWindow *window,
2009 gboolean override_redirect)
2011 GdkWindowPrivate *private;
2012 XSetWindowAttributes attr;
2014 g_return_if_fail (window != NULL);
2015 private = (GdkWindowPrivate*) window;
2016 if (private->destroyed)
2019 attr.override_redirect = (override_redirect == FALSE)?False:True;
2020 XChangeWindowAttributes (gdk_display,
2021 ((GdkWindowPrivate *)window)->xwindow,
2027 gdk_window_set_icon (GdkWindow *window,
2028 GdkWindow *icon_window,
2033 GdkWindowPrivate *window_private;
2034 GdkWindowPrivate *private;
2036 g_return_if_fail (window != NULL);
2037 window_private = (GdkWindowPrivate*) window;
2038 if (window_private->destroyed)
2041 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2043 wm_hints = XAllocWMHints ();
2045 if (icon_window != NULL)
2047 private = (GdkWindowPrivate *)icon_window;
2048 wm_hints->flags |= IconWindowHint;
2049 wm_hints->icon_window = private->xwindow;
2054 private = (GdkWindowPrivate *)pixmap;
2055 wm_hints->flags |= IconPixmapHint;
2056 wm_hints->icon_pixmap = private->xwindow;
2061 private = (GdkWindowPrivate *)mask;
2062 wm_hints->flags |= IconMaskHint;
2063 wm_hints->icon_mask = private->xwindow;
2066 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2071 gdk_window_set_icon_name (GdkWindow *window,
2074 GdkWindowPrivate *window_private;
2075 XTextProperty property;
2078 g_return_if_fail (window != NULL);
2079 window_private = (GdkWindowPrivate*) window;
2080 if (window_private->destroyed)
2082 res = XmbTextListToTextProperty (window_private->xdisplay,
2083 &name, 1, XStdICCTextStyle,
2087 g_warning ("Error converting icon name to text property: %d\n", res);
2091 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2095 XFree (property.value);
2099 gdk_window_set_group (GdkWindow *window,
2103 GdkWindowPrivate *window_private;
2104 GdkWindowPrivate *private;
2106 g_return_if_fail (window != NULL);
2107 g_return_if_fail (leader != NULL);
2108 window_private = (GdkWindowPrivate*) window;
2109 if (window_private->destroyed)
2112 private = (GdkWindowPrivate *)leader;
2114 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2116 wm_hints = XAllocWMHints ();
2118 wm_hints->flags |= WindowGroupHint;
2119 wm_hints->window_group = private->xwindow;
2121 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2126 gdk_window_set_mwm_hints (GdkWindow *window,
2127 MotifWmHints *new_hints)
2129 static Atom hints_atom = None;
2130 MotifWmHints *hints;
2136 GdkWindowPrivate *window_private;
2138 g_return_if_fail (window != NULL);
2139 window_private = (GdkWindowPrivate*) window;
2140 if (window_private->destroyed)
2144 hints_atom = XInternAtom (window_private->xdisplay,
2145 _XA_MOTIF_WM_HINTS, FALSE);
2147 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2148 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2149 False, AnyPropertyType, &type, &format, &nitems,
2150 &bytes_after, (guchar **)&hints);
2156 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2158 hints->flags |= MWM_HINTS_FUNCTIONS;
2159 hints->functions = new_hints->functions;
2161 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2163 hints->flags |= MWM_HINTS_DECORATIONS;
2164 hints->decorations = new_hints->decorations;
2168 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2169 hints_atom, hints_atom, 32, PropModeReplace,
2170 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
2172 if (hints != new_hints)
2177 gdk_window_set_decorations (GdkWindow *window,
2178 GdkWMDecoration decorations)
2182 hints.flags = MWM_HINTS_DECORATIONS;
2183 hints.decorations = decorations;
2185 gdk_window_set_mwm_hints (window, &hints);
2189 gdk_window_set_functions (GdkWindow *window,
2190 GdkWMFunction functions)
2194 hints.flags = MWM_HINTS_FUNCTIONS;
2195 hints.functions = functions;
2197 gdk_window_set_mwm_hints (window, &hints);
2201 gdk_window_get_toplevels (void)
2203 GList *new_list = NULL;
2206 tmp_list = gdk_root_parent.children;
2209 new_list = g_list_prepend (new_list, tmp_list->data);
2210 tmp_list = tmp_list->next;
2217 * propagate the shapes from all child windows of a GDK window to the parent
2218 * window. Shamelessly ripped from Enlightenment's code
2227 struct _gdk_span *next;
2231 gdk_add_to_span (struct _gdk_span **s,
2235 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2242 /* scan the spans for this line */
2245 /* -- -> new span */
2246 /* == -> existing span */
2247 /* ## -> spans intersect */
2248 /* if we are in the middle of spanning the span into the line */
2251 /* case: ---- ==== */
2252 if (xx < ptr1->start - 1)
2254 /* ends before next span - extend to here */
2258 /* case: ----##=== */
2259 else if (xx <= ptr1->end)
2261 /* crosses into next span - delete next span and append */
2262 ss->end = ptr1->end;
2263 ss->next = ptr1->next;
2267 /* case: ---###--- */
2270 /* overlaps next span - delete and keep checking */
2271 ss->next = ptr1->next;
2276 /* otherwise havent started spanning it in yet */
2279 /* case: ---- ==== */
2280 if (xx < ptr1->start - 1)
2282 /* insert span here in list */
2283 noo = g_malloc (sizeof (struct _gdk_span));
2297 /* case: ----##=== */
2298 else if ((x < ptr1->start) && (xx <= ptr1->end))
2300 /* expand this span to the left point of the new one */
2304 /* case: ===###=== */
2305 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2307 /* throw the span away */
2310 /* case: ---###--- */
2311 else if ((x < ptr1->start) && (xx > ptr1->end))
2318 /* case: ===##---- */
2319 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2325 /* case: ==== ---- */
2326 /* case handled by next loop iteration - first case */
2331 /* it started in the middle but spans beyond your current list */
2337 /* it does not start inside a span or in the middle, so add it to the end */
2338 noo = g_malloc (sizeof (struct _gdk_span));
2346 noo->next = ptr2->next;
2359 gdk_add_rectangles (Display *disp,
2361 struct _gdk_span **spans,
2368 gint x1, y1, x2, y2;
2372 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2375 /* go through all clip rects in this window's shape */
2376 for (k = 0; k < rn; k++)
2378 /* for each clip rect, add it to each line's spans */
2380 x2 = x + rl[k].x + (rl[k].width - 1);
2382 y2 = y + rl[k].y + (rl[k].height - 1);
2391 for (a = y1; a <= y2; a++)
2394 gdk_add_to_span (&spans[a], x1, x2);
2402 gdk_propagate_shapes (Display *disp,
2406 Window rt, par, *list = NULL;
2407 gint i, j, num = 0, num_rects = 0;
2411 XRectangle *rects = NULL;
2412 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2413 XWindowAttributes xatt;
2415 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2420 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2422 for (i = 0; i < h; i++)
2424 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2427 /* go through all child windows and create/insert spans */
2428 for (i = 0; i < num; i++)
2430 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2431 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2432 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2435 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2437 /* go through the spans list and build a list of rects */
2438 rects = g_malloc (sizeof (XRectangle) * 256);
2440 for (i = 0; i < baseh; i++)
2443 /* go through the line for all spans */
2446 rects[num_rects].x = ptr1->start;
2447 rects[num_rects].y = i;
2448 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2449 rects[num_rects].height = 1;
2451 /* if there are more lines */
2453 /* while contigous rects (same start/end coords) exist */
2454 while ((contig) && (j < baseh))
2456 /* search next line for spans matching this one */
2462 /* if we have an exact span match set contig */
2463 if ((ptr2->start == ptr1->start) &&
2464 (ptr2->end == ptr1->end))
2467 /* remove the span - not needed */
2470 ptr3->next = ptr2->next;
2476 spans[j] = ptr2->next;
2482 /* gone past the span point no point looking */
2483 else if (ptr2->start < ptr1->start)
2491 /* if a contiguous span was found increase the rect h */
2494 rects[num_rects].height++;
2498 /* up the rect count */
2500 /* every 256 new rects increase the rect array */
2501 if ((num_rects % 256) == 0)
2502 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2506 /* set the rects as the shape mask */
2509 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2510 ShapeSet, YXSorted);
2515 /* free up all the spans we made */
2516 for (i = 0; i < baseh; i++)
2530 gdk_window_set_child_shapes (GdkWindow *window)
2532 GdkWindowPrivate *private;
2534 g_return_if_fail (window != NULL);
2536 #ifdef HAVE_SHAPE_EXT
2537 private = (GdkWindowPrivate*) window;
2538 if (private->destroyed)
2541 if (gdk_window_have_shape_ext ())
2542 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2547 gdk_window_merge_child_shapes (GdkWindow *window)
2549 GdkWindowPrivate *private;
2551 g_return_if_fail (window != NULL);
2553 #ifdef HAVE_SHAPE_EXT
2554 private = (GdkWindowPrivate*) window;
2555 if (private->destroyed)
2558 if (gdk_window_have_shape_ext ())
2559 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2563 /*************************************************************
2564 * gdk_window_is_visible:
2565 * Check if the given window is mapped.
2569 * is the window mapped
2570 *************************************************************/
2573 gdk_window_is_visible (GdkWindow *window)
2575 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2577 g_return_val_if_fail (window != NULL, FALSE);
2579 return private->mapped;
2582 /*************************************************************
2583 * gdk_window_is_viewable:
2584 * Check if the window and all ancestors of the window
2585 * are mapped. (This is not necessarily "viewable" in
2586 * the X sense, since we only check as far as we have
2587 * GDK window parents, not to the root window)
2591 * is the window viewable
2592 *************************************************************/
2595 gdk_window_is_viewable (GdkWindow *window)
2597 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2599 g_return_val_if_fail (window != NULL, FALSE);
2602 (private != &gdk_root_parent) &&
2603 (private->window_type != GDK_WINDOW_FOREIGN))
2605 if (!private->mapped)
2608 private = (GdkWindowPrivate *)private->parent;
2615 gdk_drawable_set_data (GdkDrawable *drawable,
2618 GDestroyNotify destroy_func)
2620 g_dataset_set_data_full (drawable, key, data, destroy_func);
2624 /* Support for windows that can be guffaw-scrolled
2625 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2629 gdk_window_gravity_works (void)
2631 enum { UNKNOWN, NO, YES };
2632 static gint gravity_works = UNKNOWN;
2634 if (gravity_works == UNKNOWN)
2641 /* This particular server apparently has a bug so that the test
2642 * works but the actual code crashes it
2644 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2645 (VendorRelease (gdk_display) == 3400))
2651 attr.window_type = GDK_WINDOW_TEMP;
2652 attr.wclass = GDK_INPUT_OUTPUT;
2657 attr.event_mask = 0;
2659 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2661 attr.window_type = GDK_WINDOW_CHILD;
2662 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2664 gdk_window_set_static_win_gravity (child, TRUE);
2666 gdk_window_resize (parent, 100, 110);
2667 gdk_window_move (parent, 0, -10);
2668 gdk_window_move_resize (parent, 0, 0, 100, 100);
2670 gdk_window_resize (parent, 100, 110);
2671 gdk_window_move (parent, 0, -10);
2672 gdk_window_move_resize (parent, 0, 0, 100, 100);
2674 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2676 gdk_window_destroy (parent);
2677 gdk_window_destroy (child);
2679 gravity_works = ((y == -20) ? YES : NO);
2682 return (gravity_works == YES);
2686 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2688 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2689 XSetWindowAttributes xattributes;
2691 g_return_if_fail (window != NULL);
2693 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2694 XChangeWindowAttributes (private->xdisplay,
2696 CWBitGravity, &xattributes);
2700 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2702 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2703 XSetWindowAttributes xattributes;
2705 g_return_if_fail (window != NULL);
2707 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2709 XChangeWindowAttributes (private->xdisplay,
2711 CWWinGravity, &xattributes);
2714 /*************************************************************
2715 * gdk_window_set_static_gravities:
2716 * Set the bit gravity of the given window to static,
2717 * and flag it so all children get static subwindow
2720 * window: window for which to set static gravity
2721 * use_static: Whether to turn static gravity on or off.
2723 * Does the XServer support static gravity?
2724 *************************************************************/
2727 gdk_window_set_static_gravities (GdkWindow *window,
2728 gboolean use_static)
2730 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2733 g_return_val_if_fail (window != NULL, FALSE);
2735 if (!use_static == !private->guffaw_gravity)
2738 if (use_static && !gdk_window_gravity_works ())
2741 private->guffaw_gravity = use_static;
2743 gdk_window_set_static_bit_gravity (window, use_static);
2745 tmp_list = private->children;
2748 gdk_window_set_static_win_gravity (window, use_static);
2750 tmp_list = tmp_list->next;