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"
33 #include <X11/extensions/shape.h>
36 int nevent_masks = 20;
37 int event_mask_table[20] =
41 PointerMotionHintMask,
46 ButtonPressMask | OwnerGrabButtonMask,
47 ButtonReleaseMask | OwnerGrabButtonMask,
58 SubstructureNotifyMask
61 static gboolean gdk_window_have_shape_ext (void);
63 /* internal function created for and used by gdk_window_xid_at_coords */
65 gdk_window_xid_at (Window base,
74 GdkWindowPrivate *private;
77 Window child = 0, parent_win = 0, root_win = 0;
79 unsigned int ww, wh, wb, wd, num;
82 window = (GdkWindow*) &gdk_root_parent;
83 private = (GdkWindowPrivate*) window;
84 disp = private->xdisplay;
85 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
92 (x < (int) (wx + ww)) &&
93 (y < (int) (wy + wh))))
96 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
101 for (i = num - 1; ; i--)
103 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
105 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
120 * The following fucntion by The Rasterman <raster@redhat.com>
121 * This function returns the X Window ID in which the x y location is in
122 * (x and y being relative to the root window), excluding any windows listed
123 * in the GList excludes (this is a list of X Window ID's - gpointer being
126 * This is primarily designed for internal gdk use - for DND for example
127 * when using a shaped icon window as the drag object - you exclude the
128 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
129 * You can get back an X Window ID as to what X Window ID is infact under
130 * those X,Y co-ordinates.
133 gdk_window_xid_at_coords (gint x,
139 GdkWindowPrivate *private;
142 Window root, child = 0, parent_win = 0, root_win = 0;
146 window = (GdkWindow*) &gdk_root_parent;
147 private = (GdkWindowPrivate*) window;
148 disp = private->xdisplay;
149 root = private->xwindow;
150 num = g_list_length (excludes);
153 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
163 XWindowAttributes xwa;
165 XGetWindowAttributes (disp, list [i], &xwa);
167 if (xwa.map_state != IsViewable)
170 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
173 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
178 if (!g_list_find (excludes, (gpointer *) child))
181 XUngrabServer (disp);
188 XUngrabServer (disp);
194 XUngrabServer (disp);
199 gdk_window_init (void)
201 XWindowAttributes xattributes;
204 unsigned int border_width;
208 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
209 &x, &y, &width, &height, &border_width, &depth);
210 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
212 gdk_root_parent.xwindow = gdk_root_window;
213 gdk_root_parent.xdisplay = gdk_display;
214 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
215 gdk_root_parent.window.user_data = NULL;
216 gdk_root_parent.width = width;
217 gdk_root_parent.height = height;
218 gdk_root_parent.children = NULL;
219 gdk_root_parent.colormap = NULL;
220 gdk_root_parent.ref_count = 1;
222 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
226 gdk_window_new (GdkWindow *parent,
227 GdkWindowAttr *attributes,
228 gint attributes_mask)
231 GdkWindowPrivate *private;
232 GdkWindowPrivate *parent_private;
234 Display *parent_display;
237 XSetWindowAttributes xattributes;
238 long xattributes_mask;
239 XSizeHints size_hints;
241 XClassHint *class_hint;
247 g_return_val_if_fail (attributes != NULL, NULL);
250 parent = (GdkWindow*) &gdk_root_parent;
252 parent_private = (GdkWindowPrivate*) parent;
253 if (parent_private->destroyed)
256 xparent = parent_private->xwindow;
257 parent_display = parent_private->xdisplay;
259 private = g_new (GdkWindowPrivate, 1);
260 window = (GdkWindow*) private;
262 private->parent = parent;
265 parent_private->children = g_list_prepend (parent_private->children, window);
267 private->xdisplay = parent_display;
268 private->destroyed = FALSE;
269 private->resize_count = 0;
270 private->ref_count = 1;
271 xattributes_mask = 0;
273 if (attributes_mask & GDK_WA_X)
278 if (attributes_mask & GDK_WA_Y)
285 private->width = (attributes->width > 1) ? (attributes->width) : (1);
286 private->height = (attributes->height > 1) ? (attributes->height) : (1);
287 private->window_type = attributes->window_type;
288 private->extension_events = FALSE;
290 private->filters = NULL;
291 private->children = NULL;
293 window->user_data = NULL;
295 if (attributes_mask & GDK_WA_VISUAL)
296 visual = attributes->visual;
298 visual = gdk_visual_get_system ();
299 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
301 xattributes.event_mask = StructureNotifyMask;
302 for (i = 0; i < nevent_masks; i++)
304 if (attributes->event_mask & (1 << (i + 1)))
305 xattributes.event_mask |= event_mask_table[i];
308 if (xattributes.event_mask)
309 xattributes_mask |= CWEventMask;
311 if(attributes_mask & GDK_WA_NOREDIR) {
312 xattributes.override_redirect =
313 (attributes->override_redirect == FALSE)?False:True;
314 xattributes_mask |= CWOverrideRedirect;
316 xattributes.override_redirect = False;
318 if (attributes->wclass == GDK_INPUT_OUTPUT)
321 depth = visual->depth;
323 if (attributes_mask & GDK_WA_COLORMAP)
324 private->colormap = attributes->colormap;
326 private->colormap = gdk_colormap_get_system ();
328 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
329 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
330 xattributes_mask |= CWBorderPixel | CWBackPixel;
332 switch (private->window_type)
334 case GDK_WINDOW_TOPLEVEL:
335 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
336 xattributes_mask |= CWColormap;
338 xparent = gdk_root_window;
341 case GDK_WINDOW_CHILD:
342 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
343 xattributes_mask |= CWColormap;
346 case GDK_WINDOW_DIALOG:
347 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
348 xattributes_mask |= CWColormap;
350 xparent = gdk_root_window;
353 case GDK_WINDOW_TEMP:
354 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
355 xattributes_mask |= CWColormap;
357 xparent = gdk_root_window;
359 xattributes.save_under = True;
360 xattributes.override_redirect = True;
361 xattributes.cursor = None;
362 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
364 case GDK_WINDOW_ROOT:
365 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
367 case GDK_WINDOW_PIXMAP:
368 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
376 private->colormap = NULL;
379 private->xwindow = XCreateWindow (private->xdisplay, xparent,
380 x, y, private->width, private->height,
381 0, depth, class, xvisual,
382 xattributes_mask, &xattributes);
383 gdk_window_ref (window);
384 gdk_xid_table_insert (&private->xwindow, window);
386 if (private->colormap)
387 gdk_colormap_ref (private->colormap);
389 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
390 (attributes->cursor) :
393 switch (private->window_type)
395 case GDK_WINDOW_DIALOG:
396 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
397 case GDK_WINDOW_TOPLEVEL:
398 case GDK_WINDOW_TEMP:
399 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
401 case GDK_WINDOW_CHILD:
402 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
403 (private->colormap != gdk_colormap_get_system ()) &&
404 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
406 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
407 gdk_window_add_colormap_windows (window);
416 size_hints.flags = PSize;
417 size_hints.width = private->width;
418 size_hints.height = private->height;
420 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
421 wm_hints.window_group = gdk_leader_window;
422 wm_hints.input = True;
423 wm_hints.initial_state = NormalState;
425 /* FIXME: Is there any point in doing this? Do any WM's pay
426 * attention to PSize, and even if they do, is this the
429 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
431 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
433 if (attributes_mask & GDK_WA_TITLE)
434 title = attributes->title;
436 title = g_get_prgname ();
438 XmbSetWMProperties (private->xdisplay, private->xwindow,
443 if (attributes_mask & GDK_WA_WMCLASS)
445 class_hint = XAllocClassHint ();
446 class_hint->res_name = attributes->wmclass_name;
447 class_hint->res_class = attributes->wmclass_class;
448 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
457 gdk_window_foreign_new (guint32 anid)
460 GdkWindowPrivate *private;
461 GdkWindowPrivate *parent_private;
462 XWindowAttributes attrs;
464 Window *children = NULL;
467 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
468 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
472 private = g_new (GdkWindowPrivate, 1);
473 window = (GdkWindow*) private;
475 /* FIXME: This is pretty expensive. Maybe the caller should supply
477 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
481 private->parent = gdk_xid_table_lookup (parent);
483 parent_private = (GdkWindowPrivate *)private->parent;
486 parent_private->children = g_list_prepend (parent_private->children, window);
488 private->xwindow = anid;
489 private->xdisplay = gdk_display;
490 private->x = attrs.x;
491 private->y = attrs.y;
492 private->width = attrs.width;
493 private->height = attrs.height;
494 private->resize_count = 0;
495 private->ref_count = 1;
496 private->window_type = GDK_WINDOW_FOREIGN;
497 private->destroyed = FALSE;
498 private->extension_events = 0;
500 private->colormap = NULL;
502 private->filters = NULL;
503 private->children = NULL;
505 window->user_data = NULL;
507 gdk_window_ref (window);
508 gdk_xid_table_insert (&private->xwindow, window);
513 /* Call this function when you want a window and all its children to
514 disappear. When xdestroy is true, a request to destroy the XWindow
515 is sent out. When it is false, it is assumed that the XWindow has
516 been or will be destroyed by destroying some ancestor of this
520 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
521 gboolean our_destroy)
523 GdkWindowPrivate *private;
524 GdkWindowPrivate *temp_private;
525 GdkWindow *temp_window;
529 g_return_if_fail (window != NULL);
531 private = (GdkWindowPrivate*) window;
533 switch (private->window_type)
535 case GDK_WINDOW_TOPLEVEL:
536 case GDK_WINDOW_CHILD:
537 case GDK_WINDOW_DIALOG:
538 case GDK_WINDOW_TEMP:
539 case GDK_WINDOW_FOREIGN:
540 if (!private->destroyed)
544 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
545 if (parent_private->children)
546 parent_private->children = g_list_remove (parent_private->children, window);
549 if (private->window_type != GDK_WINDOW_FOREIGN)
551 children = tmp = private->children;
552 private->children = NULL;
556 temp_window = tmp->data;
559 temp_private = (GdkWindowPrivate*) temp_window;
561 gdk_window_internal_destroy (temp_window, FALSE,
565 g_list_free (children);
568 if (private->extension_events != 0)
569 gdk_input_window_destroy (window);
571 if (private->filters)
573 tmp = private->filters;
581 g_list_free (private->filters);
582 private->filters = NULL;
585 if (private->window_type == GDK_WINDOW_FOREIGN)
587 if (our_destroy && (private->parent != NULL))
589 /* It's somebody elses window, but in our heirarchy,
590 * so reparent it to the root window, and then send
591 * it a delete event, as if we were a WM
593 XClientMessageEvent xevent;
595 gdk_window_hide (window);
596 gdk_window_reparent (window, NULL, 0, 0);
598 xevent.type = ClientMessage;
599 xevent.window = private->xwindow;
600 xevent.message_type = gdk_wm_protocols;
602 xevent.data.l[0] = gdk_wm_delete_window;
603 xevent.data.l[1] = CurrentTime;
605 XSendEvent (private->xdisplay, private->xwindow,
606 False, 0, (XEvent *)&xevent);
610 XDestroyWindow (private->xdisplay, private->xwindow);
612 if (private->colormap)
613 gdk_colormap_unref (private->colormap);
615 private->destroyed = TRUE;
619 case GDK_WINDOW_ROOT:
620 g_error ("attempted to destroy root window");
623 case GDK_WINDOW_PIXMAP:
624 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
629 /* Like internal_destroy, but also destroys the reference created by
633 gdk_window_destroy (GdkWindow *window)
635 gdk_window_internal_destroy (window, TRUE, TRUE);
636 gdk_window_unref (window);
639 /* This function is called when the XWindow is really gone. */
642 gdk_window_destroy_notify (GdkWindow *window)
644 GdkWindowPrivate *private;
646 g_return_if_fail (window != NULL);
648 private = (GdkWindowPrivate*) window;
650 if (!private->destroyed)
652 if (private->window_type == GDK_WINDOW_FOREIGN)
653 gdk_window_internal_destroy (window, FALSE, FALSE);
655 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
658 gdk_xid_table_remove (private->xwindow);
659 gdk_window_unref (window);
663 gdk_window_ref (GdkWindow *window)
665 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
666 g_return_val_if_fail (window != NULL, NULL);
668 private->ref_count += 1;
673 gdk_window_unref (GdkWindow *window)
675 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
676 g_return_if_fail (window != NULL);
678 private->ref_count -= 1;
679 if (private->ref_count == 0)
681 if (!private->destroyed)
683 if (private->window_type == GDK_WINDOW_FOREIGN)
684 gdk_xid_table_remove (private->xwindow);
686 g_warning ("losing last reference to undestroyed window\n");
688 g_dataset_destroy (window);
694 gdk_window_show (GdkWindow *window)
696 GdkWindowPrivate *private;
698 g_return_if_fail (window != NULL);
700 private = (GdkWindowPrivate*) window;
701 if (!private->destroyed)
703 XRaiseWindow (private->xdisplay, private->xwindow);
704 XMapWindow (private->xdisplay, private->xwindow);
709 gdk_window_hide (GdkWindow *window)
711 GdkWindowPrivate *private;
713 g_return_if_fail (window != NULL);
715 private = (GdkWindowPrivate*) window;
716 if (!private->destroyed)
717 XUnmapWindow (private->xdisplay, private->xwindow);
721 gdk_window_withdraw (GdkWindow *window)
723 GdkWindowPrivate *private;
725 g_return_if_fail (window != NULL);
727 private = (GdkWindowPrivate*) window;
728 if (!private->destroyed)
729 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
733 gdk_window_move (GdkWindow *window,
737 GdkWindowPrivate *private;
739 g_return_if_fail (window != NULL);
741 private = (GdkWindowPrivate*) window;
742 if (!private->destroyed)
744 XMoveWindow (private->xdisplay, private->xwindow, x, y);
746 if (private->window_type == GDK_WINDOW_CHILD)
755 gdk_window_resize (GdkWindow *window,
759 GdkWindowPrivate *private;
761 g_return_if_fail (window != NULL);
768 private = (GdkWindowPrivate*) window;
770 if (!private->destroyed &&
771 ((private->resize_count > 0) ||
772 (private->width != (guint16) width) ||
773 (private->height != (guint16) height)))
775 XResizeWindow (private->xdisplay, private->xwindow, width, height);
776 private->resize_count += 1;
778 if (private->window_type == GDK_WINDOW_CHILD)
780 private->width = width;
781 private->height = height;
787 gdk_window_move_resize (GdkWindow *window,
793 GdkWindowPrivate *private;
795 g_return_if_fail (window != NULL);
802 private = (GdkWindowPrivate*) window;
803 if (!private->destroyed)
805 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
807 if (private->window_type == GDK_WINDOW_CHILD)
811 private->width = width;
812 private->height = height;
818 gdk_window_reparent (GdkWindow *window,
819 GdkWindow *new_parent,
823 GdkWindowPrivate *window_private;
824 GdkWindowPrivate *parent_private;
825 GdkWindowPrivate *old_parent_private;
827 g_return_if_fail (window != NULL);
830 new_parent = (GdkWindow*) &gdk_root_parent;
832 window_private = (GdkWindowPrivate*) window;
833 old_parent_private = (GdkWindowPrivate*)window_private->parent;
834 parent_private = (GdkWindowPrivate*) new_parent;
836 if (!window_private->destroyed && !parent_private->destroyed)
837 XReparentWindow (window_private->xdisplay,
838 window_private->xwindow,
839 parent_private->xwindow,
842 window_private->parent = new_parent;
844 if (old_parent_private)
845 old_parent_private->children = g_list_remove (old_parent_private->children, window);
846 parent_private->children = g_list_prepend (parent_private->children, window);
851 gdk_window_clear (GdkWindow *window)
853 GdkWindowPrivate *private;
855 g_return_if_fail (window != NULL);
857 private = (GdkWindowPrivate*) window;
859 if (!private->destroyed)
860 XClearWindow (private->xdisplay, private->xwindow);
864 gdk_window_clear_area (GdkWindow *window,
870 GdkWindowPrivate *private;
872 g_return_if_fail (window != NULL);
874 private = (GdkWindowPrivate*) window;
876 if (!private->destroyed)
877 XClearArea (private->xdisplay, private->xwindow,
878 x, y, width, height, False);
882 gdk_window_clear_area_e (GdkWindow *window,
888 GdkWindowPrivate *private;
890 g_return_if_fail (window != NULL);
892 private = (GdkWindowPrivate*) window;
894 if (!private->destroyed)
895 XClearArea (private->xdisplay, private->xwindow,
896 x, y, width, height, True);
900 gdk_window_copy_area (GdkWindow *window,
904 GdkWindow *source_window,
910 GdkWindowPrivate *src_private;
911 GdkWindowPrivate *dest_private;
912 GdkGCPrivate *gc_private;
914 g_return_if_fail (window != NULL);
915 g_return_if_fail (gc != NULL);
917 if (source_window == NULL)
918 source_window = window;
920 src_private = (GdkWindowPrivate*) source_window;
921 dest_private = (GdkWindowPrivate*) window;
922 gc_private = (GdkGCPrivate*) gc;
924 if (!src_private->destroyed && !dest_private->destroyed)
926 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
935 gdk_window_raise (GdkWindow *window)
937 GdkWindowPrivate *private;
939 g_return_if_fail (window != NULL);
941 private = (GdkWindowPrivate*) window;
943 if (!private->destroyed)
944 XRaiseWindow (private->xdisplay, private->xwindow);
948 gdk_window_lower (GdkWindow *window)
950 GdkWindowPrivate *private;
952 g_return_if_fail (window != NULL);
954 private = (GdkWindowPrivate*) window;
956 if (!private->destroyed)
957 XLowerWindow (private->xdisplay, private->xwindow);
961 gdk_window_set_user_data (GdkWindow *window,
964 g_return_if_fail (window != NULL);
966 window->user_data = user_data;
970 gdk_window_set_hints (GdkWindow *window,
979 GdkWindowPrivate *private;
980 XSizeHints size_hints;
982 g_return_if_fail (window != NULL);
984 private = (GdkWindowPrivate*) window;
985 if (private->destroyed)
988 size_hints.flags = 0;
990 if (flags & GDK_HINT_POS)
992 size_hints.flags |= PPosition;
997 if (flags & GDK_HINT_MIN_SIZE)
999 size_hints.flags |= PMinSize;
1000 size_hints.min_width = min_width;
1001 size_hints.min_height = min_height;
1004 if (flags & GDK_HINT_MAX_SIZE)
1006 size_hints.flags |= PMaxSize;
1007 size_hints.max_width = max_width;
1008 size_hints.max_height = max_height;
1012 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1016 gdk_window_set_title (GdkWindow *window,
1019 GdkWindowPrivate *private;
1021 g_return_if_fail (window != NULL);
1023 private = (GdkWindowPrivate*) window;
1024 if (!private->destroyed)
1025 XmbSetWMProperties (private->xdisplay, private->xwindow,
1026 title, title, NULL, 0, NULL, NULL, NULL);
1030 gdk_window_set_background (GdkWindow *window,
1033 GdkWindowPrivate *private;
1035 g_return_if_fail (window != NULL);
1037 private = (GdkWindowPrivate*) window;
1038 if (!private->destroyed)
1039 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1043 gdk_window_set_back_pixmap (GdkWindow *window,
1045 gint parent_relative)
1047 GdkWindowPrivate *window_private;
1048 GdkPixmapPrivate *pixmap_private;
1051 g_return_if_fail (window != NULL);
1053 window_private = (GdkWindowPrivate*) window;
1054 pixmap_private = (GdkPixmapPrivate*) pixmap;
1057 xpixmap = pixmap_private->xwindow;
1061 if (parent_relative)
1062 xpixmap = ParentRelative;
1064 if (!window_private->destroyed)
1065 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1069 gdk_window_set_cursor (GdkWindow *window,
1072 GdkWindowPrivate *window_private;
1073 GdkCursorPrivate *cursor_private;
1076 g_return_if_fail (window != NULL);
1078 window_private = (GdkWindowPrivate*) window;
1079 cursor_private = (GdkCursorPrivate*) cursor;
1084 xcursor = cursor_private->xcursor;
1086 if (!window_private->destroyed)
1087 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1091 gdk_window_set_colormap (GdkWindow *window,
1092 GdkColormap *colormap)
1094 GdkWindowPrivate *window_private;
1095 GdkColormapPrivate *colormap_private;
1097 g_return_if_fail (window != NULL);
1098 g_return_if_fail (colormap != NULL);
1100 window_private = (GdkWindowPrivate*) window;
1101 colormap_private = (GdkColormapPrivate*) colormap;
1103 if (!window_private->destroyed)
1105 XSetWindowColormap (window_private->xdisplay,
1106 window_private->xwindow,
1107 colormap_private->xcolormap);
1109 if (window_private->colormap)
1110 gdk_colormap_unref (window_private->colormap);
1111 window_private->colormap = colormap;
1112 gdk_colormap_ref (window_private->colormap);
1114 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1115 gdk_window_add_colormap_windows (window);
1120 gdk_window_get_user_data (GdkWindow *window,
1123 g_return_if_fail (window != NULL);
1125 *data = window->user_data;
1129 gdk_window_get_geometry (GdkWindow *window,
1136 GdkWindowPrivate *window_private;
1142 guint tborder_width;
1146 window = (GdkWindow*) &gdk_root_parent;
1148 window_private = (GdkWindowPrivate*) window;
1150 if (!window_private->destroyed)
1152 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1153 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1169 gdk_window_get_position (GdkWindow *window,
1173 GdkWindowPrivate *window_private;
1175 g_return_if_fail (window != NULL);
1177 window_private = (GdkWindowPrivate*) window;
1180 *x = window_private->x;
1182 *y = window_private->y;
1186 gdk_window_get_size (GdkWindow *window,
1190 GdkWindowPrivate *window_private;
1192 g_return_if_fail (window != NULL);
1194 window_private = (GdkWindowPrivate*) window;
1197 *width = window_private->width;
1199 *height = window_private->height;
1203 gdk_window_get_visual (GdkWindow *window)
1205 GdkWindowPrivate *window_private;
1206 XWindowAttributes window_attributes;
1208 g_return_val_if_fail (window != NULL, NULL);
1210 window_private = (GdkWindowPrivate*) window;
1211 /* Huh? ->parent is never set for a pixmap. We should just return
1214 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1215 window_private = (GdkWindowPrivate*) window_private->parent;
1217 if (window_private && !window_private->destroyed)
1219 if (window_private->colormap == NULL)
1221 XGetWindowAttributes (window_private->xdisplay,
1222 window_private->xwindow,
1223 &window_attributes);
1224 return gdk_visual_lookup (window_attributes.visual);
1227 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1234 gdk_window_get_colormap (GdkWindow *window)
1236 GdkWindowPrivate *window_private;
1237 XWindowAttributes window_attributes;
1239 g_return_val_if_fail (window != NULL, NULL);
1240 window_private = (GdkWindowPrivate*) window;
1242 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1243 if (!window_private->destroyed)
1245 if (window_private->colormap == NULL)
1247 XGetWindowAttributes (window_private->xdisplay,
1248 window_private->xwindow,
1249 &window_attributes);
1250 return gdk_colormap_lookup (window_attributes.colormap);
1253 return window_private->colormap;
1260 gdk_window_get_type (GdkWindow *window)
1262 GdkWindowPrivate *window_private;
1264 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1266 window_private = (GdkWindowPrivate*) window;
1267 return window_private->window_type;
1271 gdk_window_get_origin (GdkWindow *window,
1275 GdkWindowPrivate *private;
1281 g_return_val_if_fail (window != NULL, 0);
1283 private = (GdkWindowPrivate*) window;
1285 if (!private->destroyed)
1287 return_val = XTranslateCoordinates (private->xdisplay,
1306 gdk_window_get_deskrelative_origin (GdkWindow *window,
1310 GdkWindowPrivate *private;
1311 gboolean return_val = FALSE;
1312 gint num_children, format_return;
1313 Window win, *child, parent, root;
1317 static Atom atom = 0;
1318 gulong number_return, bytes_after_return;
1319 guchar *data_return;
1321 g_return_val_if_fail (window != NULL, 0);
1323 private = (GdkWindowPrivate*) window;
1325 if (!private->destroyed)
1328 atom = XInternAtom(private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
1329 win = private->xwindow;
1331 while (XQueryTree(private->xdisplay, win, &root, &parent,
1332 &child, (unsigned int *)&num_children))
1334 if ((child) && (num_children > 0))
1346 XGetWindowProperty(private->xdisplay, win, atom, 0, 0,
1347 False, XA_CARDINAL, &type_return, &format_return,
1348 &number_return, &bytes_after_return, &data_return);
1349 if (type_return == XA_CARDINAL)
1356 return_val = XTranslateCoordinates (private->xdisplay,
1372 gdk_window_get_root_origin (GdkWindow *window,
1376 GdkWindowPrivate *private;
1381 unsigned int nchildren;
1383 g_return_if_fail (window != NULL);
1385 private = (GdkWindowPrivate*) window;
1390 if (private->destroyed)
1393 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1394 private = (GdkWindowPrivate*) private->parent;
1395 if (private->destroyed)
1398 xparent = private->xwindow;
1402 if (!XQueryTree (private->xdisplay, xwindow,
1404 &children, &nchildren))
1410 while (xparent != root);
1412 if (xparent == root)
1414 unsigned int ww, wh, wb, wd;
1417 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1428 gdk_window_get_pointer (GdkWindow *window,
1431 GdkModifierType *mask)
1433 GdkWindowPrivate *private;
1434 GdkWindow *return_val;
1440 unsigned int xmask = 0;
1443 window = (GdkWindow*) &gdk_root_parent;
1445 private = (GdkWindowPrivate*) window;
1448 if (!private->destroyed &&
1449 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1450 &rootx, &rooty, &winx, &winy, &xmask))
1453 return_val = gdk_window_lookup (child);
1467 gdk_window_at_pointer (gint *win_x,
1470 GdkWindowPrivate *private;
1474 Window xwindow_last = 0;
1475 int rootx = -1, rooty = -1;
1479 private = &gdk_root_parent;
1481 xwindow = private->xwindow;
1483 XGrabServer (private->xdisplay);
1486 xwindow_last = xwindow;
1487 XQueryPointer (private->xdisplay,
1494 XUngrabServer (private->xdisplay);
1496 window = gdk_window_lookup (xwindow_last);
1499 *win_x = window ? winx : -1;
1501 *win_y = window ? winy : -1;
1507 gdk_window_get_parent (GdkWindow *window)
1509 g_return_val_if_fail (window != NULL, NULL);
1511 return ((GdkWindowPrivate*) window)->parent;
1515 gdk_window_get_toplevel (GdkWindow *window)
1517 GdkWindowPrivate *private;
1519 g_return_val_if_fail (window != NULL, NULL);
1521 private = (GdkWindowPrivate*) window;
1523 while (private->window_type == GDK_WINDOW_CHILD)
1525 window = ((GdkWindowPrivate*) window)->parent;
1526 private = (GdkWindowPrivate*) window;
1533 gdk_window_get_children (GdkWindow *window)
1535 GdkWindowPrivate *private;
1541 unsigned int nchildren;
1544 g_return_val_if_fail (window != NULL, NULL);
1546 private = (GdkWindowPrivate*) window;
1547 if (private->destroyed)
1550 XQueryTree (private->xdisplay, private->xwindow,
1551 &root, &parent, &xchildren, &nchildren);
1557 for (i = 0; i < nchildren; i++)
1559 child = gdk_window_lookup (xchildren[i]);
1561 children = g_list_prepend (children, child);
1572 gdk_window_get_events (GdkWindow *window)
1574 GdkWindowPrivate *private;
1575 XWindowAttributes attrs;
1576 GdkEventMask event_mask;
1579 g_return_val_if_fail (window != NULL, 0);
1581 private = (GdkWindowPrivate*) window;
1582 if (private->destroyed)
1585 XGetWindowAttributes (gdk_display, private->xwindow,
1589 for (i = 0; i < nevent_masks; i++)
1591 if (attrs.your_event_mask & event_mask_table[i])
1592 event_mask |= 1 << (i + 1);
1599 gdk_window_set_events (GdkWindow *window,
1600 GdkEventMask event_mask)
1602 GdkWindowPrivate *private;
1606 g_return_if_fail (window != NULL);
1608 private = (GdkWindowPrivate*) window;
1609 if (private->destroyed)
1612 xevent_mask = StructureNotifyMask;
1613 for (i = 0; i < nevent_masks; i++)
1615 if (event_mask & (1 << (i + 1)))
1616 xevent_mask |= event_mask_table[i];
1619 XSelectInput (gdk_display, private->xwindow,
1624 gdk_window_add_colormap_windows (GdkWindow *window)
1626 GdkWindow *toplevel;
1627 GdkWindowPrivate *toplevel_private;
1628 GdkWindowPrivate *window_private;
1629 Window *old_windows;
1630 Window *new_windows;
1633 g_return_if_fail (window != NULL);
1635 toplevel = gdk_window_get_toplevel (window);
1636 toplevel_private = (GdkWindowPrivate*) toplevel;
1637 window_private = (GdkWindowPrivate*) window;
1638 if (window_private->destroyed)
1642 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1643 toplevel_private->xwindow,
1644 &old_windows, &count))
1649 for (i = 0; i < count; i++)
1650 if (old_windows[i] == window_private->xwindow)
1652 XFree (old_windows);
1656 new_windows = g_new (Window, count + 1);
1658 for (i = 0; i < count; i++)
1659 new_windows[i] = old_windows[i];
1660 new_windows[count] = window_private->xwindow;
1662 XSetWMColormapWindows (toplevel_private->xdisplay,
1663 toplevel_private->xwindow,
1664 new_windows, count + 1);
1666 g_free (new_windows);
1668 XFree (old_windows);
1672 gdk_window_have_shape_ext (void)
1674 enum { UNKNOWN, NO, YES };
1675 static gint have_shape = UNKNOWN;
1677 if (have_shape == UNKNOWN)
1680 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1686 return (have_shape == YES);
1690 * This needs the X11 shape extension.
1691 * If not available, shaped windows will look
1692 * ugly, but programs still work. Stefan Wille
1695 gdk_window_shape_combine_mask (GdkWindow *window,
1699 GdkWindowPrivate *window_private;
1702 g_return_if_fail (window != NULL);
1704 #ifdef HAVE_SHAPE_EXT
1705 window_private = (GdkWindowPrivate*) window;
1706 if (window_private->destroyed)
1709 if (gdk_window_have_shape_ext())
1713 GdkWindowPrivate *pixmap_private;
1715 pixmap_private = (GdkWindowPrivate*) mask;
1716 pixmap = (Pixmap) pixmap_private->xwindow;
1725 XShapeCombineMask (window_private->xdisplay,
1726 window_private->xwindow,
1732 #endif /* HAVE_SHAPE_EXT */
1736 gdk_window_add_filter (GdkWindow *window,
1737 GdkFilterFunc function,
1740 GdkWindowPrivate *private;
1742 GdkEventFilter *filter;
1744 private = (GdkWindowPrivate*) window;
1745 if (private && private->destroyed)
1749 tmp_list = private->filters;
1751 tmp_list = gdk_default_filters;
1755 filter = (GdkEventFilter *)tmp_list->data;
1756 if ((filter->function == function) && (filter->data == data))
1758 tmp_list = tmp_list->next;
1761 filter = g_new (GdkEventFilter, 1);
1762 filter->function = function;
1763 filter->data = data;
1766 private->filters = g_list_append (private->filters, filter);
1768 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1772 gdk_window_remove_filter (GdkWindow *window,
1773 GdkFilterFunc function,
1776 GdkWindowPrivate *private;
1777 GList *tmp_list, *node;
1778 GdkEventFilter *filter;
1780 private = (GdkWindowPrivate*) window;
1783 tmp_list = private->filters;
1785 tmp_list = gdk_default_filters;
1789 filter = (GdkEventFilter *)tmp_list->data;
1791 tmp_list = tmp_list->next;
1793 if ((filter->function == function) && (filter->data == data))
1796 private->filters = g_list_remove_link (private->filters, node);
1798 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1799 g_list_free_1 (node);
1808 gdk_window_set_override_redirect(GdkWindow *window,
1809 gboolean override_redirect)
1811 GdkWindowPrivate *private;
1812 XSetWindowAttributes attr;
1814 g_return_if_fail (window != NULL);
1815 private = (GdkWindowPrivate*) window;
1816 if (private->destroyed)
1819 attr.override_redirect = (override_redirect == FALSE)?False:True;
1820 XChangeWindowAttributes(gdk_display,
1821 ((GdkWindowPrivate *)window)->xwindow,
1827 gdk_window_set_icon (GdkWindow *window,
1828 GdkWindow *icon_window,
1833 GdkWindowPrivate *window_private;
1834 GdkWindowPrivate *private;
1836 g_return_if_fail (window != NULL);
1837 window_private = (GdkWindowPrivate*) window;
1838 if (window_private->destroyed)
1843 if (icon_window != NULL)
1845 private = (GdkWindowPrivate *)icon_window;
1846 wm_hints.flags |= IconWindowHint;
1847 wm_hints.icon_window = private->xwindow;
1852 private = (GdkWindowPrivate *)pixmap;
1853 wm_hints.flags |= IconPixmapHint;
1854 wm_hints.icon_pixmap = private->xwindow;
1859 private = (GdkWindowPrivate *)mask;
1860 wm_hints.flags |= IconMaskHint;
1861 wm_hints.icon_mask = private->xwindow;
1864 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1868 gdk_window_set_icon_name (GdkWindow *window,
1871 GdkWindowPrivate *window_private;
1872 XTextProperty property;
1875 g_return_if_fail (window != NULL);
1876 window_private = (GdkWindowPrivate*) window;
1877 if (window_private->destroyed)
1879 res = XmbTextListToTextProperty (window_private->xdisplay,
1880 &name, 1, XStdICCTextStyle,
1884 g_warning("Error converting icon name to text property: %d\n", res);
1888 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1892 XFree (property.value);
1896 gdk_window_set_group (GdkWindow *window,
1900 GdkWindowPrivate *window_private;
1901 GdkWindowPrivate *private;
1903 g_return_if_fail (window != NULL);
1904 g_return_if_fail (leader != NULL);
1905 window_private = (GdkWindowPrivate*) window;
1906 if (window_private->destroyed)
1909 private = (GdkWindowPrivate *)leader;
1910 wm_hints.flags = WindowGroupHint;
1911 wm_hints.window_group = private->xwindow;
1913 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1917 gdk_window_set_mwm_hints (GdkWindow *window,
1918 MotifWmHints *new_hints)
1920 static Atom hints_atom = None;
1921 MotifWmHints *hints;
1927 GdkWindowPrivate *window_private;
1929 g_return_if_fail (window != NULL);
1930 window_private = (GdkWindowPrivate*) window;
1931 if (window_private->destroyed)
1935 hints_atom = XInternAtom (window_private->xdisplay,
1936 _XA_MOTIF_WM_HINTS, FALSE);
1938 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1939 hints_atom, 0, sizeof(MotifWmHints)/4,
1940 False, AnyPropertyType, &type, &format, &nitems,
1941 &bytes_after, (guchar **)&hints);
1947 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1949 hints->flags |= MWM_HINTS_FUNCTIONS;
1950 hints->functions = new_hints->functions;
1952 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1954 hints->flags |= MWM_HINTS_DECORATIONS;
1955 hints->decorations = new_hints->decorations;
1959 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1960 hints_atom, hints_atom, 32, PropModeReplace,
1961 (guchar *)hints, sizeof(MotifWmHints)/4);
1963 if (hints != new_hints)
1968 gdk_window_set_decorations (GdkWindow *window,
1969 GdkWMDecoration decorations)
1973 hints.flags = MWM_HINTS_DECORATIONS;
1974 hints.decorations = decorations;
1976 gdk_window_set_mwm_hints (window, &hints);
1980 gdk_window_set_functions (GdkWindow *window,
1981 GdkWMFunction functions)
1985 hints.flags = MWM_HINTS_FUNCTIONS;
1986 hints.functions = functions;
1988 gdk_window_set_mwm_hints (window, &hints);
1992 gdk_window_get_toplevels (void)
1994 GList *new_list = NULL;
1997 tmp_list = gdk_root_parent.children;
2000 new_list = g_list_prepend (new_list, tmp_list->data);
2001 tmp_list = tmp_list->next;
2008 * propagate the shapes from all child windows of a GDK window to the parent
2009 * window. Shamelessly ripped from Enlightenment's code
2018 struct _gdk_span *next;
2022 gdk_add_to_span(struct _gdk_span **s, int x, int xx)
2024 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2031 /* scan the spans for this line */
2034 /* -- -> new span */
2035 /* == -> existing span */
2036 /* ## -> spans intersect */
2037 /* if we are in the middle of spanning the span into the line */
2040 /* case: ---- ==== */
2041 if (xx < ptr1->start - 1)
2043 /* ends before next span - extend to here */
2047 /* case: ----##=== */
2048 else if (xx <= ptr1->end)
2050 /* crosses into next span - delete next span and append */
2051 ss->end = ptr1->end;
2052 ss->next = ptr1->next;
2056 /* case: ---###--- */
2059 /* overlaps next span - delete and keep checking */
2060 ss->next = ptr1->next;
2065 /* otherwise havent started spanning it in yet */
2068 /* case: ---- ==== */
2069 if (xx < ptr1->start - 1)
2071 /* insert span here in list */
2072 noo = g_malloc(sizeof(struct _gdk_span));
2086 /* case: ----##=== */
2087 else if ((x < ptr1->start) && (xx <= ptr1->end))
2089 /* expand this span to the left point of the new one */
2093 /* case: ===###=== */
2094 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2096 /* throw the span away */
2099 /* case: ---###--- */
2100 else if ((x < ptr1->start) && (xx > ptr1->end))
2107 /* case: ===##---- */
2108 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2114 /* case: ==== ---- */
2115 /* case handled by next loop iteration - first case */
2120 /* it started in the middle but spans beyond your current list */
2126 /* it does not start inside a span or in the middle, so add it to the end */
2127 noo = g_malloc(sizeof(struct _gdk_span));
2135 noo->next = ptr2->next;
2148 gdk_add_rectangles (Display *disp, Window win, struct _gdk_span **spans,
2149 gint basew, gint baseh, gint x, gint y)
2152 gint x1, y1, x2, y2;
2156 rl = XShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord);
2159 /* go through all clip rects in this window's shape */
2160 for (k = 0; k < rn; k++)
2162 /* for each clip rect, add it to each line's spans */
2164 x2 = x + rl[k].x + (rl[k].width - 1);
2166 y2 = y + rl[k].y + (rl[k].height - 1);
2175 for (a = y1; a <= y2; a++)
2178 gdk_add_to_span(&spans[a], x1, x2);
2186 gdk_propagate_shapes(Display *disp, Window win, gboolean merge)
2188 Window rt, par, *list = NULL;
2189 gint i, j, num = 0, num_rects = 0;
2193 XRectangle *rects = NULL;
2194 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2195 XWindowAttributes xatt;
2197 XGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d);
2202 spans = g_malloc(sizeof(struct _gdk_span *) * h);
2204 for (i = 0; i < h; i++)
2206 XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num);
2209 /* go through all child windows and create/insert spans */
2210 for (i = 0; i < num; i++)
2212 if (XGetWindowAttributes(disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2213 if (XGetGeometry(disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2214 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2217 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2219 /* go through the spans list and build a list of rects */
2220 rects = g_malloc(sizeof(XRectangle) * 256);
2222 for (i = 0; i < baseh; i++)
2225 /* go through the line for all spans */
2228 rects[num_rects].x = ptr1->start;
2229 rects[num_rects].y = i;
2230 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2231 rects[num_rects].height = 1;
2233 /* if there are more lines */
2235 /* while contigous rects (same start/end coords) exist */
2236 while ((contig) && (j < baseh))
2238 /* search next line for spans matching this one */
2244 /* if we have an exact span match set contig */
2245 if ((ptr2->start == ptr1->start) &&
2246 (ptr2->end == ptr1->end))
2249 /* remove the span - not needed */
2252 ptr3->next = ptr2->next;
2258 spans[j] = ptr2->next;
2264 /* gone past the span point no point looking */
2265 else if (ptr2->start < ptr1->start)
2273 /* if a contiguous span was found increase the rect h */
2276 rects[num_rects].height++;
2280 /* up the rect count */
2282 /* every 256 new rects increase the rect array */
2283 if ((num_rects % 256) == 0)
2284 rects = g_realloc(rects, sizeof(XRectangle) * (num_rects + 256));
2288 /* set the rects as the shape mask */
2291 XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects,
2292 ShapeSet, YXSorted);
2297 /* free up all the spans we made */
2298 for (i = 0; i < baseh; i++)
2312 gdk_window_set_child_shapes (GdkWindow *window)
2314 GdkWindowPrivate *private;
2316 g_return_if_fail (window != NULL);
2318 #ifdef HAVE_SHAPE_EXT
2319 private = (GdkWindowPrivate*) window;
2320 if (private->destroyed)
2323 if (gdk_window_have_shape_ext())
2324 gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
2329 gdk_window_merge_child_shapes (GdkWindow *window)
2331 GdkWindowPrivate *private;
2333 g_return_if_fail (window != NULL);
2335 #ifdef HAVE_SHAPE_EXT
2336 private = (GdkWindowPrivate*) window;
2337 if (private->destroyed)
2340 if (gdk_window_have_shape_ext())
2341 gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
2346 gdk_drawable_set_data (GdkDrawable *drawable,
2349 GDestroyNotify destroy_func)
2351 g_dataset_set_data_full (drawable, key, data, destroy_func);