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;
507 if (!XGetWindowAttributes (gdk_display, anid, &attrs)) {
508 g_warning ("XGetWindowAttributes failed on window ID %d\n", anid);
512 private = g_new (GdkWindowPrivate, 1);
513 window = (GdkWindow*) private;
515 /* FIXME: This is pretty expensive. Maybe the caller should supply
517 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
521 private->parent = gdk_xid_table_lookup (parent);
523 parent_private = (GdkWindowPrivate *)private->parent;
526 parent_private->children = g_list_prepend (parent_private->children, window);
528 private->xwindow = anid;
529 private->xdisplay = gdk_display;
530 private->x = attrs.x;
531 private->y = attrs.y;
532 private->width = attrs.width;
533 private->height = attrs.height;
534 private->resize_count = 0;
535 private->ref_count = 1;
536 private->window_type = GDK_WINDOW_FOREIGN;
537 private->destroyed = FALSE;
538 private->mapped = (attrs.map_state != IsUnmapped);
539 private->guffaw_gravity = FALSE;
540 private->extension_events = 0;
542 private->colormap = NULL;
544 private->filters = NULL;
545 private->children = NULL;
547 window->user_data = NULL;
549 gdk_window_ref (window);
550 gdk_xid_table_insert (&private->xwindow, window);
555 /* Call this function when you want a window and all its children to
556 * disappear. When xdestroy is true, a request to destroy the XWindow
557 * is sent out. When it is false, it is assumed that the XWindow has
558 * been or will be destroyed by destroying some ancestor of this
562 gdk_window_internal_destroy (GdkWindow *window,
564 gboolean our_destroy)
566 GdkWindowPrivate *private;
567 GdkWindowPrivate *temp_private;
568 GdkWindow *temp_window;
572 g_return_if_fail (window != NULL);
574 private = (GdkWindowPrivate*) window;
576 switch (private->window_type)
578 case GDK_WINDOW_TOPLEVEL:
579 case GDK_WINDOW_CHILD:
580 case GDK_WINDOW_DIALOG:
581 case GDK_WINDOW_TEMP:
582 case GDK_WINDOW_FOREIGN:
583 if (!private->destroyed)
587 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
588 if (parent_private->children)
589 parent_private->children = g_list_remove (parent_private->children, window);
592 if (private->window_type != GDK_WINDOW_FOREIGN)
594 children = tmp = private->children;
595 private->children = NULL;
599 temp_window = tmp->data;
602 temp_private = (GdkWindowPrivate*) temp_window;
604 gdk_window_internal_destroy (temp_window, FALSE,
608 g_list_free (children);
611 if (private->extension_events != 0)
612 gdk_input_window_destroy (window);
614 if (private->filters)
616 tmp = private->filters;
624 g_list_free (private->filters);
625 private->filters = NULL;
628 if (private->window_type == GDK_WINDOW_FOREIGN)
630 if (our_destroy && (private->parent != NULL))
632 /* It's somebody elses window, but in our heirarchy,
633 * so reparent it to the root window, and then send
634 * it a delete event, as if we were a WM
636 XClientMessageEvent xevent;
638 gdk_window_hide (window);
639 gdk_window_reparent (window, NULL, 0, 0);
641 xevent.type = ClientMessage;
642 xevent.window = private->xwindow;
643 xevent.message_type = gdk_wm_protocols;
645 xevent.data.l[0] = gdk_wm_delete_window;
646 xevent.data.l[1] = CurrentTime;
648 XSendEvent (private->xdisplay, private->xwindow,
649 False, 0, (XEvent *)&xevent);
653 XDestroyWindow (private->xdisplay, private->xwindow);
655 if (private->colormap)
656 gdk_colormap_unref (private->colormap);
658 private->mapped = FALSE;
659 private->destroyed = TRUE;
663 case GDK_WINDOW_ROOT:
664 g_error ("attempted to destroy root window");
667 case GDK_WINDOW_PIXMAP:
668 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
673 /* Like internal_destroy, but also destroys the reference created by
677 gdk_window_destroy (GdkWindow *window)
679 gdk_window_internal_destroy (window, TRUE, TRUE);
680 gdk_window_unref (window);
683 /* This function is called when the XWindow is really gone. */
686 gdk_window_destroy_notify (GdkWindow *window)
688 GdkWindowPrivate *private;
690 g_return_if_fail (window != NULL);
692 private = (GdkWindowPrivate*) window;
694 if (!private->destroyed)
696 if (private->window_type == GDK_WINDOW_FOREIGN)
697 gdk_window_internal_destroy (window, FALSE, FALSE);
699 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
702 gdk_xid_table_remove (private->xwindow);
703 gdk_window_unref (window);
707 gdk_window_ref (GdkWindow *window)
709 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
710 g_return_val_if_fail (window != NULL, NULL);
712 private->ref_count += 1;
717 gdk_window_unref (GdkWindow *window)
719 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
720 g_return_if_fail (window != NULL);
722 private->ref_count -= 1;
723 if (private->ref_count == 0)
725 if (!private->destroyed)
727 if (private->window_type == GDK_WINDOW_FOREIGN)
728 gdk_xid_table_remove (private->xwindow);
730 g_warning ("losing last reference to undestroyed window\n");
732 g_dataset_destroy (window);
738 gdk_window_show (GdkWindow *window)
740 GdkWindowPrivate *private;
742 g_return_if_fail (window != NULL);
744 private = (GdkWindowPrivate*) window;
745 if (!private->destroyed)
747 private->mapped = TRUE;
748 XRaiseWindow (private->xdisplay, private->xwindow);
749 XMapWindow (private->xdisplay, private->xwindow);
754 gdk_window_hide (GdkWindow *window)
756 GdkWindowPrivate *private;
758 g_return_if_fail (window != NULL);
760 private = (GdkWindowPrivate*) window;
761 if (!private->destroyed)
763 private->mapped = FALSE;
764 XUnmapWindow (private->xdisplay, private->xwindow);
769 gdk_window_withdraw (GdkWindow *window)
771 GdkWindowPrivate *private;
773 g_return_if_fail (window != NULL);
775 private = (GdkWindowPrivate*) window;
776 if (!private->destroyed)
777 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
781 gdk_window_move (GdkWindow *window,
785 GdkWindowPrivate *private;
787 g_return_if_fail (window != NULL);
789 private = (GdkWindowPrivate*) window;
790 if (!private->destroyed)
792 XMoveWindow (private->xdisplay, private->xwindow, x, y);
794 if (private->window_type == GDK_WINDOW_CHILD)
803 gdk_window_resize (GdkWindow *window,
807 GdkWindowPrivate *private;
809 g_return_if_fail (window != NULL);
816 private = (GdkWindowPrivate*) window;
818 if (!private->destroyed &&
819 ((private->resize_count > 0) ||
820 (private->width != (guint16) width) ||
821 (private->height != (guint16) height)))
823 XResizeWindow (private->xdisplay, private->xwindow, width, height);
824 private->resize_count += 1;
826 if (private->window_type == GDK_WINDOW_CHILD)
828 private->width = width;
829 private->height = height;
835 gdk_window_move_resize (GdkWindow *window,
841 GdkWindowPrivate *private;
843 g_return_if_fail (window != NULL);
850 private = (GdkWindowPrivate*) window;
851 if (!private->destroyed)
853 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
855 if (private->guffaw_gravity)
857 GList *tmp_list = private->children;
860 GdkWindowPrivate *child_private = tmp_list->data;
862 child_private->x -= x - private->x;
863 child_private->y -= y - private->y;
865 tmp_list = tmp_list->next;
869 if (private->window_type == GDK_WINDOW_CHILD)
873 private->width = width;
874 private->height = height;
880 gdk_window_reparent (GdkWindow *window,
881 GdkWindow *new_parent,
885 GdkWindowPrivate *window_private;
886 GdkWindowPrivate *parent_private;
887 GdkWindowPrivate *old_parent_private;
889 g_return_if_fail (window != NULL);
892 new_parent = (GdkWindow*) &gdk_root_parent;
894 window_private = (GdkWindowPrivate*) window;
895 old_parent_private = (GdkWindowPrivate*)window_private->parent;
896 parent_private = (GdkWindowPrivate*) new_parent;
898 if (!window_private->destroyed && !parent_private->destroyed)
899 XReparentWindow (window_private->xdisplay,
900 window_private->xwindow,
901 parent_private->xwindow,
904 window_private->parent = new_parent;
906 if (old_parent_private)
907 old_parent_private->children = g_list_remove (old_parent_private->children, window);
909 if ((old_parent_private &&
910 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
911 (!old_parent_private && parent_private->guffaw_gravity))
912 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
914 parent_private->children = g_list_prepend (parent_private->children, window);
918 gdk_window_clear (GdkWindow *window)
920 GdkWindowPrivate *private;
922 g_return_if_fail (window != NULL);
924 private = (GdkWindowPrivate*) window;
926 if (!private->destroyed)
927 XClearWindow (private->xdisplay, private->xwindow);
931 gdk_window_clear_area (GdkWindow *window,
937 GdkWindowPrivate *private;
939 g_return_if_fail (window != NULL);
941 private = (GdkWindowPrivate*) window;
943 if (!private->destroyed)
944 XClearArea (private->xdisplay, private->xwindow,
945 x, y, width, height, False);
949 gdk_window_clear_area_e (GdkWindow *window,
955 GdkWindowPrivate *private;
957 g_return_if_fail (window != NULL);
959 private = (GdkWindowPrivate*) window;
961 if (!private->destroyed)
962 XClearArea (private->xdisplay, private->xwindow,
963 x, y, width, height, True);
967 gdk_window_copy_area (GdkWindow *window,
971 GdkWindow *source_window,
977 GdkWindowPrivate *src_private;
978 GdkWindowPrivate *dest_private;
979 GdkGCPrivate *gc_private;
981 g_return_if_fail (window != NULL);
982 g_return_if_fail (gc != NULL);
984 if (source_window == NULL)
985 source_window = window;
987 src_private = (GdkWindowPrivate*) source_window;
988 dest_private = (GdkWindowPrivate*) window;
989 gc_private = (GdkGCPrivate*) gc;
991 if (!src_private->destroyed && !dest_private->destroyed)
993 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
1002 gdk_window_raise (GdkWindow *window)
1004 GdkWindowPrivate *private;
1006 g_return_if_fail (window != NULL);
1008 private = (GdkWindowPrivate*) window;
1010 if (!private->destroyed)
1011 XRaiseWindow (private->xdisplay, private->xwindow);
1015 gdk_window_lower (GdkWindow *window)
1017 GdkWindowPrivate *private;
1019 g_return_if_fail (window != NULL);
1021 private = (GdkWindowPrivate*) window;
1023 if (!private->destroyed)
1024 XLowerWindow (private->xdisplay, private->xwindow);
1028 gdk_window_set_user_data (GdkWindow *window,
1031 g_return_if_fail (window != NULL);
1033 window->user_data = user_data;
1037 gdk_window_set_hints (GdkWindow *window,
1046 GdkWindowPrivate *private;
1047 XSizeHints size_hints;
1049 g_return_if_fail (window != NULL);
1051 private = (GdkWindowPrivate*) window;
1052 if (private->destroyed)
1055 size_hints.flags = 0;
1057 if (flags & GDK_HINT_POS)
1059 size_hints.flags |= PPosition;
1064 if (flags & GDK_HINT_MIN_SIZE)
1066 size_hints.flags |= PMinSize;
1067 size_hints.min_width = min_width;
1068 size_hints.min_height = min_height;
1071 if (flags & GDK_HINT_MAX_SIZE)
1073 size_hints.flags |= PMaxSize;
1074 size_hints.max_width = max_width;
1075 size_hints.max_height = max_height;
1079 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1083 gdk_window_set_geometry_hints (GdkWindow *window,
1084 GdkGeometry *geometry,
1085 GdkWindowHints geom_mask)
1087 GdkWindowPrivate *private;
1088 XSizeHints size_hints;
1090 g_return_if_fail (window != NULL);
1092 private = (GdkWindowPrivate*) window;
1093 if (private->destroyed)
1096 size_hints.flags = 0;
1098 if (geom_mask & GDK_HINT_POS)
1099 size_hints.flags |= PPosition;
1101 if (geom_mask & GDK_HINT_MIN_SIZE)
1103 size_hints.flags |= PMinSize;
1104 size_hints.min_width = geometry->min_width;
1105 size_hints.min_height = geometry->min_height;
1108 if (geom_mask & GDK_HINT_MAX_SIZE)
1110 size_hints.flags |= PMaxSize;
1111 size_hints.max_width = geometry->max_width;
1112 size_hints.max_height = geometry->max_height;
1115 if (geom_mask & GDK_HINT_BASE_SIZE)
1117 size_hints.flags |= PBaseSize;
1118 size_hints.base_width = geometry->base_width;
1119 size_hints.base_height = geometry->base_height;
1122 if (geom_mask & GDK_HINT_RESIZE_INC)
1124 size_hints.flags |= PResizeInc;
1125 size_hints.width_inc = geometry->width_inc;
1126 size_hints.height_inc = geometry->height_inc;
1129 if (geom_mask & GDK_HINT_ASPECT)
1131 size_hints.flags |= PAspect;
1132 if (geometry->min_aspect <= 1)
1134 size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
1135 size_hints.min_aspect.y = G_MAXINT;
1139 size_hints.min_aspect.x = G_MAXINT;
1140 size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
1142 if (geometry->max_aspect <= 1)
1144 size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
1145 size_hints.max_aspect.y = G_MAXINT;
1149 size_hints.max_aspect.x = G_MAXINT;
1150 size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
1155 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1159 gdk_window_set_title (GdkWindow *window,
1162 GdkWindowPrivate *private;
1164 g_return_if_fail (window != NULL);
1166 private = (GdkWindowPrivate*) window;
1167 if (!private->destroyed)
1168 XmbSetWMProperties (private->xdisplay, private->xwindow,
1169 title, title, NULL, 0, NULL, NULL, NULL);
1173 gdk_window_set_role (GdkWindow *window,
1176 GdkWindowPrivate *private;
1178 g_return_if_fail (window != NULL);
1180 private = (GdkWindowPrivate*) window;
1183 XChangeProperty (private->xdisplay, private->xwindow,
1184 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1185 8, PropModeReplace, role, strlen (role));
1187 XDeleteProperty (private->xdisplay, private->xwindow,
1188 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1192 gdk_window_set_transient_for (GdkWindow *window,
1195 GdkWindowPrivate *private;
1196 GdkWindowPrivate *parent_private;
1198 g_return_if_fail (window != NULL);
1200 private = (GdkWindowPrivate*) window;
1201 parent_private = (GdkWindowPrivate*) parent;
1203 if (!private->destroyed && !parent_private->destroyed)
1204 XSetTransientForHint (private->xdisplay,
1205 private->xwindow, parent_private->xwindow);
1209 gdk_window_set_background (GdkWindow *window,
1212 GdkWindowPrivate *private;
1214 g_return_if_fail (window != NULL);
1216 private = (GdkWindowPrivate*) window;
1217 if (!private->destroyed)
1218 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1222 gdk_window_set_back_pixmap (GdkWindow *window,
1224 gint parent_relative)
1226 GdkWindowPrivate *window_private;
1227 GdkPixmapPrivate *pixmap_private;
1230 g_return_if_fail (window != NULL);
1232 window_private = (GdkWindowPrivate*) window;
1233 pixmap_private = (GdkPixmapPrivate*) pixmap;
1236 xpixmap = pixmap_private->xwindow;
1240 if (parent_relative)
1241 xpixmap = ParentRelative;
1243 if (!window_private->destroyed)
1244 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1248 gdk_window_set_cursor (GdkWindow *window,
1251 GdkWindowPrivate *window_private;
1252 GdkCursorPrivate *cursor_private;
1255 g_return_if_fail (window != NULL);
1257 window_private = (GdkWindowPrivate*) window;
1258 cursor_private = (GdkCursorPrivate*) cursor;
1263 xcursor = cursor_private->xcursor;
1265 if (!window_private->destroyed)
1266 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1270 gdk_window_set_colormap (GdkWindow *window,
1271 GdkColormap *colormap)
1273 GdkWindowPrivate *window_private;
1274 GdkColormapPrivate *colormap_private;
1276 g_return_if_fail (window != NULL);
1277 g_return_if_fail (colormap != NULL);
1279 window_private = (GdkWindowPrivate*) window;
1280 colormap_private = (GdkColormapPrivate*) colormap;
1282 if (!window_private->destroyed)
1284 XSetWindowColormap (window_private->xdisplay,
1285 window_private->xwindow,
1286 colormap_private->xcolormap);
1288 if (window_private->colormap)
1289 gdk_colormap_unref (window_private->colormap);
1290 window_private->colormap = colormap;
1291 gdk_colormap_ref (window_private->colormap);
1293 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1294 gdk_window_add_colormap_windows (window);
1299 gdk_window_get_user_data (GdkWindow *window,
1302 g_return_if_fail (window != NULL);
1304 *data = window->user_data;
1308 gdk_window_get_geometry (GdkWindow *window,
1315 GdkWindowPrivate *window_private;
1321 guint tborder_width;
1325 window = (GdkWindow*) &gdk_root_parent;
1327 window_private = (GdkWindowPrivate*) window;
1329 if (!window_private->destroyed)
1331 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1332 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1348 gdk_window_get_position (GdkWindow *window,
1352 GdkWindowPrivate *window_private;
1354 g_return_if_fail (window != NULL);
1356 window_private = (GdkWindowPrivate*) window;
1359 *x = window_private->x;
1361 *y = window_private->y;
1365 gdk_window_get_size (GdkWindow *window,
1369 GdkWindowPrivate *window_private;
1371 g_return_if_fail (window != NULL);
1373 window_private = (GdkWindowPrivate*) window;
1376 *width = window_private->width;
1378 *height = window_private->height;
1382 gdk_window_get_visual (GdkWindow *window)
1384 GdkWindowPrivate *window_private;
1385 XWindowAttributes window_attributes;
1387 g_return_val_if_fail (window != NULL, NULL);
1389 window_private = (GdkWindowPrivate*) window;
1390 /* Huh? ->parent is never set for a pixmap. We should just return
1393 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1394 window_private = (GdkWindowPrivate*) window_private->parent;
1396 if (window_private && !window_private->destroyed)
1398 if (window_private->colormap == NULL)
1400 XGetWindowAttributes (window_private->xdisplay,
1401 window_private->xwindow,
1402 &window_attributes);
1403 return gdk_visual_lookup (window_attributes.visual);
1406 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1413 gdk_window_get_colormap (GdkWindow *window)
1415 GdkWindowPrivate *window_private;
1416 XWindowAttributes window_attributes;
1418 g_return_val_if_fail (window != NULL, NULL);
1419 window_private = (GdkWindowPrivate*) window;
1421 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1422 if (!window_private->destroyed)
1424 if (window_private->colormap == NULL)
1426 XGetWindowAttributes (window_private->xdisplay,
1427 window_private->xwindow,
1428 &window_attributes);
1429 return gdk_colormap_lookup (window_attributes.colormap);
1432 return window_private->colormap;
1439 gdk_window_get_type (GdkWindow *window)
1441 GdkWindowPrivate *window_private;
1443 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1445 window_private = (GdkWindowPrivate*) window;
1446 return window_private->window_type;
1450 gdk_window_get_origin (GdkWindow *window,
1454 GdkWindowPrivate *private;
1460 g_return_val_if_fail (window != NULL, 0);
1462 private = (GdkWindowPrivate*) window;
1464 if (!private->destroyed)
1466 return_val = XTranslateCoordinates (private->xdisplay,
1485 gdk_window_get_deskrelative_origin (GdkWindow *window,
1489 GdkWindowPrivate *private;
1490 gboolean return_val = FALSE;
1491 gint num_children, format_return;
1492 Window win, *child, parent, root;
1496 static Atom atom = 0;
1497 gulong number_return, bytes_after_return;
1498 guchar *data_return;
1500 g_return_val_if_fail (window != NULL, 0);
1502 private = (GdkWindowPrivate*) window;
1504 if (!private->destroyed)
1507 atom = XInternAtom (private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1508 win = private->xwindow;
1510 while (XQueryTree (private->xdisplay, win, &root, &parent,
1511 &child, (unsigned int *)&num_children))
1513 if ((child) && (num_children > 0))
1525 XGetWindowProperty (private->xdisplay, win, atom, 0, 0,
1526 False, XA_CARDINAL, &type_return, &format_return,
1527 &number_return, &bytes_after_return, &data_return);
1528 if (type_return == XA_CARDINAL)
1530 XFree (data_return);
1535 return_val = XTranslateCoordinates (private->xdisplay,
1551 gdk_window_get_root_origin (GdkWindow *window,
1555 GdkWindowPrivate *private;
1560 unsigned int nchildren;
1562 g_return_if_fail (window != NULL);
1564 private = (GdkWindowPrivate*) window;
1569 if (private->destroyed)
1572 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1573 private = (GdkWindowPrivate*) private->parent;
1574 if (private->destroyed)
1577 xparent = private->xwindow;
1581 if (!XQueryTree (private->xdisplay, xwindow,
1583 &children, &nchildren))
1589 while (xparent != root);
1591 if (xparent == root)
1593 unsigned int ww, wh, wb, wd;
1596 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1607 gdk_window_get_pointer (GdkWindow *window,
1610 GdkModifierType *mask)
1612 GdkWindowPrivate *private;
1613 GdkWindow *return_val;
1619 unsigned int xmask = 0;
1622 window = (GdkWindow*) &gdk_root_parent;
1624 private = (GdkWindowPrivate*) window;
1627 if (!private->destroyed &&
1628 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1629 &rootx, &rooty, &winx, &winy, &xmask))
1632 return_val = gdk_window_lookup (child);
1646 gdk_window_at_pointer (gint *win_x,
1649 GdkWindowPrivate *private;
1653 Window xwindow_last = 0;
1654 int rootx = -1, rooty = -1;
1658 private = &gdk_root_parent;
1660 xwindow = private->xwindow;
1662 XGrabServer (private->xdisplay);
1665 xwindow_last = xwindow;
1666 XQueryPointer (private->xdisplay,
1673 XUngrabServer (private->xdisplay);
1675 window = gdk_window_lookup (xwindow_last);
1678 *win_x = window ? winx : -1;
1680 *win_y = window ? winy : -1;
1686 gdk_window_get_parent (GdkWindow *window)
1688 g_return_val_if_fail (window != NULL, NULL);
1690 return ((GdkWindowPrivate*) window)->parent;
1694 gdk_window_get_toplevel (GdkWindow *window)
1696 GdkWindowPrivate *private;
1698 g_return_val_if_fail (window != NULL, NULL);
1700 private = (GdkWindowPrivate*) window;
1702 while (private->window_type == GDK_WINDOW_CHILD)
1704 window = ((GdkWindowPrivate*) window)->parent;
1705 private = (GdkWindowPrivate*) window;
1712 gdk_window_get_children (GdkWindow *window)
1714 GdkWindowPrivate *private;
1720 unsigned int nchildren;
1723 g_return_val_if_fail (window != NULL, NULL);
1725 private = (GdkWindowPrivate*) window;
1726 if (private->destroyed)
1729 XQueryTree (private->xdisplay, private->xwindow,
1730 &root, &parent, &xchildren, &nchildren);
1736 for (i = 0; i < nchildren; i++)
1738 child = gdk_window_lookup (xchildren[i]);
1740 children = g_list_prepend (children, child);
1751 gdk_window_get_events (GdkWindow *window)
1753 GdkWindowPrivate *private;
1754 XWindowAttributes attrs;
1755 GdkEventMask event_mask;
1758 g_return_val_if_fail (window != NULL, 0);
1760 private = (GdkWindowPrivate*) window;
1761 if (private->destroyed)
1764 XGetWindowAttributes (gdk_display, private->xwindow,
1768 for (i = 0; i < gdk_nevent_masks; i++)
1770 if (attrs.your_event_mask & gdk_event_mask_table[i])
1771 event_mask |= 1 << (i + 1);
1778 gdk_window_set_events (GdkWindow *window,
1779 GdkEventMask event_mask)
1781 GdkWindowPrivate *private;
1785 g_return_if_fail (window != NULL);
1787 private = (GdkWindowPrivate*) window;
1788 if (private->destroyed)
1791 xevent_mask = StructureNotifyMask;
1792 for (i = 0; i < gdk_nevent_masks; i++)
1794 if (event_mask & (1 << (i + 1)))
1795 xevent_mask |= gdk_event_mask_table[i];
1798 XSelectInput (gdk_display, private->xwindow,
1803 gdk_window_add_colormap_windows (GdkWindow *window)
1805 GdkWindow *toplevel;
1806 GdkWindowPrivate *toplevel_private;
1807 GdkWindowPrivate *window_private;
1808 Window *old_windows;
1809 Window *new_windows;
1812 g_return_if_fail (window != NULL);
1814 toplevel = gdk_window_get_toplevel (window);
1815 toplevel_private = (GdkWindowPrivate*) toplevel;
1816 window_private = (GdkWindowPrivate*) window;
1817 if (window_private->destroyed)
1821 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1822 toplevel_private->xwindow,
1823 &old_windows, &count))
1828 for (i = 0; i < count; i++)
1829 if (old_windows[i] == window_private->xwindow)
1831 XFree (old_windows);
1835 new_windows = g_new (Window, count + 1);
1837 for (i = 0; i < count; i++)
1838 new_windows[i] = old_windows[i];
1839 new_windows[count] = window_private->xwindow;
1841 XSetWMColormapWindows (toplevel_private->xdisplay,
1842 toplevel_private->xwindow,
1843 new_windows, count + 1);
1845 g_free (new_windows);
1847 XFree (old_windows);
1851 gdk_window_have_shape_ext (void)
1853 enum { UNKNOWN, NO, YES };
1854 static gint have_shape = UNKNOWN;
1856 if (have_shape == UNKNOWN)
1859 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1865 return (have_shape == YES);
1869 * This needs the X11 shape extension.
1870 * If not available, shaped windows will look
1871 * ugly, but programs still work. Stefan Wille
1874 gdk_window_shape_combine_mask (GdkWindow *window,
1878 GdkWindowPrivate *window_private;
1881 g_return_if_fail (window != NULL);
1883 #ifdef HAVE_SHAPE_EXT
1884 window_private = (GdkWindowPrivate*) window;
1885 if (window_private->destroyed)
1888 if (gdk_window_have_shape_ext ())
1892 GdkWindowPrivate *pixmap_private;
1894 pixmap_private = (GdkWindowPrivate*) mask;
1895 pixmap = (Pixmap) pixmap_private->xwindow;
1904 XShapeCombineMask (window_private->xdisplay,
1905 window_private->xwindow,
1911 #endif /* HAVE_SHAPE_EXT */
1915 gdk_window_add_filter (GdkWindow *window,
1916 GdkFilterFunc function,
1919 GdkWindowPrivate *private;
1921 GdkEventFilter *filter;
1923 private = (GdkWindowPrivate*) window;
1924 if (private && private->destroyed)
1928 tmp_list = private->filters;
1930 tmp_list = gdk_default_filters;
1934 filter = (GdkEventFilter *)tmp_list->data;
1935 if ((filter->function == function) && (filter->data == data))
1937 tmp_list = tmp_list->next;
1940 filter = g_new (GdkEventFilter, 1);
1941 filter->function = function;
1942 filter->data = data;
1945 private->filters = g_list_append (private->filters, filter);
1947 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1951 gdk_window_remove_filter (GdkWindow *window,
1952 GdkFilterFunc function,
1955 GdkWindowPrivate *private;
1956 GList *tmp_list, *node;
1957 GdkEventFilter *filter;
1959 private = (GdkWindowPrivate*) window;
1962 tmp_list = private->filters;
1964 tmp_list = gdk_default_filters;
1968 filter = (GdkEventFilter *)tmp_list->data;
1970 tmp_list = tmp_list->next;
1972 if ((filter->function == function) && (filter->data == data))
1975 private->filters = g_list_remove_link (private->filters, node);
1977 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1978 g_list_free_1 (node);
1987 gdk_window_set_override_redirect (GdkWindow *window,
1988 gboolean override_redirect)
1990 GdkWindowPrivate *private;
1991 XSetWindowAttributes attr;
1993 g_return_if_fail (window != NULL);
1994 private = (GdkWindowPrivate*) window;
1995 if (private->destroyed)
1998 attr.override_redirect = (override_redirect == FALSE)?False:True;
1999 XChangeWindowAttributes (gdk_display,
2000 ((GdkWindowPrivate *)window)->xwindow,
2006 gdk_window_set_icon (GdkWindow *window,
2007 GdkWindow *icon_window,
2012 GdkWindowPrivate *window_private;
2013 GdkWindowPrivate *private;
2015 g_return_if_fail (window != NULL);
2016 window_private = (GdkWindowPrivate*) window;
2017 if (window_private->destroyed)
2022 if (icon_window != NULL)
2024 private = (GdkWindowPrivate *)icon_window;
2025 wm_hints.flags |= IconWindowHint;
2026 wm_hints.icon_window = private->xwindow;
2031 private = (GdkWindowPrivate *)pixmap;
2032 wm_hints.flags |= IconPixmapHint;
2033 wm_hints.icon_pixmap = private->xwindow;
2038 private = (GdkWindowPrivate *)mask;
2039 wm_hints.flags |= IconMaskHint;
2040 wm_hints.icon_mask = private->xwindow;
2043 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2047 gdk_window_set_icon_name (GdkWindow *window,
2050 GdkWindowPrivate *window_private;
2051 XTextProperty property;
2054 g_return_if_fail (window != NULL);
2055 window_private = (GdkWindowPrivate*) window;
2056 if (window_private->destroyed)
2058 res = XmbTextListToTextProperty (window_private->xdisplay,
2059 &name, 1, XStdICCTextStyle,
2063 g_warning ("Error converting icon name to text property: %d\n", res);
2067 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2071 XFree (property.value);
2075 gdk_window_set_group (GdkWindow *window,
2079 GdkWindowPrivate *window_private;
2080 GdkWindowPrivate *private;
2082 g_return_if_fail (window != NULL);
2083 g_return_if_fail (leader != NULL);
2084 window_private = (GdkWindowPrivate*) window;
2085 if (window_private->destroyed)
2088 private = (GdkWindowPrivate *)leader;
2089 wm_hints.flags = WindowGroupHint;
2090 wm_hints.window_group = private->xwindow;
2092 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2096 gdk_window_set_mwm_hints (GdkWindow *window,
2097 MotifWmHints *new_hints)
2099 static Atom hints_atom = None;
2100 MotifWmHints *hints;
2106 GdkWindowPrivate *window_private;
2108 g_return_if_fail (window != NULL);
2109 window_private = (GdkWindowPrivate*) window;
2110 if (window_private->destroyed)
2114 hints_atom = XInternAtom (window_private->xdisplay,
2115 _XA_MOTIF_WM_HINTS, FALSE);
2117 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2118 hints_atom, 0, sizeof (MotifWmHints)/4,
2119 False, AnyPropertyType, &type, &format, &nitems,
2120 &bytes_after, (guchar **)&hints);
2126 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2128 hints->flags |= MWM_HINTS_FUNCTIONS;
2129 hints->functions = new_hints->functions;
2131 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2133 hints->flags |= MWM_HINTS_DECORATIONS;
2134 hints->decorations = new_hints->decorations;
2138 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2139 hints_atom, hints_atom, 32, PropModeReplace,
2140 (guchar *)hints, sizeof (MotifWmHints)/4);
2142 if (hints != new_hints)
2147 gdk_window_set_decorations (GdkWindow *window,
2148 GdkWMDecoration decorations)
2152 hints.flags = MWM_HINTS_DECORATIONS;
2153 hints.decorations = decorations;
2155 gdk_window_set_mwm_hints (window, &hints);
2159 gdk_window_set_functions (GdkWindow *window,
2160 GdkWMFunction functions)
2164 hints.flags = MWM_HINTS_FUNCTIONS;
2165 hints.functions = functions;
2167 gdk_window_set_mwm_hints (window, &hints);
2171 gdk_window_get_toplevels (void)
2173 GList *new_list = NULL;
2176 tmp_list = gdk_root_parent.children;
2179 new_list = g_list_prepend (new_list, tmp_list->data);
2180 tmp_list = tmp_list->next;
2187 * propagate the shapes from all child windows of a GDK window to the parent
2188 * window. Shamelessly ripped from Enlightenment's code
2197 struct _gdk_span *next;
2201 gdk_add_to_span (struct _gdk_span **s,
2205 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2212 /* scan the spans for this line */
2215 /* -- -> new span */
2216 /* == -> existing span */
2217 /* ## -> spans intersect */
2218 /* if we are in the middle of spanning the span into the line */
2221 /* case: ---- ==== */
2222 if (xx < ptr1->start - 1)
2224 /* ends before next span - extend to here */
2228 /* case: ----##=== */
2229 else if (xx <= ptr1->end)
2231 /* crosses into next span - delete next span and append */
2232 ss->end = ptr1->end;
2233 ss->next = ptr1->next;
2237 /* case: ---###--- */
2240 /* overlaps next span - delete and keep checking */
2241 ss->next = ptr1->next;
2246 /* otherwise havent started spanning it in yet */
2249 /* case: ---- ==== */
2250 if (xx < ptr1->start - 1)
2252 /* insert span here in list */
2253 noo = g_malloc (sizeof (struct _gdk_span));
2267 /* case: ----##=== */
2268 else if ((x < ptr1->start) && (xx <= ptr1->end))
2270 /* expand this span to the left point of the new one */
2274 /* case: ===###=== */
2275 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2277 /* throw the span away */
2280 /* case: ---###--- */
2281 else if ((x < ptr1->start) && (xx > ptr1->end))
2288 /* case: ===##---- */
2289 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2295 /* case: ==== ---- */
2296 /* case handled by next loop iteration - first case */
2301 /* it started in the middle but spans beyond your current list */
2307 /* it does not start inside a span or in the middle, so add it to the end */
2308 noo = g_malloc (sizeof (struct _gdk_span));
2316 noo->next = ptr2->next;
2329 gdk_add_rectangles (Display *disp,
2331 struct _gdk_span **spans,
2338 gint x1, y1, x2, y2;
2342 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2345 /* go through all clip rects in this window's shape */
2346 for (k = 0; k < rn; k++)
2348 /* for each clip rect, add it to each line's spans */
2350 x2 = x + rl[k].x + (rl[k].width - 1);
2352 y2 = y + rl[k].y + (rl[k].height - 1);
2361 for (a = y1; a <= y2; a++)
2364 gdk_add_to_span (&spans[a], x1, x2);
2372 gdk_propagate_shapes (Display *disp,
2376 Window rt, par, *list = NULL;
2377 gint i, j, num = 0, num_rects = 0;
2381 XRectangle *rects = NULL;
2382 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2383 XWindowAttributes xatt;
2385 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2390 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2392 for (i = 0; i < h; i++)
2394 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2397 /* go through all child windows and create/insert spans */
2398 for (i = 0; i < num; i++)
2400 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2401 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2402 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2405 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2407 /* go through the spans list and build a list of rects */
2408 rects = g_malloc (sizeof (XRectangle) * 256);
2410 for (i = 0; i < baseh; i++)
2413 /* go through the line for all spans */
2416 rects[num_rects].x = ptr1->start;
2417 rects[num_rects].y = i;
2418 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2419 rects[num_rects].height = 1;
2421 /* if there are more lines */
2423 /* while contigous rects (same start/end coords) exist */
2424 while ((contig) && (j < baseh))
2426 /* search next line for spans matching this one */
2432 /* if we have an exact span match set contig */
2433 if ((ptr2->start == ptr1->start) &&
2434 (ptr2->end == ptr1->end))
2437 /* remove the span - not needed */
2440 ptr3->next = ptr2->next;
2446 spans[j] = ptr2->next;
2452 /* gone past the span point no point looking */
2453 else if (ptr2->start < ptr1->start)
2461 /* if a contiguous span was found increase the rect h */
2464 rects[num_rects].height++;
2468 /* up the rect count */
2470 /* every 256 new rects increase the rect array */
2471 if ((num_rects % 256) == 0)
2472 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
2476 /* set the rects as the shape mask */
2479 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
2480 ShapeSet, YXSorted);
2485 /* free up all the spans we made */
2486 for (i = 0; i < baseh; i++)
2500 gdk_window_set_child_shapes (GdkWindow *window)
2502 GdkWindowPrivate *private;
2504 g_return_if_fail (window != NULL);
2506 #ifdef HAVE_SHAPE_EXT
2507 private = (GdkWindowPrivate*) window;
2508 if (private->destroyed)
2511 if (gdk_window_have_shape_ext ())
2512 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2517 gdk_window_merge_child_shapes (GdkWindow *window)
2519 GdkWindowPrivate *private;
2521 g_return_if_fail (window != NULL);
2523 #ifdef HAVE_SHAPE_EXT
2524 private = (GdkWindowPrivate*) window;
2525 if (private->destroyed)
2528 if (gdk_window_have_shape_ext ())
2529 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2533 /*************************************************************
2534 * gdk_window_is_visible:
2535 * Check if the given window is mapped.
2539 * is the window mapped
2540 *************************************************************/
2543 gdk_window_is_visible (GdkWindow *window)
2545 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2547 g_return_val_if_fail (window != NULL, FALSE);
2549 return private->mapped;
2552 /*************************************************************
2553 * gdk_window_is_viewable:
2554 * Check if the window and all ancestors of the window
2555 * are mapped. (This is not necessarily "viewable" in
2556 * the X sense, since we only check as far as we have
2557 * GDK window parents, not to the root window)
2561 * is the window viewable
2562 *************************************************************/
2565 gdk_window_is_viewable (GdkWindow *window)
2567 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2569 g_return_val_if_fail (window != NULL, FALSE);
2572 (private != &gdk_root_parent) &&
2573 (private->window_type != GDK_WINDOW_FOREIGN))
2575 if (!private->mapped)
2578 private = (GdkWindowPrivate *)private->parent;
2585 gdk_drawable_set_data (GdkDrawable *drawable,
2588 GDestroyNotify destroy_func)
2590 g_dataset_set_data_full (drawable, key, data, destroy_func);
2594 /* Support for windows that can be guffaw-scrolled
2595 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2599 gdk_window_gravity_works (void)
2601 enum { UNKNOWN, NO, YES };
2602 static gint gravity_works = UNKNOWN;
2604 if (gravity_works == UNKNOWN)
2611 /* This particular server apparently has a bug so that the test
2612 * works but the actual code crashes it
2614 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
2615 (VendorRelease (gdk_display) == 3400))
2621 attr.window_type = GDK_WINDOW_TEMP;
2622 attr.wclass = GDK_INPUT_OUTPUT;
2627 attr.event_mask = 0;
2629 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2631 attr.window_type = GDK_WINDOW_CHILD;
2632 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2634 gdk_window_set_static_win_gravity (child, TRUE);
2636 gdk_window_resize (parent, 100, 110);
2637 gdk_window_move (parent, 0, -10);
2638 gdk_window_move_resize (parent, 0, 0, 100, 100);
2640 gdk_window_resize (parent, 100, 110);
2641 gdk_window_move (parent, 0, -10);
2642 gdk_window_move_resize (parent, 0, 0, 100, 100);
2644 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2646 gdk_window_destroy (parent);
2647 gdk_window_destroy (child);
2649 gravity_works = ((y == -20) ? YES : NO);
2652 return (gravity_works == YES);
2656 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2658 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2659 XSetWindowAttributes xattributes;
2661 g_return_if_fail (window != NULL);
2663 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
2664 XChangeWindowAttributes (private->xdisplay,
2666 CWBitGravity, &xattributes);
2670 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2672 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2673 XSetWindowAttributes xattributes;
2675 g_return_if_fail (window != NULL);
2677 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
2679 XChangeWindowAttributes (private->xdisplay,
2681 CWWinGravity, &xattributes);
2684 /*************************************************************
2685 * gdk_window_set_static_gravities:
2686 * Set the bit gravity of the given window to static,
2687 * and flag it so all children get static subwindow
2690 * window: window for which to set static gravity
2691 * use_static: Whether to turn static gravity on or off.
2693 * Does the XServer support static gravity?
2694 *************************************************************/
2697 gdk_window_set_static_gravities (GdkWindow *window,
2698 gboolean use_static)
2700 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2703 g_return_val_if_fail (window != NULL, FALSE);
2705 if (!use_static == !private->guffaw_gravity)
2708 if (use_static && !gdk_window_gravity_works ())
2711 private->guffaw_gravity = use_static;
2713 gdk_window_set_static_bit_gravity (window, use_static);
2715 tmp_list = private->children;
2718 gdk_window_set_static_win_gravity (window, use_static);
2720 tmp_list = tmp_list->next;