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"
51 #include <X11/extensions/shape.h>
54 const int gdk_event_mask_table[20] =
58 PointerMotionHintMask,
63 ButtonPressMask | OwnerGrabButtonMask,
64 ButtonReleaseMask | OwnerGrabButtonMask,
75 SubstructureNotifyMask
77 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
79 /* Forward declarations */
80 static gboolean gdk_window_gravity_works (void);
81 static void gdk_window_set_static_win_gravity (GdkWindow *window,
83 static gboolean gdk_window_have_shape_ext (void);
85 /* internal function created for and used by gdk_window_xid_at_coords */
87 gdk_window_xid_at (Window base,
96 GdkWindowPrivate *private;
99 Window child = 0, parent_win = 0, root_win = 0;
101 unsigned int ww, wh, wb, wd, num;
104 window = (GdkWindow*) &gdk_root_parent;
105 private = (GdkWindowPrivate*) window;
106 disp = private->xdisplay;
107 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
114 (x < (int) (wx + ww)) &&
115 (y < (int) (wy + wh))))
118 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
123 for (i = num - 1; ; i--)
125 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
127 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
142 * The following fucntion by The Rasterman <raster@redhat.com>
143 * This function returns the X Window ID in which the x y location is in
144 * (x and y being relative to the root window), excluding any windows listed
145 * in the GList excludes (this is a list of X Window ID's - gpointer being
148 * This is primarily designed for internal gdk use - for DND for example
149 * when using a shaped icon window as the drag object - you exclude the
150 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
151 * You can get back an X Window ID as to what X Window ID is infact under
152 * those X,Y co-ordinates.
155 gdk_window_xid_at_coords (gint x,
161 GdkWindowPrivate *private;
164 Window root, child = 0, parent_win = 0, root_win = 0;
168 window = (GdkWindow*) &gdk_root_parent;
169 private = (GdkWindowPrivate*) window;
170 disp = private->xdisplay;
171 root = private->xwindow;
172 num = g_list_length (excludes);
175 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
177 XUngrabServer (disp);
185 XWindowAttributes xwa;
187 XGetWindowAttributes (disp, list [i], &xwa);
189 if (xwa.map_state != IsViewable)
192 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
195 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
200 if (!g_list_find (excludes, (gpointer *) child))
203 XUngrabServer (disp);
210 XUngrabServer (disp);
216 XUngrabServer (disp);
221 gdk_window_init (void)
223 XWindowAttributes xattributes;
226 unsigned int border_width;
230 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
231 &x, &y, &width, &height, &border_width, &depth);
232 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
234 gdk_root_parent.xwindow = gdk_root_window;
235 gdk_root_parent.xdisplay = gdk_display;
236 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
237 gdk_root_parent.window.user_data = NULL;
238 gdk_root_parent.width = width;
239 gdk_root_parent.height = height;
240 gdk_root_parent.children = NULL;
241 gdk_root_parent.colormap = NULL;
242 gdk_root_parent.ref_count = 1;
244 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
247 static GdkAtom wm_client_leader_atom = GDK_NONE;
250 gdk_window_new (GdkWindow *parent,
251 GdkWindowAttr *attributes,
252 gint attributes_mask)
255 GdkWindowPrivate *private;
256 GdkWindowPrivate *parent_private;
258 Display *parent_display;
261 XSetWindowAttributes xattributes;
262 long xattributes_mask;
263 XSizeHints size_hints;
265 XClassHint *class_hint;
271 g_return_val_if_fail (attributes != NULL, NULL);
274 parent = (GdkWindow*) &gdk_root_parent;
276 parent_private = (GdkWindowPrivate*) parent;
277 if (parent_private->destroyed)
280 xparent = parent_private->xwindow;
281 parent_display = parent_private->xdisplay;
283 private = g_new (GdkWindowPrivate, 1);
284 window = (GdkWindow*) private;
286 private->parent = parent;
288 private->xdisplay = parent_display;
289 private->destroyed = FALSE;
290 private->mapped = FALSE;
291 private->guffaw_gravity = FALSE;
292 private->resize_count = 0;
293 private->ref_count = 1;
294 xattributes_mask = 0;
296 if (attributes_mask & GDK_WA_X)
301 if (attributes_mask & GDK_WA_Y)
308 private->width = (attributes->width > 1) ? (attributes->width) : (1);
309 private->height = (attributes->height > 1) ? (attributes->height) : (1);
310 private->window_type = attributes->window_type;
311 private->extension_events = FALSE;
313 private->filters = NULL;
314 private->children = NULL;
316 window->user_data = NULL;
318 if (attributes_mask & GDK_WA_VISUAL)
319 visual = attributes->visual;
321 visual = gdk_visual_get_system ();
322 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
324 xattributes.event_mask = StructureNotifyMask;
325 for (i = 0; i < gdk_nevent_masks; i++)
327 if (attributes->event_mask & (1 << (i + 1)))
328 xattributes.event_mask |= gdk_event_mask_table[i];
331 if (xattributes.event_mask)
332 xattributes_mask |= CWEventMask;
334 if (attributes_mask & GDK_WA_NOREDIR)
336 xattributes.override_redirect =
337 (attributes->override_redirect == FALSE)?False:True;
338 xattributes_mask |= CWOverrideRedirect;
341 xattributes.override_redirect = False;
343 if (parent_private && parent_private->guffaw_gravity)
345 xattributes.win_gravity = StaticGravity;
346 xattributes_mask |= CWWinGravity;
349 if (attributes->wclass == GDK_INPUT_OUTPUT)
352 depth = visual->depth;
354 if (attributes_mask & GDK_WA_COLORMAP)
355 private->colormap = attributes->colormap;
358 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
359 private->colormap = gdk_colormap_get_system ();
361 private->colormap = gdk_colormap_new (visual, False);
364 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
365 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
366 xattributes_mask |= CWBorderPixel | CWBackPixel;
368 switch (private->window_type)
370 case GDK_WINDOW_TOPLEVEL:
371 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
372 xattributes_mask |= CWColormap;
374 xparent = gdk_root_window;
377 case GDK_WINDOW_CHILD:
378 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
379 xattributes_mask |= CWColormap;
382 case GDK_WINDOW_DIALOG:
383 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
384 xattributes_mask |= CWColormap;
386 xparent = gdk_root_window;
389 case GDK_WINDOW_TEMP:
390 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
391 xattributes_mask |= CWColormap;
393 xparent = gdk_root_window;
395 xattributes.save_under = True;
396 xattributes.override_redirect = True;
397 xattributes.cursor = None;
398 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
400 case GDK_WINDOW_ROOT:
401 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
403 case GDK_WINDOW_PIXMAP:
404 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
412 private->colormap = NULL;
415 private->xwindow = XCreateWindow (private->xdisplay, xparent,
416 x, y, private->width, private->height,
417 0, depth, class, xvisual,
418 xattributes_mask, &xattributes);
419 gdk_window_ref (window);
420 gdk_xid_table_insert (&private->xwindow, window);
422 if (private->colormap)
423 gdk_colormap_ref (private->colormap);
425 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
426 (attributes->cursor) :
430 parent_private->children = g_list_prepend (parent_private->children, window);
432 switch (private->window_type)
434 case GDK_WINDOW_DIALOG:
435 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
436 case GDK_WINDOW_TOPLEVEL:
437 case GDK_WINDOW_TEMP:
438 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
440 case GDK_WINDOW_CHILD:
441 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
442 (private->colormap != gdk_colormap_get_system ()) &&
443 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
445 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
446 gdk_window_add_colormap_windows (window);
455 size_hints.flags = PSize;
456 size_hints.width = private->width;
457 size_hints.height = private->height;
459 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
460 wm_hints.window_group = gdk_leader_window;
461 wm_hints.input = True;
462 wm_hints.initial_state = NormalState;
464 /* FIXME: Is there any point in doing this? Do any WM's pay
465 * attention to PSize, and even if they do, is this the
468 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
470 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
472 if (!wm_client_leader_atom)
473 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
475 XChangeProperty (private->xdisplay, private->xwindow,
476 wm_client_leader_atom,
477 XA_WINDOW, 32, PropModeReplace,
478 (guchar*) &gdk_leader_window, 1);
480 if (attributes_mask & GDK_WA_TITLE)
481 title = attributes->title;
483 title = g_get_prgname ();
485 XmbSetWMProperties (private->xdisplay, private->xwindow,
490 if (attributes_mask & GDK_WA_WMCLASS)
492 class_hint = XAllocClassHint ();
493 class_hint->res_name = attributes->wmclass_name;
494 class_hint->res_class = attributes->wmclass_class;
495 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
504 gdk_window_foreign_new (guint32 anid)
507 GdkWindowPrivate *private;
508 GdkWindowPrivate *parent_private;
509 XWindowAttributes attrs;
511 Window *children = NULL;
515 gdk_error_trap_push ();
516 result = XGetWindowAttributes (gdk_display, anid, &attrs);
517 if (gdk_error_trap_pop () || !result)
520 /* FIXME: This is pretty expensive. Maybe the caller should supply
522 gdk_error_trap_push ();
523 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
524 if (gdk_error_trap_pop () || !result)
527 private = g_new (GdkWindowPrivate, 1);
528 window = (GdkWindow*) private;
532 private->parent = gdk_xid_table_lookup (parent);
534 parent_private = (GdkWindowPrivate *)private->parent;
537 parent_private->children = g_list_prepend (parent_private->children, window);
539 private->xwindow = anid;
540 private->xdisplay = gdk_display;
541 private->x = attrs.x;
542 private->y = attrs.y;
543 private->width = attrs.width;
544 private->height = attrs.height;
545 private->resize_count = 0;
546 private->ref_count = 1;
547 private->window_type = GDK_WINDOW_FOREIGN;
548 private->destroyed = FALSE;
549 private->mapped = (attrs.map_state != IsUnmapped);
550 private->guffaw_gravity = FALSE;
551 private->extension_events = 0;
553 private->colormap = NULL;
555 private->filters = NULL;
556 private->children = NULL;
558 window->user_data = NULL;
560 gdk_window_ref (window);
561 gdk_xid_table_insert (&private->xwindow, window);
566 /* Call this function when you want a window and all its children to
567 * disappear. When xdestroy is true, a request to destroy the XWindow
568 * is sent out. When it is false, it is assumed that the XWindow has
569 * been or will be destroyed by destroying some ancestor of this
573 gdk_window_internal_destroy (GdkWindow *window,
575 gboolean our_destroy)
577 GdkWindowPrivate *private;
578 GdkWindowPrivate *temp_private;
579 GdkWindow *temp_window;
583 g_return_if_fail (window != NULL);
585 private = (GdkWindowPrivate*) window;
587 switch (private->window_type)
589 case GDK_WINDOW_TOPLEVEL:
590 case GDK_WINDOW_CHILD:
591 case GDK_WINDOW_DIALOG:
592 case GDK_WINDOW_TEMP:
593 case GDK_WINDOW_FOREIGN:
594 if (!private->destroyed)
598 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
599 if (parent_private->children)
600 parent_private->children = g_list_remove (parent_private->children, window);
603 if (private->window_type != GDK_WINDOW_FOREIGN)
605 children = tmp = private->children;
606 private->children = NULL;
610 temp_window = tmp->data;
613 temp_private = (GdkWindowPrivate*) temp_window;
615 gdk_window_internal_destroy (temp_window, FALSE,
619 g_list_free (children);
622 if (private->extension_events != 0)
623 gdk_input_window_destroy (window);
625 if (private->filters)
627 tmp = private->filters;
635 g_list_free (private->filters);
636 private->filters = NULL;
639 if (private->window_type == GDK_WINDOW_FOREIGN)
641 if (our_destroy && (private->parent != NULL))
643 /* It's somebody elses window, but in our heirarchy,
644 * so reparent it to the root window, and then send
645 * it a delete event, as if we were a WM
647 XClientMessageEvent xevent;
649 gdk_error_trap_push ();
650 gdk_window_hide (window);
651 gdk_window_reparent (window, NULL, 0, 0);
653 xevent.type = ClientMessage;
654 xevent.window = private->xwindow;
655 xevent.message_type = gdk_wm_protocols;
657 xevent.data.l[0] = gdk_wm_delete_window;
658 xevent.data.l[1] = CurrentTime;
660 XSendEvent (private->xdisplay, private->xwindow,
661 False, 0, (XEvent *)&xevent);
663 gdk_error_trap_pop ();
667 XDestroyWindow (private->xdisplay, private->xwindow);
669 if (private->colormap)
670 gdk_colormap_unref (private->colormap);
672 private->mapped = FALSE;
673 private->destroyed = TRUE;
677 case GDK_WINDOW_ROOT:
678 g_error ("attempted to destroy root window");
681 case GDK_WINDOW_PIXMAP:
682 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
687 /* Like internal_destroy, but also destroys the reference created by
691 gdk_window_destroy (GdkWindow *window)
693 gdk_window_internal_destroy (window, TRUE, TRUE);
694 gdk_window_unref (window);
697 /* This function is called when the XWindow is really gone. */
700 gdk_window_destroy_notify (GdkWindow *window)
702 GdkWindowPrivate *private;
704 g_return_if_fail (window != NULL);
706 private = (GdkWindowPrivate*) window;
708 if (!private->destroyed)
710 if (private->window_type == GDK_WINDOW_FOREIGN)
711 gdk_window_internal_destroy (window, FALSE, FALSE);
713 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
716 gdk_xid_table_remove (private->xwindow);
717 gdk_window_unref (window);
721 gdk_window_ref (GdkWindow *window)
723 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
724 g_return_val_if_fail (window != NULL, NULL);
726 private->ref_count += 1;
731 gdk_window_unref (GdkWindow *window)
733 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
734 g_return_if_fail (window != NULL);
736 private->ref_count -= 1;
737 if (private->ref_count == 0)
739 if (!private->destroyed)
741 if (private->window_type == GDK_WINDOW_FOREIGN)
742 gdk_xid_table_remove (private->xwindow);
744 g_warning ("losing last reference to undestroyed window\n");
746 g_dataset_destroy (window);
752 gdk_window_show (GdkWindow *window)
754 GdkWindowPrivate *private;
756 g_return_if_fail (window != NULL);
758 private = (GdkWindowPrivate*) window;
759 if (!private->destroyed)
761 private->mapped = TRUE;
762 XRaiseWindow (private->xdisplay, private->xwindow);
763 XMapWindow (private->xdisplay, private->xwindow);
768 gdk_window_hide (GdkWindow *window)
770 GdkWindowPrivate *private;
772 g_return_if_fail (window != NULL);
774 private = (GdkWindowPrivate*) window;
775 if (!private->destroyed)
777 private->mapped = FALSE;
778 XUnmapWindow (private->xdisplay, private->xwindow);
783 gdk_window_withdraw (GdkWindow *window)
785 GdkWindowPrivate *private;
787 g_return_if_fail (window != NULL);
789 private = (GdkWindowPrivate*) window;
790 if (!private->destroyed)
791 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
795 gdk_window_move (GdkWindow *window,
799 GdkWindowPrivate *private;
801 g_return_if_fail (window != NULL);
803 private = (GdkWindowPrivate*) window;
804 if (!private->destroyed)
806 XMoveWindow (private->xdisplay, private->xwindow, x, y);
808 if (private->window_type == GDK_WINDOW_CHILD)
817 gdk_window_resize (GdkWindow *window,
821 GdkWindowPrivate *private;
823 g_return_if_fail (window != NULL);
830 private = (GdkWindowPrivate*) window;
832 if (!private->destroyed &&
833 ((private->resize_count > 0) ||
834 (private->width != (guint16) width) ||
835 (private->height != (guint16) height)))
837 XResizeWindow (private->xdisplay, private->xwindow, width, height);
838 private->resize_count += 1;
840 if (private->window_type == GDK_WINDOW_CHILD)
842 private->width = width;
843 private->height = height;
849 gdk_window_move_resize (GdkWindow *window,
855 GdkWindowPrivate *private;
857 g_return_if_fail (window != NULL);
864 private = (GdkWindowPrivate*) window;
865 if (!private->destroyed)
867 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
869 if (private->guffaw_gravity)
871 GList *tmp_list = private->children;
874 GdkWindowPrivate *child_private = tmp_list->data;
876 child_private->x -= x - private->x;
877 child_private->y -= y - private->y;
879 tmp_list = tmp_list->next;
883 if (private->window_type == GDK_WINDOW_CHILD)
887 private->width = width;
888 private->height = height;
894 gdk_window_reparent (GdkWindow *window,
895 GdkWindow *new_parent,
899 GdkWindowPrivate *window_private;
900 GdkWindowPrivate *parent_private;
901 GdkWindowPrivate *old_parent_private;
903 g_return_if_fail (window != NULL);
906 new_parent = (GdkWindow*) &gdk_root_parent;
908 window_private = (GdkWindowPrivate*) window;
909 old_parent_private = (GdkWindowPrivate*)window_private->parent;
910 parent_private = (GdkWindowPrivate*) new_parent;
912 if (!window_private->destroyed && !parent_private->destroyed)
913 XReparentWindow (window_private->xdisplay,
914 window_private->xwindow,
915 parent_private->xwindow,
918 window_private->parent = new_parent;
920 if (old_parent_private)
921 old_parent_private->children = g_list_remove (old_parent_private->children, window);
923 if ((old_parent_private &&
924 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
925 (!old_parent_private && parent_private->guffaw_gravity))
926 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
928 parent_private->children = g_list_prepend (parent_private->children, window);
932 gdk_window_clear (GdkWindow *window)
934 GdkWindowPrivate *private;
936 g_return_if_fail (window != NULL);
938 private = (GdkWindowPrivate*) window;
940 if (!private->destroyed)
941 XClearWindow (private->xdisplay, private->xwindow);
945 gdk_window_clear_area (GdkWindow *window,
951 GdkWindowPrivate *private;
953 g_return_if_fail (window != NULL);
955 private = (GdkWindowPrivate*) window;
957 if (!private->destroyed)
958 XClearArea (private->xdisplay, private->xwindow,
959 x, y, width, height, False);
963 gdk_window_clear_area_e (GdkWindow *window,
969 GdkWindowPrivate *private;
971 g_return_if_fail (window != NULL);
973 private = (GdkWindowPrivate*) window;
975 if (!private->destroyed)
976 XClearArea (private->xdisplay, private->xwindow,
977 x, y, width, height, True);
981 gdk_window_copy_area (GdkWindow *window,
985 GdkWindow *source_window,
991 GdkWindowPrivate *src_private;
992 GdkWindowPrivate *dest_private;
993 GdkGCPrivate *gc_private;
995 g_return_if_fail (window != NULL);
996 g_return_if_fail (gc != NULL);
998 if (source_window == NULL)
999 source_window = window;
1001 src_private = (GdkWindowPrivate*) source_window;
1002 dest_private = (GdkWindowPrivate*) window;
1003 gc_private = (GdkGCPrivate*) gc;
1005 if (!src_private->destroyed && !dest_private->destroyed)
1007 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
1016 gdk_window_raise (GdkWindow *window)
1018 GdkWindowPrivate *private;
1020 g_return_if_fail (window != NULL);
1022 private = (GdkWindowPrivate*) window;
1024 if (!private->destroyed)
1025 XRaiseWindow (private->xdisplay, private->xwindow);
1029 gdk_window_lower (GdkWindow *window)
1031 GdkWindowPrivate *private;
1033 g_return_if_fail (window != NULL);
1035 private = (GdkWindowPrivate*) window;
1037 if (!private->destroyed)
1038 XLowerWindow (private->xdisplay, private->xwindow);
1042 gdk_window_set_user_data (GdkWindow *window,
1045 g_return_if_fail (window != NULL);
1047 window->user_data = user_data;
1051 gdk_window_set_hints (GdkWindow *window,
1060 GdkWindowPrivate *private;
1061 XSizeHints size_hints;
1063 g_return_if_fail (window != NULL);
1065 private = (GdkWindowPrivate*) window;
1066 if (private->destroyed)
1069 size_hints.flags = 0;
1071 if (flags & GDK_HINT_POS)
1073 size_hints.flags |= PPosition;
1078 if (flags & GDK_HINT_MIN_SIZE)
1080 size_hints.flags |= PMinSize;
1081 size_hints.min_width = min_width;
1082 size_hints.min_height = min_height;
1085 if (flags & GDK_HINT_MAX_SIZE)
1087 size_hints.flags |= PMaxSize;
1088 size_hints.max_width = max_width;
1089 size_hints.max_height = max_height;
1093 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1097 gdk_window_set_geometry_hints (GdkWindow *window,
1098 GdkGeometry *geometry,
1099 GdkWindowHints geom_mask)
1101 GdkWindowPrivate *private;
1102 XSizeHints size_hints;
1104 g_return_if_fail (window != NULL);
1106 private = (GdkWindowPrivate*) window;
1107 if (private->destroyed)
1110 size_hints.flags = 0;
1112 if (geom_mask & GDK_HINT_POS)
1113 size_hints.flags |= PPosition;
1115 if (geom_mask & GDK_HINT_MIN_SIZE)
1117 size_hints.flags |= PMinSize;
1118 size_hints.min_width = geometry->min_width;
1119 size_hints.min_height = geometry->min_height;
1122 if (geom_mask & GDK_HINT_MAX_SIZE)
1124 size_hints.flags |= PMaxSize;
1125 size_hints.max_width = MAX (geometry->max_width, 1);
1126 size_hints.max_height = MAX (geometry->max_height, 1);
1129 if (geom_mask & GDK_HINT_BASE_SIZE)
1131 size_hints.flags |= PBaseSize;
1132 size_hints.base_width = geometry->base_width;
1133 size_hints.base_height = geometry->base_height;
1136 if (geom_mask & GDK_HINT_RESIZE_INC)
1138 size_hints.flags |= PResizeInc;
1139 size_hints.width_inc = geometry->width_inc;
1140 size_hints.height_inc = geometry->height_inc;
1143 if (geom_mask & GDK_HINT_ASPECT)
1145 size_hints.flags |= PAspect;
1146 if (geometry->min_aspect <= 1)
1148 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1149 size_hints.min_aspect.y = G_MAXINT;
1153 size_hints.min_aspect.x = G_MAXINT;
1154 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1156 if (geometry->max_aspect <= 1)
1158 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1159 size_hints.max_aspect.y = G_MAXINT;
1163 size_hints.max_aspect.x = G_MAXINT;
1164 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1169 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1173 gdk_window_set_title (GdkWindow *window,
1176 GdkWindowPrivate *private;
1178 g_return_if_fail (window != NULL);
1180 private = (GdkWindowPrivate*) window;
1181 if (!private->destroyed)
1182 XmbSetWMProperties (private->xdisplay, private->xwindow,
1183 title, title, NULL, 0, NULL, NULL, NULL);
1187 gdk_window_set_role (GdkWindow *window,
1190 GdkWindowPrivate *private;
1192 g_return_if_fail (window != NULL);
1194 private = (GdkWindowPrivate*) window;
1197 XChangeProperty (private->xdisplay, private->xwindow,
1198 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1199 8, PropModeReplace, role, strlen (role));
1201 XDeleteProperty (private->xdisplay, private->xwindow,
1202 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1206 gdk_window_set_transient_for (GdkWindow *window,
1209 GdkWindowPrivate *private;
1210 GdkWindowPrivate *parent_private;
1212 g_return_if_fail (window != NULL);
1214 private = (GdkWindowPrivate*) window;
1215 parent_private = (GdkWindowPrivate*) parent;
1217 if (!private->destroyed && !parent_private->destroyed)
1218 XSetTransientForHint (private->xdisplay,
1219 private->xwindow, parent_private->xwindow);
1223 gdk_window_set_background (GdkWindow *window,
1226 GdkWindowPrivate *private;
1228 g_return_if_fail (window != NULL);
1230 private = (GdkWindowPrivate*) window;
1231 if (!private->destroyed)
1232 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1236 gdk_window_set_back_pixmap (GdkWindow *window,
1238 gint parent_relative)
1240 GdkWindowPrivate *window_private;
1241 GdkPixmapPrivate *pixmap_private;
1244 g_return_if_fail (window != NULL);
1246 window_private = (GdkWindowPrivate*) window;
1247 pixmap_private = (GdkPixmapPrivate*) pixmap;
1250 xpixmap = pixmap_private->xwindow;
1254 if (parent_relative)
1255 xpixmap = ParentRelative;
1257 if (!window_private->destroyed)
1258 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1262 gdk_window_set_cursor (GdkWindow *window,
1265 GdkWindowPrivate *window_private;
1266 GdkCursorPrivate *cursor_private;
1269 g_return_if_fail (window != NULL);
1271 window_private = (GdkWindowPrivate*) window;
1272 cursor_private = (GdkCursorPrivate*) cursor;
1277 xcursor = cursor_private->xcursor;
1279 if (!window_private->destroyed)
1280 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1284 gdk_window_set_colormap (GdkWindow *window,
1285 GdkColormap *colormap)
1287 GdkWindowPrivate *window_private;
1288 GdkColormapPrivate *colormap_private;
1290 g_return_if_fail (window != NULL);
1291 g_return_if_fail (colormap != NULL);
1293 window_private = (GdkWindowPrivate*) window;
1294 colormap_private = (GdkColormapPrivate*) colormap;
1296 if (!window_private->destroyed)
1298 XSetWindowColormap (window_private->xdisplay,
1299 window_private->xwindow,
1300 colormap_private->xcolormap);
1302 if (window_private->colormap)
1303 gdk_colormap_unref (window_private->colormap);
1304 window_private->colormap = colormap;
1305 gdk_colormap_ref (window_private->colormap);
1307 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1308 gdk_window_add_colormap_windows (window);
1313 gdk_window_get_user_data (GdkWindow *window,
1316 g_return_if_fail (window != NULL);
1318 *data = window->user_data;
1322 gdk_window_get_geometry (GdkWindow *window,
1329 GdkWindowPrivate *window_private;
1335 guint tborder_width;
1339 window = (GdkWindow*) &gdk_root_parent;
1341 window_private = (GdkWindowPrivate*) window;
1343 if (!window_private->destroyed)
1345 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1346 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1362 gdk_window_get_position (GdkWindow *window,
1366 GdkWindowPrivate *window_private;
1368 g_return_if_fail (window != NULL);
1370 window_private = (GdkWindowPrivate*) window;
1373 *x = window_private->x;
1375 *y = window_private->y;
1379 gdk_window_get_size (GdkWindow *window,
1383 GdkWindowPrivate *window_private;
1385 g_return_if_fail (window != NULL);
1387 window_private = (GdkWindowPrivate*) window;
1390 *width = window_private->width;
1392 *height = window_private->height;
1396 gdk_window_get_visual (GdkWindow *window)
1398 GdkWindowPrivate *window_private;
1399 XWindowAttributes window_attributes;
1401 g_return_val_if_fail (window != NULL, NULL);
1403 window_private = (GdkWindowPrivate*) window;
1404 /* Huh? ->parent is never set for a pixmap. We should just return
1407 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1408 window_private = (GdkWindowPrivate*) window_private->parent;
1410 if (window_private && !window_private->destroyed)
1412 if (window_private->colormap == NULL)
1414 XGetWindowAttributes (window_private->xdisplay,
1415 window_private->xwindow,
1416 &window_attributes);
1417 return gdk_visual_lookup (window_attributes.visual);
1420 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1427 gdk_window_get_colormap (GdkWindow *window)
1429 GdkWindowPrivate *window_private;
1430 XWindowAttributes window_attributes;
1432 g_return_val_if_fail (window != NULL, NULL);
1433 window_private = (GdkWindowPrivate*) window;
1435 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1436 if (!window_private->destroyed)
1438 if (window_private->colormap == NULL)
1440 XGetWindowAttributes (window_private->xdisplay,
1441 window_private->xwindow,
1442 &window_attributes);
1443 return gdk_colormap_lookup (window_attributes.colormap);
1446 return window_private->colormap;
1453 gdk_window_get_type (GdkWindow *window)
1455 GdkWindowPrivate *window_private;
1457 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1459 window_private = (GdkWindowPrivate*) window;
1460 return window_private->window_type;
1464 gdk_window_get_origin (GdkWindow *window,
1468 GdkWindowPrivate *private;
1474 g_return_val_if_fail (window != NULL, 0);
1476 private = (GdkWindowPrivate*) window;
1478 if (!private->destroyed)
1480 return_val = XTranslateCoordinates (private->xdisplay,
1499 gdk_window_get_deskrelative_origin (GdkWindow *window,
1503 GdkWindowPrivate *private;
1504 gboolean return_val = FALSE;
1505 gint num_children, format_return;
1506 Window win, *child, parent, root;
1510 static Atom atom = 0;
1511 gulong number_return, bytes_after_return;
1512 guchar *data_return;
1514 g_return_val_if_fail (window != NULL, 0);
1516 private = (GdkWindowPrivate*) window;
1518 if (!private->destroyed)
1521 atom = XInternAtom (private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1522 win = private->xwindow;
1524 while (XQueryTree (private->xdisplay, win, &root, &parent,
1525 &child, (unsigned int *)&num_children))
1527 if ((child) && (num_children > 0))
1539 XGetWindowProperty (private->xdisplay, win, atom, 0, 0,
1540 False, XA_CARDINAL, &type_return, &format_return,
1541 &number_return, &bytes_after_return, &data_return);
1542 if (type_return == XA_CARDINAL)
1544 XFree (data_return);
1549 return_val = XTranslateCoordinates (private->xdisplay,
1565 gdk_window_get_root_origin (GdkWindow *window,
1569 GdkWindowPrivate *private;
1574 unsigned int nchildren;
1576 g_return_if_fail (window != NULL);
1578 private = (GdkWindowPrivate*) window;
1583 if (private->destroyed)
1586 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1587 private = (GdkWindowPrivate*) private->parent;
1588 if (private->destroyed)
1591 xparent = private->xwindow;
1595 if (!XQueryTree (private->xdisplay, xwindow,
1597 &children, &nchildren))
1603 while (xparent != root);
1605 if (xparent == root)
1607 unsigned int ww, wh, wb, wd;
1610 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1621 gdk_window_get_pointer (GdkWindow *window,
1624 GdkModifierType *mask)
1626 GdkWindowPrivate *private;
1627 GdkWindow *return_val;
1633 unsigned int xmask = 0;
1636 window = (GdkWindow*) &gdk_root_parent;
1638 private = (GdkWindowPrivate*) window;
1641 if (!private->destroyed &&
1642 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1643 &rootx, &rooty, &winx, &winy, &xmask))
1646 return_val = gdk_window_lookup (child);
1660 gdk_window_at_pointer (gint *win_x,
1663 GdkWindowPrivate *private;
1667 Window xwindow_last = 0;
1668 int rootx = -1, rooty = -1;
1672 private = &gdk_root_parent;
1674 xwindow = private->xwindow;
1676 XGrabServer (private->xdisplay);
1679 xwindow_last = xwindow;
1680 XQueryPointer (private->xdisplay,
1687 XUngrabServer (private->xdisplay);
1689 window = gdk_window_lookup (xwindow_last);
1692 *win_x = window ? winx : -1;
1694 *win_y = window ? winy : -1;
1700 gdk_window_get_parent (GdkWindow *window)
1702 g_return_val_if_fail (window != NULL, NULL);
1704 return ((GdkWindowPrivate*) window)->parent;
1708 gdk_window_get_toplevel (GdkWindow *window)
1710 GdkWindowPrivate *private;
1712 g_return_val_if_fail (window != NULL, NULL);
1714 private = (GdkWindowPrivate*) window;
1716 while (private->window_type == GDK_WINDOW_CHILD)
1718 window = ((GdkWindowPrivate*) window)->parent;
1719 private = (GdkWindowPrivate*) window;
1726 gdk_window_get_children (GdkWindow *window)
1728 GdkWindowPrivate *private;
1734 unsigned int nchildren;
1737 g_return_val_if_fail (window != NULL, NULL);
1739 private = (GdkWindowPrivate*) window;
1740 if (private->destroyed)
1743 XQueryTree (private->xdisplay, private->xwindow,
1744 &root, &parent, &xchildren, &nchildren);
1750 for (i = 0; i < nchildren; i++)
1752 child = gdk_window_lookup (xchildren[i]);
1754 children = g_list_prepend (children, child);
1765 gdk_window_get_events (GdkWindow *window)
1767 GdkWindowPrivate *private;
1768 XWindowAttributes attrs;
1769 GdkEventMask event_mask;
1772 g_return_val_if_fail (window != NULL, 0);
1774 private = (GdkWindowPrivate*) window;
1775 if (private->destroyed)
1778 XGetWindowAttributes (gdk_display, private->xwindow,
1782 for (i = 0; i < gdk_nevent_masks; i++)
1784 if (attrs.your_event_mask & gdk_event_mask_table[i])
1785 event_mask |= 1 << (i + 1);
1792 gdk_window_set_events (GdkWindow *window,
1793 GdkEventMask event_mask)
1795 GdkWindowPrivate *private;
1799 g_return_if_fail (window != NULL);
1801 private = (GdkWindowPrivate*) window;
1802 if (private->destroyed)
1805 xevent_mask = StructureNotifyMask;
1806 for (i = 0; i < gdk_nevent_masks; i++)
1808 if (event_mask & (1 << (i + 1)))
1809 xevent_mask |= gdk_event_mask_table[i];
1812 XSelectInput (gdk_display, private->xwindow,
1817 gdk_window_add_colormap_windows (GdkWindow *window)
1819 GdkWindow *toplevel;
1820 GdkWindowPrivate *toplevel_private;
1821 GdkWindowPrivate *window_private;
1822 Window *old_windows;
1823 Window *new_windows;
1826 g_return_if_fail (window != NULL);
1828 toplevel = gdk_window_get_toplevel (window);
1829 toplevel_private = (GdkWindowPrivate*) toplevel;
1830 window_private = (GdkWindowPrivate*) window;
1831 if (window_private->destroyed)
1835 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1836 toplevel_private->xwindow,
1837 &old_windows, &count))
1842 for (i = 0; i < count; i++)
1843 if (old_windows[i] == window_private->xwindow)
1845 XFree (old_windows);
1849 new_windows = g_new (Window, count + 1);
1851 for (i = 0; i < count; i++)
1852 new_windows[i] = old_windows[i];
1853 new_windows[count] = window_private->xwindow;
1855 XSetWMColormapWindows (toplevel_private->xdisplay,
1856 toplevel_private->xwindow,
1857 new_windows, count + 1);
1859 g_free (new_windows);
1861 XFree (old_windows);
1865 gdk_window_have_shape_ext (void)
1867 enum { UNKNOWN, NO, YES };
1868 static gint have_shape = UNKNOWN;
1870 if (have_shape == UNKNOWN)
1873 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1879 return (have_shape == YES);
1883 * This needs the X11 shape extension.
1884 * If not available, shaped windows will look
1885 * ugly, but programs still work. Stefan Wille
1888 gdk_window_shape_combine_mask (GdkWindow *window,
1892 GdkWindowPrivate *window_private;
1895 g_return_if_fail (window != NULL);
1897 #ifdef HAVE_SHAPE_EXT
1898 window_private = (GdkWindowPrivate*) window;
1899 if (window_private->destroyed)
1902 if (gdk_window_have_shape_ext ())
1906 GdkWindowPrivate *pixmap_private;
1908 pixmap_private = (GdkWindowPrivate*) mask;
1909 pixmap = (Pixmap) pixmap_private->xwindow;
1918 XShapeCombineMask (window_private->xdisplay,
1919 window_private->xwindow,
1925 #endif /* HAVE_SHAPE_EXT */
1929 gdk_window_add_filter (GdkWindow *window,
1930 GdkFilterFunc function,
1933 GdkWindowPrivate *private;
1935 GdkEventFilter *filter;
1937 private = (GdkWindowPrivate*) window;
1938 if (private && private->destroyed)
1942 tmp_list = private->filters;
1944 tmp_list = gdk_default_filters;
1948 filter = (GdkEventFilter *)tmp_list->data;
1949 if ((filter->function == function) && (filter->data == data))
1951 tmp_list = tmp_list->next;
1954 filter = g_new (GdkEventFilter, 1);
1955 filter->function = function;
1956 filter->data = data;
1959 private->filters = g_list_append (private->filters, filter);
1961 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1965 gdk_window_remove_filter (GdkWindow *window,
1966 GdkFilterFunc function,
1969 GdkWindowPrivate *private;
1970 GList *tmp_list, *node;
1971 GdkEventFilter *filter;
1973 private = (GdkWindowPrivate*) window;
1976 tmp_list = private->filters;
1978 tmp_list = gdk_default_filters;
1982 filter = (GdkEventFilter *)tmp_list->data;
1984 tmp_list = tmp_list->next;
1986 if ((filter->function == function) && (filter->data == data))
1989 private->filters = g_list_remove_link (private->filters, node);
1991 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1992 g_list_free_1 (node);
2001 gdk_window_set_override_redirect (GdkWindow *window,
2002 gboolean override_redirect)
2004 GdkWindowPrivate *private;
2005 XSetWindowAttributes attr;
2007 g_return_if_fail (window != NULL);
2008 private = (GdkWindowPrivate*) window;
2009 if (private->destroyed)
2012 attr.override_redirect = (override_redirect == FALSE)?False:True;
2013 XChangeWindowAttributes (gdk_display,
2014 ((GdkWindowPrivate *)window)->xwindow,
2020 gdk_window_set_icon (GdkWindow *window,
2021 GdkWindow *icon_window,
2026 GdkWindowPrivate *window_private;
2027 GdkWindowPrivate *private;
2029 g_return_if_fail (window != NULL);
2030 window_private = (GdkWindowPrivate*) window;
2031 if (window_private->destroyed)
2034 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2036 wm_hints = XAllocWMHints ();
2038 if (icon_window != NULL)
2040 private = (GdkWindowPrivate *)icon_window;
2041 wm_hints->flags |= IconWindowHint;
2042 wm_hints->icon_window = private->xwindow;
2047 private = (GdkWindowPrivate *)pixmap;
2048 wm_hints->flags |= IconPixmapHint;
2049 wm_hints->icon_pixmap = private->xwindow;
2054 private = (GdkWindowPrivate *)mask;
2055 wm_hints->flags |= IconMaskHint;
2056 wm_hints->icon_mask = private->xwindow;
2059 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2064 gdk_window_set_icon_name (GdkWindow *window,
2067 GdkWindowPrivate *window_private;
2068 XTextProperty property;
2071 g_return_if_fail (window != NULL);
2072 window_private = (GdkWindowPrivate*) window;
2073 if (window_private->destroyed)
2075 res = XmbTextListToTextProperty (window_private->xdisplay,
2076 &name, 1, XStdICCTextStyle,
2080 g_warning ("Error converting icon name to text property: %d\n", res);
2084 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2088 XFree (property.value);
2092 gdk_window_set_group (GdkWindow *window,
2096 GdkWindowPrivate *window_private;
2097 GdkWindowPrivate *private;
2099 g_return_if_fail (window != NULL);
2100 g_return_if_fail (leader != NULL);
2101 window_private = (GdkWindowPrivate*) window;
2102 if (window_private->destroyed)
2105 private = (GdkWindowPrivate *)leader;
2107 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2109 wm_hints = XAllocWMHints ();
2111 wm_hints->flags |= WindowGroupHint;
2112 wm_hints->window_group = private->xwindow;
2114 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2119 gdk_window_set_mwm_hints (GdkWindow *window,
2120 MotifWmHints *new_hints)
2122 static Atom hints_atom = None;
2123 MotifWmHints *hints;
2129 GdkWindowPrivate *window_private;
2131 g_return_if_fail (window != NULL);
2132 window_private = (GdkWindowPrivate*) window;
2133 if (window_private->destroyed)
2137 hints_atom = XInternAtom (window_private->xdisplay,
2138 _XA_MOTIF_WM_HINTS, FALSE);
2140 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2141 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2142 False, AnyPropertyType, &type, &format, &nitems,
2143 &bytes_after, (guchar **)&hints);
2149 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2151 hints->flags |= MWM_HINTS_FUNCTIONS;
2152 hints->functions = new_hints->functions;
2154 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2156 hints->flags |= MWM_HINTS_DECORATIONS;
2157 hints->decorations = new_hints->decorations;
2161 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2162 hints_atom, hints_atom, 32, PropModeReplace,
2163 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
2165 if (hints != new_hints)
2170 gdk_window_set_decorations (GdkWindow *window,
2171 GdkWMDecoration decorations)
2175 hints.flags = MWM_HINTS_DECORATIONS;
2176 hints.decorations = decorations;
2178 gdk_window_set_mwm_hints (window, &hints);
2182 gdk_window_set_functions (GdkWindow *window,
2183 GdkWMFunction functions)
2187 hints.flags = MWM_HINTS_FUNCTIONS;
2188 hints.functions = functions;
2190 gdk_window_set_mwm_hints (window, &hints);
2194 gdk_window_get_toplevels (void)
2196 GList *new_list = NULL;
2199 tmp_list = gdk_root_parent.children;
2202 new_list = g_list_prepend (new_list, tmp_list->data);
2203 tmp_list = tmp_list->next;
2210 * propagate the shapes from all child windows of a GDK window to the parent
2211 * window. Shamelessly ripped from Enlightenment's code
2220 struct _gdk_span *next;
2224 gdk_add_to_span (struct _gdk_span **s,
2228 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2235 /* scan the spans for this line */
2238 /* -- -> new span */
2239 /* == -> existing span */
2240 /* ## -> spans intersect */
2241 /* if we are in the middle of spanning the span into the line */
2244 /* case: ---- ==== */
2245 if (xx < ptr1->start - 1)
2247 /* ends before next span - extend to here */
2251 /* case: ----##=== */
2252 else if (xx <= ptr1->end)
2254 /* crosses into next span - delete next span and append */
2255 ss->end = ptr1->end;
2256 ss->next = ptr1->next;
2260 /* case: ---###--- */
2263 /* overlaps next span - delete and keep checking */
2264 ss->next = ptr1->next;
2269 /* otherwise havent started spanning it in yet */
2272 /* case: ---- ==== */
2273 if (xx < ptr1->start - 1)
2275 /* insert span here in list */
2276 noo = g_malloc (sizeof (struct _gdk_span));
2290 /* case: ----##=== */
2291 else if ((x < ptr1->start) && (xx <= ptr1->end))
2293 /* expand this span to the left point of the new one */
2297 /* case: ===###=== */
2298 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2300 /* throw the span away */
2303 /* case: ---###--- */
2304 else if ((x < ptr1->start) && (xx > ptr1->end))
2311 /* case: ===##---- */
2312 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2318 /* case: ==== ---- */
2319 /* case handled by next loop iteration - first case */
2324 /* it started in the middle but spans beyond your current list */
2330 /* it does not start inside a span or in the middle, so add it to the end */
2331 noo = g_malloc (sizeof (struct _gdk_span));
2339 noo->next = ptr2->next;
2352 gdk_add_rectangles (Display *disp,
2354 struct _gdk_span **spans,
2361 gint x1, y1, x2, y2;
2365 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2368 /* go through all clip rects in this window's shape */
2369 for (k = 0; k < rn; k++)
2371 /* for each clip rect, add it to each line's spans */
2373 x2 = x + rl[k].x + (rl[k].width - 1);
2375 y2 = y + rl[k].y + (rl[k].height - 1);
2384 for (a = y1; a <= y2; a++)
2387 gdk_add_to_span (&spans[a], x1, x2);
2395 gdk_propagate_shapes (Display *disp,
2399 Window rt, par, *list = NULL;
2400 gint i, j, num = 0, num_rects = 0;
2404 XRectangle *rects = NULL;
2405 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2406 XWindowAttributes xatt;
2408 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2413 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2415 for (i = 0; i < h; i++)
2417 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2420 /* go through all child windows and create/insert spans */
2421 for (i = 0; i < num; i++)
2423 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2424 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2425 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2428 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2430 /* go through the spans list and build a list of rects */
2431 rects = g_malloc (sizeof (XRectangle) * 256);
2433 for (i = 0; i < baseh; i++)
2436 /* go through the line for all spans */
2439 rects[num_rects].x = ptr1->start;
2440 rects[num_rects].y = i;
2441 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2442 rects[num_rects].height = 1;
2444 /* if there are more lines */
2446 /* while contigous rects (same start/end coords) exist */
2447 while ((contig) && (j < baseh))
2449 /* search next line for spans matching this one */
2455 /* if we have an exact span match set contig */
2456 if ((ptr2->start == ptr1->start) &&
2457 (ptr2->end == ptr1->end))
2460 /* remove the span - not needed */
2463 ptr3->next = ptr2->next;
2469 spans[j] = ptr2->next;
2475 /* gone past the span point no point looking */
2476 else if (ptr2->start < ptr1->start)
2484 /* if a contiguous span was found increase the rect h */
2487 rects[num_rects].height++;
2491 /* up the rect count */
2493 /* every 256 new rects increase the rect array */
2494 if ((num_rects % 256) == 0)
2495 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2499 /* set the rects as the shape mask */
2502 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2503 ShapeSet, YXSorted);
2508 /* free up all the spans we made */
2509 for (i = 0; i < baseh; i++)
2523 gdk_window_set_child_shapes (GdkWindow *window)
2525 GdkWindowPrivate *private;
2527 g_return_if_fail (window != NULL);
2529 #ifdef HAVE_SHAPE_EXT
2530 private = (GdkWindowPrivate*) window;
2531 if (private->destroyed)
2534 if (gdk_window_have_shape_ext ())
2535 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2540 gdk_window_merge_child_shapes (GdkWindow *window)
2542 GdkWindowPrivate *private;
2544 g_return_if_fail (window != NULL);
2546 #ifdef HAVE_SHAPE_EXT
2547 private = (GdkWindowPrivate*) window;
2548 if (private->destroyed)
2551 if (gdk_window_have_shape_ext ())
2552 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2556 /*************************************************************
2557 * gdk_window_is_visible:
2558 * Check if the given window is mapped.
2562 * is the window mapped
2563 *************************************************************/
2566 gdk_window_is_visible (GdkWindow *window)
2568 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2570 g_return_val_if_fail (window != NULL, FALSE);
2572 return private->mapped;
2575 /*************************************************************
2576 * gdk_window_is_viewable:
2577 * Check if the window and all ancestors of the window
2578 * are mapped. (This is not necessarily "viewable" in
2579 * the X sense, since we only check as far as we have
2580 * GDK window parents, not to the root window)
2584 * is the window viewable
2585 *************************************************************/
2588 gdk_window_is_viewable (GdkWindow *window)
2590 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2592 g_return_val_if_fail (window != NULL, FALSE);
2595 (private != &gdk_root_parent) &&
2596 (private->window_type != GDK_WINDOW_FOREIGN))
2598 if (!private->mapped)
2601 private = (GdkWindowPrivate *)private->parent;
2608 gdk_drawable_set_data (GdkDrawable *drawable,
2611 GDestroyNotify destroy_func)
2613 g_dataset_set_data_full (drawable, key, data, destroy_func);
2617 /* Support for windows that can be guffaw-scrolled
2618 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2622 gdk_window_gravity_works (void)
2624 enum { UNKNOWN, NO, YES };
2625 static gint gravity_works = UNKNOWN;
2627 if (gravity_works == UNKNOWN)
2634 /* This particular server apparently has a bug so that the test
2635 * works but the actual code crashes it
2637 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2638 (VendorRelease (gdk_display) == 3400))
2644 attr.window_type = GDK_WINDOW_TEMP;
2645 attr.wclass = GDK_INPUT_OUTPUT;
2650 attr.event_mask = 0;
2652 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2654 attr.window_type = GDK_WINDOW_CHILD;
2655 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2657 gdk_window_set_static_win_gravity (child, TRUE);
2659 gdk_window_resize (parent, 100, 110);
2660 gdk_window_move (parent, 0, -10);
2661 gdk_window_move_resize (parent, 0, 0, 100, 100);
2663 gdk_window_resize (parent, 100, 110);
2664 gdk_window_move (parent, 0, -10);
2665 gdk_window_move_resize (parent, 0, 0, 100, 100);
2667 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2669 gdk_window_destroy (parent);
2670 gdk_window_destroy (child);
2672 gravity_works = ((y == -20) ? YES : NO);
2675 return (gravity_works == YES);
2679 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2681 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2682 XSetWindowAttributes xattributes;
2684 g_return_if_fail (window != NULL);
2686 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2687 XChangeWindowAttributes (private->xdisplay,
2689 CWBitGravity, &xattributes);
2693 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2695 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2696 XSetWindowAttributes xattributes;
2698 g_return_if_fail (window != NULL);
2700 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2702 XChangeWindowAttributes (private->xdisplay,
2704 CWWinGravity, &xattributes);
2707 /*************************************************************
2708 * gdk_window_set_static_gravities:
2709 * Set the bit gravity of the given window to static,
2710 * and flag it so all children get static subwindow
2713 * window: window for which to set static gravity
2714 * use_static: Whether to turn static gravity on or off.
2716 * Does the XServer support static gravity?
2717 *************************************************************/
2720 gdk_window_set_static_gravities (GdkWindow *window,
2721 gboolean use_static)
2723 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2726 g_return_val_if_fail (window != NULL, FALSE);
2728 if (!use_static == !private->guffaw_gravity)
2731 if (use_static && !gdk_window_gravity_works ())
2734 private->guffaw_gravity = use_static;
2736 gdk_window_set_static_bit_gravity (window, use_static);
2738 tmp_list = private->children;
2741 gdk_window_set_static_win_gravity (window, use_static);
2743 tmp_list = tmp_list->next;