1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
23 #include <netinet/in.h>
27 #include "gdkprivate.h"
44 #include <X11/extensions/shape.h>
47 const int gdk_event_mask_table[20] =
51 PointerMotionHintMask,
56 ButtonPressMask | OwnerGrabButtonMask,
57 ButtonReleaseMask | OwnerGrabButtonMask,
68 SubstructureNotifyMask
70 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
72 /* Forward declarations */
73 static gboolean gdk_window_gravity_works (void);
74 static void gdk_window_set_static_win_gravity (GdkWindow *window,
76 static gboolean gdk_window_have_shape_ext (void);
78 /* internal function created for and used by gdk_window_xid_at_coords */
80 gdk_window_xid_at (Window base,
89 GdkWindowPrivate *private;
92 Window child = 0, parent_win = 0, root_win = 0;
94 unsigned int ww, wh, wb, wd, num;
97 window = (GdkWindow*) &gdk_root_parent;
98 private = (GdkWindowPrivate*) window;
99 disp = private->xdisplay;
100 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
107 (x < (int) (wx + ww)) &&
108 (y < (int) (wy + wh))))
111 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
116 for (i = num - 1; ; i--)
118 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
120 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
135 * The following fucntion by The Rasterman <raster@redhat.com>
136 * This function returns the X Window ID in which the x y location is in
137 * (x and y being relative to the root window), excluding any windows listed
138 * in the GList excludes (this is a list of X Window ID's - gpointer being
141 * This is primarily designed for internal gdk use - for DND for example
142 * when using a shaped icon window as the drag object - you exclude the
143 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
144 * You can get back an X Window ID as to what X Window ID is infact under
145 * those X,Y co-ordinates.
148 gdk_window_xid_at_coords (gint x,
154 GdkWindowPrivate *private;
157 Window root, child = 0, parent_win = 0, root_win = 0;
161 window = (GdkWindow*) &gdk_root_parent;
162 private = (GdkWindowPrivate*) window;
163 disp = private->xdisplay;
164 root = private->xwindow;
165 num = g_list_length (excludes);
168 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
170 XUngrabServer (disp);
178 XWindowAttributes xwa;
180 XGetWindowAttributes (disp, list [i], &xwa);
182 if (xwa.map_state != IsViewable)
185 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
188 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
193 if (!g_list_find (excludes, (gpointer *) child))
196 XUngrabServer (disp);
203 XUngrabServer (disp);
209 XUngrabServer (disp);
214 gdk_window_init (void)
216 XWindowAttributes xattributes;
219 unsigned int border_width;
223 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
224 &x, &y, &width, &height, &border_width, &depth);
225 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
227 gdk_root_parent.xwindow = gdk_root_window;
228 gdk_root_parent.xdisplay = gdk_display;
229 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
230 gdk_root_parent.window.user_data = NULL;
231 gdk_root_parent.width = width;
232 gdk_root_parent.height = height;
233 gdk_root_parent.children = NULL;
234 gdk_root_parent.colormap = NULL;
235 gdk_root_parent.ref_count = 1;
237 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
240 static GdkAtom wm_client_leader_atom = GDK_NONE;
243 gdk_window_new (GdkWindow *parent,
244 GdkWindowAttr *attributes,
245 gint attributes_mask)
248 GdkWindowPrivate *private;
249 GdkWindowPrivate *parent_private;
251 Display *parent_display;
254 XSetWindowAttributes xattributes;
255 long xattributes_mask;
256 XSizeHints size_hints;
258 XClassHint *class_hint;
264 g_return_val_if_fail (attributes != NULL, NULL);
267 parent = (GdkWindow*) &gdk_root_parent;
269 parent_private = (GdkWindowPrivate*) parent;
270 if (parent_private->destroyed)
273 xparent = parent_private->xwindow;
274 parent_display = parent_private->xdisplay;
276 private = g_new (GdkWindowPrivate, 1);
277 window = (GdkWindow*) private;
279 private->parent = parent;
281 private->xdisplay = parent_display;
282 private->destroyed = FALSE;
283 private->mapped = FALSE;
284 private->guffaw_gravity = FALSE;
285 private->resize_count = 0;
286 private->ref_count = 1;
287 xattributes_mask = 0;
289 if (attributes_mask & GDK_WA_X)
294 if (attributes_mask & GDK_WA_Y)
301 private->width = (attributes->width > 1) ? (attributes->width) : (1);
302 private->height = (attributes->height > 1) ? (attributes->height) : (1);
303 private->window_type = attributes->window_type;
304 private->extension_events = FALSE;
306 private->filters = NULL;
307 private->children = NULL;
309 window->user_data = NULL;
311 if (attributes_mask & GDK_WA_VISUAL)
312 visual = attributes->visual;
314 visual = gdk_visual_get_system ();
315 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
317 xattributes.event_mask = StructureNotifyMask;
318 for (i = 0; i < gdk_nevent_masks; i++)
320 if (attributes->event_mask & (1 << (i + 1)))
321 xattributes.event_mask |= gdk_event_mask_table[i];
324 if (xattributes.event_mask)
325 xattributes_mask |= CWEventMask;
327 if (attributes_mask & GDK_WA_NOREDIR)
329 xattributes.override_redirect =
330 (attributes->override_redirect == FALSE)?False:True;
331 xattributes_mask |= CWOverrideRedirect;
334 xattributes.override_redirect = False;
336 if (parent_private && parent_private->guffaw_gravity)
338 xattributes.win_gravity = StaticGravity;
339 xattributes_mask |= CWWinGravity;
342 if (attributes->wclass == GDK_INPUT_OUTPUT)
345 depth = visual->depth;
347 if (attributes_mask & GDK_WA_COLORMAP)
348 private->colormap = attributes->colormap;
351 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
352 private->colormap = gdk_colormap_get_system ();
354 private->colormap = gdk_colormap_new (visual, False);
357 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
358 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
359 xattributes_mask |= CWBorderPixel | CWBackPixel;
361 switch (private->window_type)
363 case GDK_WINDOW_TOPLEVEL:
364 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
365 xattributes_mask |= CWColormap;
367 xparent = gdk_root_window;
370 case GDK_WINDOW_CHILD:
371 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
372 xattributes_mask |= CWColormap;
375 case GDK_WINDOW_DIALOG:
376 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
377 xattributes_mask |= CWColormap;
379 xparent = gdk_root_window;
382 case GDK_WINDOW_TEMP:
383 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
384 xattributes_mask |= CWColormap;
386 xparent = gdk_root_window;
388 xattributes.save_under = True;
389 xattributes.override_redirect = True;
390 xattributes.cursor = None;
391 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
393 case GDK_WINDOW_ROOT:
394 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
396 case GDK_WINDOW_PIXMAP:
397 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
405 private->colormap = NULL;
408 private->xwindow = XCreateWindow (private->xdisplay, xparent,
409 x, y, private->width, private->height,
410 0, depth, class, xvisual,
411 xattributes_mask, &xattributes);
412 gdk_window_ref (window);
413 gdk_xid_table_insert (&private->xwindow, window);
415 if (private->colormap)
416 gdk_colormap_ref (private->colormap);
418 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
419 (attributes->cursor) :
423 parent_private->children = g_list_prepend (parent_private->children, window);
425 switch (private->window_type)
427 case GDK_WINDOW_DIALOG:
428 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
429 case GDK_WINDOW_TOPLEVEL:
430 case GDK_WINDOW_TEMP:
431 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
433 case GDK_WINDOW_CHILD:
434 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
435 (private->colormap != gdk_colormap_get_system ()) &&
436 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
438 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
439 gdk_window_add_colormap_windows (window);
448 size_hints.flags = PSize;
449 size_hints.width = private->width;
450 size_hints.height = private->height;
452 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
453 wm_hints.window_group = gdk_leader_window;
454 wm_hints.input = True;
455 wm_hints.initial_state = NormalState;
457 /* FIXME: Is there any point in doing this? Do any WM's pay
458 * attention to PSize, and even if they do, is this the
461 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
463 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
465 if (!wm_client_leader_atom)
466 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
468 XChangeProperty (private->xdisplay, private->xwindow,
469 wm_client_leader_atom,
470 XA_WINDOW, 32, PropModeReplace,
471 (guchar*) &gdk_leader_window, 1);
473 if (attributes_mask & GDK_WA_TITLE)
474 title = attributes->title;
476 title = g_get_prgname ();
478 XmbSetWMProperties (private->xdisplay, private->xwindow,
483 if (attributes_mask & GDK_WA_WMCLASS)
485 class_hint = XAllocClassHint ();
486 class_hint->res_name = attributes->wmclass_name;
487 class_hint->res_class = attributes->wmclass_class;
488 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
497 gdk_window_foreign_new (guint32 anid)
500 GdkWindowPrivate *private;
501 GdkWindowPrivate *parent_private;
502 XWindowAttributes attrs;
504 Window *children = NULL;
508 gdk_error_trap_push ();
509 result = XGetWindowAttributes (gdk_display, anid, &attrs);
510 if (gdk_error_trap_pop () || !result)
513 /* FIXME: This is pretty expensive. Maybe the caller should supply
515 gdk_error_trap_push ();
516 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
517 if (gdk_error_trap_pop () || !result)
520 private = g_new (GdkWindowPrivate, 1);
521 window = (GdkWindow*) private;
525 private->parent = gdk_xid_table_lookup (parent);
527 parent_private = (GdkWindowPrivate *)private->parent;
530 parent_private->children = g_list_prepend (parent_private->children, window);
532 private->xwindow = anid;
533 private->xdisplay = gdk_display;
534 private->x = attrs.x;
535 private->y = attrs.y;
536 private->width = attrs.width;
537 private->height = attrs.height;
538 private->resize_count = 0;
539 private->ref_count = 1;
540 private->window_type = GDK_WINDOW_FOREIGN;
541 private->destroyed = FALSE;
542 private->mapped = (attrs.map_state != IsUnmapped);
543 private->guffaw_gravity = FALSE;
544 private->extension_events = 0;
546 private->colormap = NULL;
548 private->filters = NULL;
549 private->children = NULL;
551 window->user_data = NULL;
553 gdk_window_ref (window);
554 gdk_xid_table_insert (&private->xwindow, window);
559 /* Call this function when you want a window and all its children to
560 * disappear. When xdestroy is true, a request to destroy the XWindow
561 * is sent out. When it is false, it is assumed that the XWindow has
562 * been or will be destroyed by destroying some ancestor of this
566 gdk_window_internal_destroy (GdkWindow *window,
568 gboolean our_destroy)
570 GdkWindowPrivate *private;
571 GdkWindowPrivate *temp_private;
572 GdkWindow *temp_window;
576 g_return_if_fail (window != NULL);
578 private = (GdkWindowPrivate*) window;
580 switch (private->window_type)
582 case GDK_WINDOW_TOPLEVEL:
583 case GDK_WINDOW_CHILD:
584 case GDK_WINDOW_DIALOG:
585 case GDK_WINDOW_TEMP:
586 case GDK_WINDOW_FOREIGN:
587 if (!private->destroyed)
591 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
592 if (parent_private->children)
593 parent_private->children = g_list_remove (parent_private->children, window);
596 if (private->window_type != GDK_WINDOW_FOREIGN)
598 children = tmp = private->children;
599 private->children = NULL;
603 temp_window = tmp->data;
606 temp_private = (GdkWindowPrivate*) temp_window;
608 gdk_window_internal_destroy (temp_window, FALSE,
612 g_list_free (children);
615 if (private->extension_events != 0)
616 gdk_input_window_destroy (window);
618 if (private->filters)
620 tmp = private->filters;
628 g_list_free (private->filters);
629 private->filters = NULL;
632 if (private->window_type == GDK_WINDOW_FOREIGN)
634 if (our_destroy && (private->parent != NULL))
636 /* It's somebody elses window, but in our heirarchy,
637 * so reparent it to the root window, and then send
638 * it a delete event, as if we were a WM
640 XClientMessageEvent xevent;
642 gdk_error_trap_push ();
643 gdk_window_hide (window);
644 gdk_window_reparent (window, NULL, 0, 0);
646 xevent.type = ClientMessage;
647 xevent.window = private->xwindow;
648 xevent.message_type = gdk_wm_protocols;
650 xevent.data.l[0] = gdk_wm_delete_window;
651 xevent.data.l[1] = CurrentTime;
653 XSendEvent (private->xdisplay, private->xwindow,
654 False, 0, (XEvent *)&xevent);
656 gdk_error_trap_pop ();
660 XDestroyWindow (private->xdisplay, private->xwindow);
662 if (private->colormap)
663 gdk_colormap_unref (private->colormap);
665 private->mapped = FALSE;
666 private->destroyed = TRUE;
670 case GDK_WINDOW_ROOT:
671 g_error ("attempted to destroy root window");
674 case GDK_WINDOW_PIXMAP:
675 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
680 /* Like internal_destroy, but also destroys the reference created by
684 gdk_window_destroy (GdkWindow *window)
686 gdk_window_internal_destroy (window, TRUE, TRUE);
687 gdk_window_unref (window);
690 /* This function is called when the XWindow is really gone. */
693 gdk_window_destroy_notify (GdkWindow *window)
695 GdkWindowPrivate *private;
697 g_return_if_fail (window != NULL);
699 private = (GdkWindowPrivate*) window;
701 if (!private->destroyed)
703 if (private->window_type == GDK_WINDOW_FOREIGN)
704 gdk_window_internal_destroy (window, FALSE, FALSE);
706 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
709 gdk_xid_table_remove (private->xwindow);
710 gdk_window_unref (window);
714 gdk_window_ref (GdkWindow *window)
716 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
717 g_return_val_if_fail (window != NULL, NULL);
719 private->ref_count += 1;
724 gdk_window_unref (GdkWindow *window)
726 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
727 g_return_if_fail (window != NULL);
729 private->ref_count -= 1;
730 if (private->ref_count == 0)
732 if (!private->destroyed)
734 if (private->window_type == GDK_WINDOW_FOREIGN)
735 gdk_xid_table_remove (private->xwindow);
737 g_warning ("losing last reference to undestroyed window\n");
739 g_dataset_destroy (window);
745 gdk_window_show (GdkWindow *window)
747 GdkWindowPrivate *private;
749 g_return_if_fail (window != NULL);
751 private = (GdkWindowPrivate*) window;
752 if (!private->destroyed)
754 private->mapped = TRUE;
755 XRaiseWindow (private->xdisplay, private->xwindow);
756 XMapWindow (private->xdisplay, private->xwindow);
761 gdk_window_hide (GdkWindow *window)
763 GdkWindowPrivate *private;
765 g_return_if_fail (window != NULL);
767 private = (GdkWindowPrivate*) window;
768 if (!private->destroyed)
770 private->mapped = FALSE;
771 XUnmapWindow (private->xdisplay, private->xwindow);
776 gdk_window_withdraw (GdkWindow *window)
778 GdkWindowPrivate *private;
780 g_return_if_fail (window != NULL);
782 private = (GdkWindowPrivate*) window;
783 if (!private->destroyed)
784 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
788 gdk_window_move (GdkWindow *window,
792 GdkWindowPrivate *private;
794 g_return_if_fail (window != NULL);
796 private = (GdkWindowPrivate*) window;
797 if (!private->destroyed)
799 XMoveWindow (private->xdisplay, private->xwindow, x, y);
801 if (private->window_type == GDK_WINDOW_CHILD)
810 gdk_window_resize (GdkWindow *window,
814 GdkWindowPrivate *private;
816 g_return_if_fail (window != NULL);
823 private = (GdkWindowPrivate*) window;
825 if (!private->destroyed &&
826 ((private->resize_count > 0) ||
827 (private->width != (guint16) width) ||
828 (private->height != (guint16) height)))
830 XResizeWindow (private->xdisplay, private->xwindow, width, height);
831 private->resize_count += 1;
833 if (private->window_type == GDK_WINDOW_CHILD)
835 private->width = width;
836 private->height = height;
842 gdk_window_move_resize (GdkWindow *window,
848 GdkWindowPrivate *private;
850 g_return_if_fail (window != NULL);
857 private = (GdkWindowPrivate*) window;
858 if (!private->destroyed)
860 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
862 if (private->guffaw_gravity)
864 GList *tmp_list = private->children;
867 GdkWindowPrivate *child_private = tmp_list->data;
869 child_private->x -= x - private->x;
870 child_private->y -= y - private->y;
872 tmp_list = tmp_list->next;
876 if (private->window_type == GDK_WINDOW_CHILD)
880 private->width = width;
881 private->height = height;
887 gdk_window_reparent (GdkWindow *window,
888 GdkWindow *new_parent,
892 GdkWindowPrivate *window_private;
893 GdkWindowPrivate *parent_private;
894 GdkWindowPrivate *old_parent_private;
896 g_return_if_fail (window != NULL);
899 new_parent = (GdkWindow*) &gdk_root_parent;
901 window_private = (GdkWindowPrivate*) window;
902 old_parent_private = (GdkWindowPrivate*)window_private->parent;
903 parent_private = (GdkWindowPrivate*) new_parent;
905 if (!window_private->destroyed && !parent_private->destroyed)
906 XReparentWindow (window_private->xdisplay,
907 window_private->xwindow,
908 parent_private->xwindow,
911 window_private->parent = new_parent;
913 if (old_parent_private)
914 old_parent_private->children = g_list_remove (old_parent_private->children, window);
916 if ((old_parent_private &&
917 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
918 (!old_parent_private && parent_private->guffaw_gravity))
919 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
921 parent_private->children = g_list_prepend (parent_private->children, window);
925 gdk_window_clear (GdkWindow *window)
927 GdkWindowPrivate *private;
929 g_return_if_fail (window != NULL);
931 private = (GdkWindowPrivate*) window;
933 if (!private->destroyed)
934 XClearWindow (private->xdisplay, private->xwindow);
938 gdk_window_clear_area (GdkWindow *window,
944 GdkWindowPrivate *private;
946 g_return_if_fail (window != NULL);
948 private = (GdkWindowPrivate*) window;
950 if (!private->destroyed)
951 XClearArea (private->xdisplay, private->xwindow,
952 x, y, width, height, False);
956 gdk_window_clear_area_e (GdkWindow *window,
962 GdkWindowPrivate *private;
964 g_return_if_fail (window != NULL);
966 private = (GdkWindowPrivate*) window;
968 if (!private->destroyed)
969 XClearArea (private->xdisplay, private->xwindow,
970 x, y, width, height, True);
974 gdk_window_copy_area (GdkWindow *window,
978 GdkWindow *source_window,
984 GdkWindowPrivate *src_private;
985 GdkWindowPrivate *dest_private;
986 GdkGCPrivate *gc_private;
988 g_return_if_fail (window != NULL);
989 g_return_if_fail (gc != NULL);
991 if (source_window == NULL)
992 source_window = window;
994 src_private = (GdkWindowPrivate*) source_window;
995 dest_private = (GdkWindowPrivate*) window;
996 gc_private = (GdkGCPrivate*) gc;
998 if (!src_private->destroyed && !dest_private->destroyed)
1000 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
1009 gdk_window_raise (GdkWindow *window)
1011 GdkWindowPrivate *private;
1013 g_return_if_fail (window != NULL);
1015 private = (GdkWindowPrivate*) window;
1017 if (!private->destroyed)
1018 XRaiseWindow (private->xdisplay, private->xwindow);
1022 gdk_window_lower (GdkWindow *window)
1024 GdkWindowPrivate *private;
1026 g_return_if_fail (window != NULL);
1028 private = (GdkWindowPrivate*) window;
1030 if (!private->destroyed)
1031 XLowerWindow (private->xdisplay, private->xwindow);
1035 gdk_window_set_user_data (GdkWindow *window,
1038 g_return_if_fail (window != NULL);
1040 window->user_data = user_data;
1044 gdk_window_set_hints (GdkWindow *window,
1053 GdkWindowPrivate *private;
1054 XSizeHints size_hints;
1056 g_return_if_fail (window != NULL);
1058 private = (GdkWindowPrivate*) window;
1059 if (private->destroyed)
1062 size_hints.flags = 0;
1064 if (flags & GDK_HINT_POS)
1066 size_hints.flags |= PPosition;
1071 if (flags & GDK_HINT_MIN_SIZE)
1073 size_hints.flags |= PMinSize;
1074 size_hints.min_width = min_width;
1075 size_hints.min_height = min_height;
1078 if (flags & GDK_HINT_MAX_SIZE)
1080 size_hints.flags |= PMaxSize;
1081 size_hints.max_width = max_width;
1082 size_hints.max_height = max_height;
1086 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1090 gdk_window_set_geometry_hints (GdkWindow *window,
1091 GdkGeometry *geometry,
1092 GdkWindowHints geom_mask)
1094 GdkWindowPrivate *private;
1095 XSizeHints size_hints;
1097 g_return_if_fail (window != NULL);
1099 private = (GdkWindowPrivate*) window;
1100 if (private->destroyed)
1103 size_hints.flags = 0;
1105 if (geom_mask & GDK_HINT_POS)
1106 size_hints.flags |= PPosition;
1108 if (geom_mask & GDK_HINT_MIN_SIZE)
1110 size_hints.flags |= PMinSize;
1111 size_hints.min_width = geometry->min_width;
1112 size_hints.min_height = geometry->min_height;
1115 if (geom_mask & GDK_HINT_MAX_SIZE)
1117 size_hints.flags |= PMaxSize;
1118 size_hints.max_width = geometry->max_width;
1119 size_hints.max_height = geometry->max_height;
1122 if (geom_mask & GDK_HINT_BASE_SIZE)
1124 size_hints.flags |= PBaseSize;
1125 size_hints.base_width = geometry->base_width;
1126 size_hints.base_height = geometry->base_height;
1129 if (geom_mask & GDK_HINT_RESIZE_INC)
1131 size_hints.flags |= PResizeInc;
1132 size_hints.width_inc = geometry->width_inc;
1133 size_hints.height_inc = geometry->height_inc;
1136 if (geom_mask & GDK_HINT_ASPECT)
1138 size_hints.flags |= PAspect;
1139 if (geometry->min_aspect <= 1)
1141 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1142 size_hints.min_aspect.y = G_MAXINT;
1146 size_hints.min_aspect.x = G_MAXINT;
1147 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1149 if (geometry->max_aspect <= 1)
1151 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1152 size_hints.max_aspect.y = G_MAXINT;
1156 size_hints.max_aspect.x = G_MAXINT;
1157 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1162 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1166 gdk_window_set_title (GdkWindow *window,
1169 GdkWindowPrivate *private;
1171 g_return_if_fail (window != NULL);
1173 private = (GdkWindowPrivate*) window;
1174 if (!private->destroyed)
1175 XmbSetWMProperties (private->xdisplay, private->xwindow,
1176 title, title, NULL, 0, NULL, NULL, NULL);
1180 gdk_window_set_role (GdkWindow *window,
1183 GdkWindowPrivate *private;
1185 g_return_if_fail (window != NULL);
1187 private = (GdkWindowPrivate*) window;
1190 XChangeProperty (private->xdisplay, private->xwindow,
1191 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1192 8, PropModeReplace, role, strlen (role));
1194 XDeleteProperty (private->xdisplay, private->xwindow,
1195 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1199 gdk_window_set_transient_for (GdkWindow *window,
1202 GdkWindowPrivate *private;
1203 GdkWindowPrivate *parent_private;
1205 g_return_if_fail (window != NULL);
1207 private = (GdkWindowPrivate*) window;
1208 parent_private = (GdkWindowPrivate*) parent;
1210 if (!private->destroyed && !parent_private->destroyed)
1211 XSetTransientForHint (private->xdisplay,
1212 private->xwindow, parent_private->xwindow);
1216 gdk_window_set_background (GdkWindow *window,
1219 GdkWindowPrivate *private;
1221 g_return_if_fail (window != NULL);
1223 private = (GdkWindowPrivate*) window;
1224 if (!private->destroyed)
1225 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1229 gdk_window_set_back_pixmap (GdkWindow *window,
1231 gint parent_relative)
1233 GdkWindowPrivate *window_private;
1234 GdkPixmapPrivate *pixmap_private;
1237 g_return_if_fail (window != NULL);
1239 window_private = (GdkWindowPrivate*) window;
1240 pixmap_private = (GdkPixmapPrivate*) pixmap;
1243 xpixmap = pixmap_private->xwindow;
1247 if (parent_relative)
1248 xpixmap = ParentRelative;
1250 if (!window_private->destroyed)
1251 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1255 gdk_window_set_cursor (GdkWindow *window,
1258 GdkWindowPrivate *window_private;
1259 GdkCursorPrivate *cursor_private;
1262 g_return_if_fail (window != NULL);
1264 window_private = (GdkWindowPrivate*) window;
1265 cursor_private = (GdkCursorPrivate*) cursor;
1270 xcursor = cursor_private->xcursor;
1272 if (!window_private->destroyed)
1273 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1277 gdk_window_set_colormap (GdkWindow *window,
1278 GdkColormap *colormap)
1280 GdkWindowPrivate *window_private;
1281 GdkColormapPrivate *colormap_private;
1283 g_return_if_fail (window != NULL);
1284 g_return_if_fail (colormap != NULL);
1286 window_private = (GdkWindowPrivate*) window;
1287 colormap_private = (GdkColormapPrivate*) colormap;
1289 if (!window_private->destroyed)
1291 XSetWindowColormap (window_private->xdisplay,
1292 window_private->xwindow,
1293 colormap_private->xcolormap);
1295 if (window_private->colormap)
1296 gdk_colormap_unref (window_private->colormap);
1297 window_private->colormap = colormap;
1298 gdk_colormap_ref (window_private->colormap);
1300 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1301 gdk_window_add_colormap_windows (window);
1306 gdk_window_get_user_data (GdkWindow *window,
1309 g_return_if_fail (window != NULL);
1311 *data = window->user_data;
1315 gdk_window_get_geometry (GdkWindow *window,
1322 GdkWindowPrivate *window_private;
1328 guint tborder_width;
1332 window = (GdkWindow*) &gdk_root_parent;
1334 window_private = (GdkWindowPrivate*) window;
1336 if (!window_private->destroyed)
1338 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1339 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1355 gdk_window_get_position (GdkWindow *window,
1359 GdkWindowPrivate *window_private;
1361 g_return_if_fail (window != NULL);
1363 window_private = (GdkWindowPrivate*) window;
1366 *x = window_private->x;
1368 *y = window_private->y;
1372 gdk_window_get_size (GdkWindow *window,
1376 GdkWindowPrivate *window_private;
1378 g_return_if_fail (window != NULL);
1380 window_private = (GdkWindowPrivate*) window;
1383 *width = window_private->width;
1385 *height = window_private->height;
1389 gdk_window_get_visual (GdkWindow *window)
1391 GdkWindowPrivate *window_private;
1392 XWindowAttributes window_attributes;
1394 g_return_val_if_fail (window != NULL, NULL);
1396 window_private = (GdkWindowPrivate*) window;
1397 /* Huh? ->parent is never set for a pixmap. We should just return
1400 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1401 window_private = (GdkWindowPrivate*) window_private->parent;
1403 if (window_private && !window_private->destroyed)
1405 if (window_private->colormap == NULL)
1407 XGetWindowAttributes (window_private->xdisplay,
1408 window_private->xwindow,
1409 &window_attributes);
1410 return gdk_visual_lookup (window_attributes.visual);
1413 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1420 gdk_window_get_colormap (GdkWindow *window)
1422 GdkWindowPrivate *window_private;
1423 XWindowAttributes window_attributes;
1425 g_return_val_if_fail (window != NULL, NULL);
1426 window_private = (GdkWindowPrivate*) window;
1428 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1429 if (!window_private->destroyed)
1431 if (window_private->colormap == NULL)
1433 XGetWindowAttributes (window_private->xdisplay,
1434 window_private->xwindow,
1435 &window_attributes);
1436 return gdk_colormap_lookup (window_attributes.colormap);
1439 return window_private->colormap;
1446 gdk_window_get_type (GdkWindow *window)
1448 GdkWindowPrivate *window_private;
1450 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1452 window_private = (GdkWindowPrivate*) window;
1453 return window_private->window_type;
1457 gdk_window_get_origin (GdkWindow *window,
1461 GdkWindowPrivate *private;
1467 g_return_val_if_fail (window != NULL, 0);
1469 private = (GdkWindowPrivate*) window;
1471 if (!private->destroyed)
1473 return_val = XTranslateCoordinates (private->xdisplay,
1492 gdk_window_get_deskrelative_origin (GdkWindow *window,
1496 GdkWindowPrivate *private;
1497 gboolean return_val = FALSE;
1498 gint num_children, format_return;
1499 Window win, *child, parent, root;
1503 static Atom atom = 0;
1504 gulong number_return, bytes_after_return;
1505 guchar *data_return;
1507 g_return_val_if_fail (window != NULL, 0);
1509 private = (GdkWindowPrivate*) window;
1511 if (!private->destroyed)
1514 atom = XInternAtom (private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1515 win = private->xwindow;
1517 while (XQueryTree (private->xdisplay, win, &root, &parent,
1518 &child, (unsigned int *)&num_children))
1520 if ((child) && (num_children > 0))
1532 XGetWindowProperty (private->xdisplay, win, atom, 0, 0,
1533 False, XA_CARDINAL, &type_return, &format_return,
1534 &number_return, &bytes_after_return, &data_return);
1535 if (type_return == XA_CARDINAL)
1537 XFree (data_return);
1542 return_val = XTranslateCoordinates (private->xdisplay,
1558 gdk_window_get_root_origin (GdkWindow *window,
1562 GdkWindowPrivate *private;
1567 unsigned int nchildren;
1569 g_return_if_fail (window != NULL);
1571 private = (GdkWindowPrivate*) window;
1576 if (private->destroyed)
1579 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1580 private = (GdkWindowPrivate*) private->parent;
1581 if (private->destroyed)
1584 xparent = private->xwindow;
1588 if (!XQueryTree (private->xdisplay, xwindow,
1590 &children, &nchildren))
1596 while (xparent != root);
1598 if (xparent == root)
1600 unsigned int ww, wh, wb, wd;
1603 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1614 gdk_window_get_pointer (GdkWindow *window,
1617 GdkModifierType *mask)
1619 GdkWindowPrivate *private;
1620 GdkWindow *return_val;
1626 unsigned int xmask = 0;
1629 window = (GdkWindow*) &gdk_root_parent;
1631 private = (GdkWindowPrivate*) window;
1634 if (!private->destroyed &&
1635 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1636 &rootx, &rooty, &winx, &winy, &xmask))
1639 return_val = gdk_window_lookup (child);
1653 gdk_window_at_pointer (gint *win_x,
1656 GdkWindowPrivate *private;
1660 Window xwindow_last = 0;
1661 int rootx = -1, rooty = -1;
1665 private = &gdk_root_parent;
1667 xwindow = private->xwindow;
1669 XGrabServer (private->xdisplay);
1672 xwindow_last = xwindow;
1673 XQueryPointer (private->xdisplay,
1680 XUngrabServer (private->xdisplay);
1682 window = gdk_window_lookup (xwindow_last);
1685 *win_x = window ? winx : -1;
1687 *win_y = window ? winy : -1;
1693 gdk_window_get_parent (GdkWindow *window)
1695 g_return_val_if_fail (window != NULL, NULL);
1697 return ((GdkWindowPrivate*) window)->parent;
1701 gdk_window_get_toplevel (GdkWindow *window)
1703 GdkWindowPrivate *private;
1705 g_return_val_if_fail (window != NULL, NULL);
1707 private = (GdkWindowPrivate*) window;
1709 while (private->window_type == GDK_WINDOW_CHILD)
1711 window = ((GdkWindowPrivate*) window)->parent;
1712 private = (GdkWindowPrivate*) window;
1719 gdk_window_get_children (GdkWindow *window)
1721 GdkWindowPrivate *private;
1727 unsigned int nchildren;
1730 g_return_val_if_fail (window != NULL, NULL);
1732 private = (GdkWindowPrivate*) window;
1733 if (private->destroyed)
1736 XQueryTree (private->xdisplay, private->xwindow,
1737 &root, &parent, &xchildren, &nchildren);
1743 for (i = 0; i < nchildren; i++)
1745 child = gdk_window_lookup (xchildren[i]);
1747 children = g_list_prepend (children, child);
1758 gdk_window_get_events (GdkWindow *window)
1760 GdkWindowPrivate *private;
1761 XWindowAttributes attrs;
1762 GdkEventMask event_mask;
1765 g_return_val_if_fail (window != NULL, 0);
1767 private = (GdkWindowPrivate*) window;
1768 if (private->destroyed)
1771 XGetWindowAttributes (gdk_display, private->xwindow,
1775 for (i = 0; i < gdk_nevent_masks; i++)
1777 if (attrs.your_event_mask & gdk_event_mask_table[i])
1778 event_mask |= 1 << (i + 1);
1785 gdk_window_set_events (GdkWindow *window,
1786 GdkEventMask event_mask)
1788 GdkWindowPrivate *private;
1792 g_return_if_fail (window != NULL);
1794 private = (GdkWindowPrivate*) window;
1795 if (private->destroyed)
1798 xevent_mask = StructureNotifyMask;
1799 for (i = 0; i < gdk_nevent_masks; i++)
1801 if (event_mask & (1 << (i + 1)))
1802 xevent_mask |= gdk_event_mask_table[i];
1805 XSelectInput (gdk_display, private->xwindow,
1810 gdk_window_add_colormap_windows (GdkWindow *window)
1812 GdkWindow *toplevel;
1813 GdkWindowPrivate *toplevel_private;
1814 GdkWindowPrivate *window_private;
1815 Window *old_windows;
1816 Window *new_windows;
1819 g_return_if_fail (window != NULL);
1821 toplevel = gdk_window_get_toplevel (window);
1822 toplevel_private = (GdkWindowPrivate*) toplevel;
1823 window_private = (GdkWindowPrivate*) window;
1824 if (window_private->destroyed)
1828 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1829 toplevel_private->xwindow,
1830 &old_windows, &count))
1835 for (i = 0; i < count; i++)
1836 if (old_windows[i] == window_private->xwindow)
1838 XFree (old_windows);
1842 new_windows = g_new (Window, count + 1);
1844 for (i = 0; i < count; i++)
1845 new_windows[i] = old_windows[i];
1846 new_windows[count] = window_private->xwindow;
1848 XSetWMColormapWindows (toplevel_private->xdisplay,
1849 toplevel_private->xwindow,
1850 new_windows, count + 1);
1852 g_free (new_windows);
1854 XFree (old_windows);
1858 gdk_window_have_shape_ext (void)
1860 enum { UNKNOWN, NO, YES };
1861 static gint have_shape = UNKNOWN;
1863 if (have_shape == UNKNOWN)
1866 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1872 return (have_shape == YES);
1876 * This needs the X11 shape extension.
1877 * If not available, shaped windows will look
1878 * ugly, but programs still work. Stefan Wille
1881 gdk_window_shape_combine_mask (GdkWindow *window,
1885 GdkWindowPrivate *window_private;
1888 g_return_if_fail (window != NULL);
1890 #ifdef HAVE_SHAPE_EXT
1891 window_private = (GdkWindowPrivate*) window;
1892 if (window_private->destroyed)
1895 if (gdk_window_have_shape_ext ())
1899 GdkWindowPrivate *pixmap_private;
1901 pixmap_private = (GdkWindowPrivate*) mask;
1902 pixmap = (Pixmap) pixmap_private->xwindow;
1911 XShapeCombineMask (window_private->xdisplay,
1912 window_private->xwindow,
1918 #endif /* HAVE_SHAPE_EXT */
1922 gdk_window_add_filter (GdkWindow *window,
1923 GdkFilterFunc function,
1926 GdkWindowPrivate *private;
1928 GdkEventFilter *filter;
1930 private = (GdkWindowPrivate*) window;
1931 if (private && private->destroyed)
1935 tmp_list = private->filters;
1937 tmp_list = gdk_default_filters;
1941 filter = (GdkEventFilter *)tmp_list->data;
1942 if ((filter->function == function) && (filter->data == data))
1944 tmp_list = tmp_list->next;
1947 filter = g_new (GdkEventFilter, 1);
1948 filter->function = function;
1949 filter->data = data;
1952 private->filters = g_list_append (private->filters, filter);
1954 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1958 gdk_window_remove_filter (GdkWindow *window,
1959 GdkFilterFunc function,
1962 GdkWindowPrivate *private;
1963 GList *tmp_list, *node;
1964 GdkEventFilter *filter;
1966 private = (GdkWindowPrivate*) window;
1969 tmp_list = private->filters;
1971 tmp_list = gdk_default_filters;
1975 filter = (GdkEventFilter *)tmp_list->data;
1977 tmp_list = tmp_list->next;
1979 if ((filter->function == function) && (filter->data == data))
1982 private->filters = g_list_remove_link (private->filters, node);
1984 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1985 g_list_free_1 (node);
1994 gdk_window_set_override_redirect (GdkWindow *window,
1995 gboolean override_redirect)
1997 GdkWindowPrivate *private;
1998 XSetWindowAttributes attr;
2000 g_return_if_fail (window != NULL);
2001 private = (GdkWindowPrivate*) window;
2002 if (private->destroyed)
2005 attr.override_redirect = (override_redirect == FALSE)?False:True;
2006 XChangeWindowAttributes (gdk_display,
2007 ((GdkWindowPrivate *)window)->xwindow,
2013 gdk_window_set_icon (GdkWindow *window,
2014 GdkWindow *icon_window,
2019 GdkWindowPrivate *window_private;
2020 GdkWindowPrivate *private;
2022 g_return_if_fail (window != NULL);
2023 window_private = (GdkWindowPrivate*) window;
2024 if (window_private->destroyed)
2027 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2029 wm_hints = XAllocWMHints ();
2031 if (icon_window != NULL)
2033 private = (GdkWindowPrivate *)icon_window;
2034 wm_hints->flags |= IconWindowHint;
2035 wm_hints->icon_window = private->xwindow;
2040 private = (GdkWindowPrivate *)pixmap;
2041 wm_hints->flags |= IconPixmapHint;
2042 wm_hints->icon_pixmap = private->xwindow;
2047 private = (GdkWindowPrivate *)mask;
2048 wm_hints->flags |= IconMaskHint;
2049 wm_hints->icon_mask = private->xwindow;
2052 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2057 gdk_window_set_icon_name (GdkWindow *window,
2060 GdkWindowPrivate *window_private;
2061 XTextProperty property;
2064 g_return_if_fail (window != NULL);
2065 window_private = (GdkWindowPrivate*) window;
2066 if (window_private->destroyed)
2068 res = XmbTextListToTextProperty (window_private->xdisplay,
2069 &name, 1, XStdICCTextStyle,
2073 g_warning ("Error converting icon name to text property: %d\n", res);
2077 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2081 XFree (property.value);
2085 gdk_window_set_group (GdkWindow *window,
2089 GdkWindowPrivate *window_private;
2090 GdkWindowPrivate *private;
2092 g_return_if_fail (window != NULL);
2093 g_return_if_fail (leader != NULL);
2094 window_private = (GdkWindowPrivate*) window;
2095 if (window_private->destroyed)
2098 private = (GdkWindowPrivate *)leader;
2100 wm_hints = XGetWMHints (window_private->xdisplay, window_private->xwindow);
2102 wm_hints = XAllocWMHints ();
2104 wm_hints->flags |= WindowGroupHint;
2105 wm_hints->window_group = private->xwindow;
2107 XSetWMHints (window_private->xdisplay, window_private->xwindow, wm_hints);
2112 gdk_window_set_mwm_hints (GdkWindow *window,
2113 MotifWmHints *new_hints)
2115 static Atom hints_atom = None;
2116 MotifWmHints *hints;
2122 GdkWindowPrivate *window_private;
2124 g_return_if_fail (window != NULL);
2125 window_private = (GdkWindowPrivate*) window;
2126 if (window_private->destroyed)
2130 hints_atom = XInternAtom (window_private->xdisplay,
2131 _XA_MOTIF_WM_HINTS, FALSE);
2133 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2134 hints_atom, 0, sizeof (MotifWmHints)/4,
2135 False, AnyPropertyType, &type, &format, &nitems,
2136 &bytes_after, (guchar **)&hints);
2142 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2144 hints->flags |= MWM_HINTS_FUNCTIONS;
2145 hints->functions = new_hints->functions;
2147 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2149 hints->flags |= MWM_HINTS_DECORATIONS;
2150 hints->decorations = new_hints->decorations;
2154 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2155 hints_atom, hints_atom, 32, PropModeReplace,
2156 (guchar *)hints, sizeof (MotifWmHints)/4);
2158 if (hints != new_hints)
2163 gdk_window_set_decorations (GdkWindow *window,
2164 GdkWMDecoration decorations)
2168 hints.flags = MWM_HINTS_DECORATIONS;
2169 hints.decorations = decorations;
2171 gdk_window_set_mwm_hints (window, &hints);
2175 gdk_window_set_functions (GdkWindow *window,
2176 GdkWMFunction functions)
2180 hints.flags = MWM_HINTS_FUNCTIONS;
2181 hints.functions = functions;
2183 gdk_window_set_mwm_hints (window, &hints);
2187 gdk_window_get_toplevels (void)
2189 GList *new_list = NULL;
2192 tmp_list = gdk_root_parent.children;
2195 new_list = g_list_prepend (new_list, tmp_list->data);
2196 tmp_list = tmp_list->next;
2203 * propagate the shapes from all child windows of a GDK window to the parent
2204 * window. Shamelessly ripped from Enlightenment's code
2213 struct _gdk_span *next;
2217 gdk_add_to_span (struct _gdk_span **s,
2221 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2228 /* scan the spans for this line */
2231 /* -- -> new span */
2232 /* == -> existing span */
2233 /* ## -> spans intersect */
2234 /* if we are in the middle of spanning the span into the line */
2237 /* case: ---- ==== */
2238 if (xx < ptr1->start - 1)
2240 /* ends before next span - extend to here */
2244 /* case: ----##=== */
2245 else if (xx <= ptr1->end)
2247 /* crosses into next span - delete next span and append */
2248 ss->end = ptr1->end;
2249 ss->next = ptr1->next;
2253 /* case: ---###--- */
2256 /* overlaps next span - delete and keep checking */
2257 ss->next = ptr1->next;
2262 /* otherwise havent started spanning it in yet */
2265 /* case: ---- ==== */
2266 if (xx < ptr1->start - 1)
2268 /* insert span here in list */
2269 noo = g_malloc (sizeof (struct _gdk_span));
2283 /* case: ----##=== */
2284 else if ((x < ptr1->start) && (xx <= ptr1->end))
2286 /* expand this span to the left point of the new one */
2290 /* case: ===###=== */
2291 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2293 /* throw the span away */
2296 /* case: ---###--- */
2297 else if ((x < ptr1->start) && (xx > ptr1->end))
2304 /* case: ===##---- */
2305 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2311 /* case: ==== ---- */
2312 /* case handled by next loop iteration - first case */
2317 /* it started in the middle but spans beyond your current list */
2323 /* it does not start inside a span or in the middle, so add it to the end */
2324 noo = g_malloc (sizeof (struct _gdk_span));
2332 noo->next = ptr2->next;
2345 gdk_add_rectangles (Display *disp,
2347 struct _gdk_span **spans,
2354 gint x1, y1, x2, y2;
2358 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2361 /* go through all clip rects in this window's shape */
2362 for (k = 0; k < rn; k++)
2364 /* for each clip rect, add it to each line's spans */
2366 x2 = x + rl[k].x + (rl[k].width - 1);
2368 y2 = y + rl[k].y + (rl[k].height - 1);
2377 for (a = y1; a <= y2; a++)
2380 gdk_add_to_span (&spans[a], x1, x2);
2388 gdk_propagate_shapes (Display *disp,
2392 Window rt, par, *list = NULL;
2393 gint i, j, num = 0, num_rects = 0;
2397 XRectangle *rects = NULL;
2398 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2399 XWindowAttributes xatt;
2401 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2406 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2408 for (i = 0; i < h; i++)
2410 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2413 /* go through all child windows and create/insert spans */
2414 for (i = 0; i < num; i++)
2416 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2417 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2418 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2421 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2423 /* go through the spans list and build a list of rects */
2424 rects = g_malloc (sizeof (XRectangle) * 256);
2426 for (i = 0; i < baseh; i++)
2429 /* go through the line for all spans */
2432 rects[num_rects].x = ptr1->start;
2433 rects[num_rects].y = i;
2434 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2435 rects[num_rects].height = 1;
2437 /* if there are more lines */
2439 /* while contigous rects (same start/end coords) exist */
2440 while ((contig) && (j < baseh))
2442 /* search next line for spans matching this one */
2448 /* if we have an exact span match set contig */
2449 if ((ptr2->start == ptr1->start) &&
2450 (ptr2->end == ptr1->end))
2453 /* remove the span - not needed */
2456 ptr3->next = ptr2->next;
2462 spans[j] = ptr2->next;
2468 /* gone past the span point no point looking */
2469 else if (ptr2->start < ptr1->start)
2477 /* if a contiguous span was found increase the rect h */
2480 rects[num_rects].height++;
2484 /* up the rect count */
2486 /* every 256 new rects increase the rect array */
2487 if ((num_rects % 256) == 0)
2488 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2492 /* set the rects as the shape mask */
2495 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2496 ShapeSet, YXSorted);
2501 /* free up all the spans we made */
2502 for (i = 0; i < baseh; i++)
2516 gdk_window_set_child_shapes (GdkWindow *window)
2518 GdkWindowPrivate *private;
2520 g_return_if_fail (window != NULL);
2522 #ifdef HAVE_SHAPE_EXT
2523 private = (GdkWindowPrivate*) window;
2524 if (private->destroyed)
2527 if (gdk_window_have_shape_ext ())
2528 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2533 gdk_window_merge_child_shapes (GdkWindow *window)
2535 GdkWindowPrivate *private;
2537 g_return_if_fail (window != NULL);
2539 #ifdef HAVE_SHAPE_EXT
2540 private = (GdkWindowPrivate*) window;
2541 if (private->destroyed)
2544 if (gdk_window_have_shape_ext ())
2545 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2549 /*************************************************************
2550 * gdk_window_is_visible:
2551 * Check if the given window is mapped.
2555 * is the window mapped
2556 *************************************************************/
2559 gdk_window_is_visible (GdkWindow *window)
2561 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2563 g_return_val_if_fail (window != NULL, FALSE);
2565 return private->mapped;
2568 /*************************************************************
2569 * gdk_window_is_viewable:
2570 * Check if the window and all ancestors of the window
2571 * are mapped. (This is not necessarily "viewable" in
2572 * the X sense, since we only check as far as we have
2573 * GDK window parents, not to the root window)
2577 * is the window viewable
2578 *************************************************************/
2581 gdk_window_is_viewable (GdkWindow *window)
2583 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2585 g_return_val_if_fail (window != NULL, FALSE);
2588 (private != &gdk_root_parent) &&
2589 (private->window_type != GDK_WINDOW_FOREIGN))
2591 if (!private->mapped)
2594 private = (GdkWindowPrivate *)private->parent;
2601 gdk_drawable_set_data (GdkDrawable *drawable,
2604 GDestroyNotify destroy_func)
2606 g_dataset_set_data_full (drawable, key, data, destroy_func);
2610 /* Support for windows that can be guffaw-scrolled
2611 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2615 gdk_window_gravity_works (void)
2617 enum { UNKNOWN, NO, YES };
2618 static gint gravity_works = UNKNOWN;
2620 if (gravity_works == UNKNOWN)
2627 /* This particular server apparently has a bug so that the test
2628 * works but the actual code crashes it
2630 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2631 (VendorRelease (gdk_display) == 3400))
2637 attr.window_type = GDK_WINDOW_TEMP;
2638 attr.wclass = GDK_INPUT_OUTPUT;
2643 attr.event_mask = 0;
2645 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2647 attr.window_type = GDK_WINDOW_CHILD;
2648 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2650 gdk_window_set_static_win_gravity (child, TRUE);
2652 gdk_window_resize (parent, 100, 110);
2653 gdk_window_move (parent, 0, -10);
2654 gdk_window_move_resize (parent, 0, 0, 100, 100);
2656 gdk_window_resize (parent, 100, 110);
2657 gdk_window_move (parent, 0, -10);
2658 gdk_window_move_resize (parent, 0, 0, 100, 100);
2660 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2662 gdk_window_destroy (parent);
2663 gdk_window_destroy (child);
2665 gravity_works = ((y == -20) ? YES : NO);
2668 return (gravity_works == YES);
2672 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2674 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2675 XSetWindowAttributes xattributes;
2677 g_return_if_fail (window != NULL);
2679 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2680 XChangeWindowAttributes (private->xdisplay,
2682 CWBitGravity, &xattributes);
2686 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2688 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2689 XSetWindowAttributes xattributes;
2691 g_return_if_fail (window != NULL);
2693 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2695 XChangeWindowAttributes (private->xdisplay,
2697 CWWinGravity, &xattributes);
2700 /*************************************************************
2701 * gdk_window_set_static_gravities:
2702 * Set the bit gravity of the given window to static,
2703 * and flag it so all children get static subwindow
2706 * window: window for which to set static gravity
2707 * use_static: Whether to turn static gravity on or off.
2709 * Does the XServer support static gravity?
2710 *************************************************************/
2713 gdk_window_set_static_gravities (GdkWindow *window,
2714 gboolean use_static)
2716 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2719 g_return_val_if_fail (window != NULL, FALSE);
2721 if (!use_static == !private->guffaw_gravity)
2724 if (use_static && !gdk_window_gravity_works ())
2727 private->guffaw_gravity = use_static;
2729 gdk_window_set_static_bit_gravity (window, use_static);
2731 tmp_list = private->children;
2734 gdk_window_set_static_win_gravity (window, use_static);
2736 tmp_list = tmp_list->next;