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>
25 #include "../config.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
62 /* internal function created for and used by gdk_window_xid_at_coords */
64 gdk_window_xid_at (Window base,
73 GdkWindowPrivate *private;
76 Window child = 0, parent_win = 0, root_win = 0;
78 unsigned int ww, wh, wb, wd, num;
81 window = (GdkWindow*) &gdk_root_parent;
82 private = (GdkWindowPrivate*) window;
83 disp = private->xdisplay;
84 if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
91 (x < (int) (wx + ww)) &&
92 (y < (int) (wy + wh))))
95 if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
100 for (i = num - 1; ; i--)
102 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
104 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
119 * The following fucntion by The Rasterman <raster@redhat.com>
120 * This function returns the X Window ID in which the x y location is in
121 * (x and y being relative to the root window), excluding any windows listed
122 * in the GList excludes (this is a list of X Window ID's - gpointer being
125 * This is primarily designed for internal gdk use - for DND for example
126 * when using a shaped icon window as the drag object - you exclude the
127 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
128 * You can get back an X Window ID as to what X Window ID is infact under
129 * those X,Y co-ordinates.
132 gdk_window_xid_at_coords (gint x,
138 GdkWindowPrivate *private;
141 Window root, child = 0, parent_win = 0, root_win = 0;
145 window = (GdkWindow*) &gdk_root_parent;
146 private = (GdkWindowPrivate*) window;
147 disp = private->xdisplay;
148 root = private->xwindow;
149 num = g_list_length (excludes);
152 if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
162 XWindowAttributes xwa;
164 XGetWindowAttributes (disp, list [i], &xwa);
166 if (xwa.map_state != IsViewable)
169 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
172 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
177 if (!g_list_find (excludes, (gpointer *) child))
180 XUngrabServer (disp);
187 XUngrabServer (disp);
193 XUngrabServer (disp);
198 gdk_window_init (void)
200 XWindowAttributes xattributes;
203 unsigned int border_width;
207 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
208 &x, &y, &width, &height, &border_width, &depth);
209 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
211 gdk_root_parent.xwindow = gdk_root_window;
212 gdk_root_parent.xdisplay = gdk_display;
213 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
214 gdk_root_parent.window.user_data = NULL;
215 gdk_root_parent.width = width;
216 gdk_root_parent.height = height;
217 gdk_root_parent.children = NULL;
218 gdk_root_parent.colormap = NULL;
219 gdk_root_parent.ref_count = 1;
221 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
225 gdk_window_new (GdkWindow *parent,
226 GdkWindowAttr *attributes,
227 gint attributes_mask)
230 GdkWindowPrivate *private;
231 GdkWindowPrivate *parent_private;
233 Display *parent_display;
236 XSetWindowAttributes xattributes;
237 long xattributes_mask;
238 XSizeHints size_hints;
240 XClassHint *class_hint;
246 g_return_val_if_fail (attributes != NULL, NULL);
249 parent = (GdkWindow*) &gdk_root_parent;
251 parent_private = (GdkWindowPrivate*) parent;
252 if (parent_private->destroyed)
255 xparent = parent_private->xwindow;
256 parent_display = parent_private->xdisplay;
258 private = g_new (GdkWindowPrivate, 1);
259 window = (GdkWindow*) private;
261 private->parent = parent;
264 parent_private->children = g_list_prepend (parent_private->children, window);
266 private->xdisplay = parent_display;
267 private->destroyed = FALSE;
268 private->resize_count = 0;
269 private->ref_count = 1;
270 xattributes_mask = 0;
272 if (attributes_mask & GDK_WA_X)
277 if (attributes_mask & GDK_WA_Y)
284 private->width = (attributes->width > 1) ? (attributes->width) : (1);
285 private->height = (attributes->height > 1) ? (attributes->height) : (1);
286 private->window_type = attributes->window_type;
287 private->extension_events = FALSE;
288 private->dnd_drag_data_type = None;
289 private->dnd_drag_data_typesavail =
290 private->dnd_drop_data_typesavail = NULL;
291 private->dnd_drop_enabled = private->dnd_drag_enabled =
292 private->dnd_drag_accepted = private->dnd_drag_datashow =
293 private->dnd_drop_data_numtypesavail =
294 private->dnd_drag_data_numtypesavail = 0;
295 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
297 private->filters = NULL;
298 private->children = NULL;
300 window->user_data = NULL;
302 if (attributes_mask & GDK_WA_VISUAL)
303 visual = attributes->visual;
305 visual = gdk_visual_get_system ();
306 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
308 xattributes.event_mask = StructureNotifyMask;
309 for (i = 0; i < nevent_masks; i++)
311 if (attributes->event_mask & (1 << (i + 1)))
312 xattributes.event_mask |= event_mask_table[i];
315 if (xattributes.event_mask)
316 xattributes_mask |= CWEventMask;
318 if(attributes_mask & GDK_WA_NOREDIR) {
319 xattributes.override_redirect =
320 (attributes->override_redirect == FALSE)?False:True;
321 xattributes_mask |= CWOverrideRedirect;
323 xattributes.override_redirect = False;
325 if (attributes->wclass == GDK_INPUT_OUTPUT)
328 depth = visual->depth;
330 if (attributes_mask & GDK_WA_COLORMAP)
331 private->colormap = attributes->colormap;
333 private->colormap = gdk_colormap_get_system ();
335 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
336 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
337 xattributes_mask |= CWBorderPixel | CWBackPixel;
339 switch (private->window_type)
341 case GDK_WINDOW_TOPLEVEL:
342 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
343 xattributes_mask |= CWColormap;
345 xparent = gdk_root_window;
348 case GDK_WINDOW_CHILD:
349 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
350 xattributes_mask |= CWColormap;
353 case GDK_WINDOW_DIALOG:
354 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
355 xattributes_mask |= CWColormap;
357 xparent = gdk_root_window;
360 case GDK_WINDOW_TEMP:
361 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
362 xattributes_mask |= CWColormap;
364 xparent = gdk_root_window;
366 xattributes.save_under = True;
367 xattributes.override_redirect = True;
368 xattributes.cursor = None;
369 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
371 case GDK_WINDOW_ROOT:
372 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
374 case GDK_WINDOW_PIXMAP:
375 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
383 private->colormap = NULL;
386 private->xwindow = XCreateWindow (private->xdisplay, xparent,
387 x, y, private->width, private->height,
388 0, depth, class, xvisual,
389 xattributes_mask, &xattributes);
390 gdk_window_ref (window);
391 gdk_xid_table_insert (&private->xwindow, window);
393 if (private->colormap)
394 gdk_colormap_ref (private->colormap);
396 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
397 (attributes->cursor) :
400 switch (private->window_type)
402 case GDK_WINDOW_DIALOG:
403 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
404 case GDK_WINDOW_TOPLEVEL:
405 case GDK_WINDOW_TEMP:
406 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
408 case GDK_WINDOW_CHILD:
409 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
410 (private->colormap != gdk_colormap_get_system ()) &&
411 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
413 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
414 gdk_window_add_colormap_windows (window);
423 size_hints.flags = PSize;
424 size_hints.width = private->width;
425 size_hints.height = private->height;
427 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
428 wm_hints.window_group = gdk_leader_window;
429 wm_hints.input = True;
430 wm_hints.initial_state = NormalState;
432 /* FIXME: Is there any point in doing this? Do any WM's pay
433 * attention to PSize, and even if they do, is this the
436 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
438 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
440 if (attributes_mask & GDK_WA_TITLE)
441 title = attributes->title;
443 title = g_get_prgname ();
445 XmbSetWMProperties (private->xdisplay, private->xwindow,
450 if (attributes_mask & GDK_WA_WMCLASS)
452 class_hint = XAllocClassHint ();
453 class_hint->res_name = attributes->wmclass_name;
454 class_hint->res_class = attributes->wmclass_class;
455 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
464 gdk_window_foreign_new (guint32 anid)
467 GdkWindowPrivate *private;
468 GdkWindowPrivate *parent_private;
469 XWindowAttributes attrs;
471 Window *children = NULL;
474 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
475 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
479 private = g_new (GdkWindowPrivate, 1);
480 window = (GdkWindow*) private;
482 /* FIXME: This is pretty expensive. Maybe the caller should supply
484 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
488 private->parent = gdk_xid_table_lookup (parent);
490 parent_private = (GdkWindowPrivate *)private->parent;
493 parent_private->children = g_list_prepend (parent_private->children, window);
495 private->xwindow = anid;
496 private->xdisplay = gdk_display;
497 private->x = attrs.x;
498 private->y = attrs.y;
499 private->width = attrs.width;
500 private->height = attrs.height;
501 private->resize_count = 0;
502 private->ref_count = 1;
503 private->window_type = GDK_WINDOW_FOREIGN;
504 private->destroyed = FALSE;
505 private->extension_events = 0;
507 private->colormap = NULL;
509 private->dnd_drag_data_type = None;
510 private->dnd_drag_data_typesavail =
511 private->dnd_drop_data_typesavail = NULL;
512 private->dnd_drop_enabled = private->dnd_drag_enabled =
513 private->dnd_drag_accepted = private->dnd_drag_datashow =
514 private->dnd_drop_data_numtypesavail =
515 private->dnd_drag_data_numtypesavail = 0;
516 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
518 private->filters = NULL;
519 private->children = NULL;
521 window->user_data = NULL;
523 gdk_window_ref (window);
524 gdk_xid_table_insert (&private->xwindow, window);
529 /* Call this function when you want a window and all its children to
530 disappear. When xdestroy is true, a request to destroy the XWindow
531 is sent out. When it is false, it is assumed that the XWindow has
532 been or will be destroyed by destroying some ancestor of this
536 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
537 gboolean our_destroy)
539 GdkWindowPrivate *private;
540 GdkWindowPrivate *temp_private;
541 GdkWindow *temp_window;
545 g_return_if_fail (window != NULL);
547 private = (GdkWindowPrivate*) window;
549 switch (private->window_type)
551 case GDK_WINDOW_TOPLEVEL:
552 case GDK_WINDOW_CHILD:
553 case GDK_WINDOW_DIALOG:
554 case GDK_WINDOW_TEMP:
555 case GDK_WINDOW_FOREIGN:
556 if (!private->destroyed)
560 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
561 if (parent_private->children)
562 parent_private->children = g_list_remove (parent_private->children, window);
565 if (private->window_type != GDK_WINDOW_FOREIGN)
567 children = tmp = private->children;
568 private->children = NULL;
572 temp_window = tmp->data;
575 temp_private = (GdkWindowPrivate*) temp_window;
577 gdk_window_internal_destroy (temp_window, FALSE,
581 g_list_free (children);
584 if (private->extension_events != 0)
585 gdk_input_window_destroy (window);
587 if(private->dnd_drag_data_numtypesavail > 0)
589 g_free (private->dnd_drag_data_typesavail);
590 private->dnd_drag_data_typesavail = NULL;
592 if(private->dnd_drop_data_numtypesavail > 0)
594 g_free (private->dnd_drop_data_typesavail);
595 private->dnd_drop_data_typesavail = NULL;
598 if (private->filters)
600 tmp = private->filters;
608 g_list_free (private->filters);
609 private->filters = NULL;
612 if (private->window_type == GDK_WINDOW_FOREIGN)
614 if (our_destroy && (private->parent != NULL))
616 /* It's somebody elses window, but in our heirarchy,
617 * so reparent it to the root window, and then send
618 * it a delete event, as if we were a WM
620 XClientMessageEvent xevent;
622 gdk_window_hide (window);
623 gdk_window_reparent (window, NULL, 0, 0);
625 xevent.type = ClientMessage;
626 xevent.window = private->xwindow;
627 xevent.message_type = gdk_wm_protocols;
629 xevent.data.l[0] = gdk_wm_delete_window;
630 xevent.data.l[1] = CurrentTime;
632 XSendEvent (private->xdisplay, private->xwindow,
633 False, 0, (XEvent *)&xevent);
637 XDestroyWindow (private->xdisplay, private->xwindow);
639 if (private->colormap)
640 gdk_colormap_unref (private->colormap);
642 private->destroyed = TRUE;
646 case GDK_WINDOW_ROOT:
647 g_error ("attempted to destroy root window");
650 case GDK_WINDOW_PIXMAP:
651 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
656 /* Like internal_destroy, but also destroys the reference created by
660 gdk_window_destroy (GdkWindow *window)
662 gdk_window_internal_destroy (window, TRUE, TRUE);
663 gdk_window_unref (window);
666 /* This function is called when the XWindow is really gone. */
669 gdk_window_destroy_notify (GdkWindow *window)
671 GdkWindowPrivate *private;
673 g_return_if_fail (window != NULL);
675 private = (GdkWindowPrivate*) window;
677 if (!private->destroyed)
679 if (private->window_type == GDK_WINDOW_FOREIGN)
680 gdk_window_internal_destroy (window, FALSE, FALSE);
682 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
685 gdk_xid_table_remove (private->xwindow);
686 gdk_window_unref (window);
690 gdk_window_ref (GdkWindow *window)
692 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
693 g_return_val_if_fail (window != NULL, NULL);
695 private->ref_count += 1;
700 gdk_window_unref (GdkWindow *window)
702 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
703 g_return_if_fail (window != NULL);
705 private->ref_count -= 1;
706 if (private->ref_count == 0)
708 if (!private->destroyed)
710 if (private->window_type == GDK_WINDOW_FOREIGN)
711 gdk_xid_table_remove (private->xwindow);
713 g_warning ("losing last reference to undestroyed window\n");
715 g_dataset_destroy (window);
721 gdk_window_show (GdkWindow *window)
723 GdkWindowPrivate *private;
725 g_return_if_fail (window != NULL);
727 private = (GdkWindowPrivate*) window;
728 if (!private->destroyed)
730 XRaiseWindow (private->xdisplay, private->xwindow);
731 XMapWindow (private->xdisplay, private->xwindow);
736 gdk_window_hide (GdkWindow *window)
738 GdkWindowPrivate *private;
740 g_return_if_fail (window != NULL);
742 private = (GdkWindowPrivate*) window;
743 if (!private->destroyed)
744 XUnmapWindow (private->xdisplay, private->xwindow);
748 gdk_window_withdraw (GdkWindow *window)
750 GdkWindowPrivate *private;
752 g_return_if_fail (window != NULL);
754 private = (GdkWindowPrivate*) window;
755 if (!private->destroyed)
756 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
760 gdk_window_move (GdkWindow *window,
764 GdkWindowPrivate *private;
766 g_return_if_fail (window != NULL);
768 private = (GdkWindowPrivate*) window;
769 if (!private->destroyed)
771 XMoveWindow (private->xdisplay, private->xwindow, x, y);
773 if (private->window_type == GDK_WINDOW_CHILD)
782 gdk_window_resize (GdkWindow *window,
786 GdkWindowPrivate *private;
788 g_return_if_fail (window != NULL);
795 private = (GdkWindowPrivate*) window;
797 if (!private->destroyed &&
798 ((private->resize_count > 0) ||
799 (private->width != (guint16) width) ||
800 (private->height != (guint16) height)))
802 XResizeWindow (private->xdisplay, private->xwindow, width, height);
803 private->resize_count += 1;
805 if (private->window_type == GDK_WINDOW_CHILD)
807 private->width = width;
808 private->height = height;
814 gdk_window_move_resize (GdkWindow *window,
820 GdkWindowPrivate *private;
822 g_return_if_fail (window != NULL);
829 private = (GdkWindowPrivate*) window;
830 if (!private->destroyed)
832 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
834 if (private->window_type == GDK_WINDOW_CHILD)
838 private->width = width;
839 private->height = height;
845 gdk_window_reparent (GdkWindow *window,
846 GdkWindow *new_parent,
850 GdkWindowPrivate *window_private;
851 GdkWindowPrivate *parent_private;
852 GdkWindowPrivate *old_parent_private;
854 g_return_if_fail (window != NULL);
857 new_parent = (GdkWindow*) &gdk_root_parent;
859 window_private = (GdkWindowPrivate*) window;
860 old_parent_private = (GdkWindowPrivate*)window_private->parent;
861 parent_private = (GdkWindowPrivate*) new_parent;
863 if (!window_private->destroyed && !parent_private->destroyed)
864 XReparentWindow (window_private->xdisplay,
865 window_private->xwindow,
866 parent_private->xwindow,
869 window_private->parent = new_parent;
871 if (old_parent_private)
872 old_parent_private->children = g_list_remove (old_parent_private->children, window);
873 parent_private->children = g_list_prepend (parent_private->children, window);
878 gdk_window_clear (GdkWindow *window)
880 GdkWindowPrivate *private;
882 g_return_if_fail (window != NULL);
884 private = (GdkWindowPrivate*) window;
886 if (!private->destroyed)
887 XClearWindow (private->xdisplay, private->xwindow);
891 gdk_window_clear_area (GdkWindow *window,
897 GdkWindowPrivate *private;
899 g_return_if_fail (window != NULL);
901 private = (GdkWindowPrivate*) window;
903 if (!private->destroyed)
904 XClearArea (private->xdisplay, private->xwindow,
905 x, y, width, height, False);
909 gdk_window_clear_area_e (GdkWindow *window,
915 GdkWindowPrivate *private;
917 g_return_if_fail (window != NULL);
919 private = (GdkWindowPrivate*) window;
921 if (!private->destroyed)
922 XClearArea (private->xdisplay, private->xwindow,
923 x, y, width, height, True);
927 gdk_window_copy_area (GdkWindow *window,
931 GdkWindow *source_window,
937 GdkWindowPrivate *src_private;
938 GdkWindowPrivate *dest_private;
939 GdkGCPrivate *gc_private;
941 g_return_if_fail (window != NULL);
942 g_return_if_fail (gc != NULL);
944 if (source_window == NULL)
945 source_window = window;
947 src_private = (GdkWindowPrivate*) source_window;
948 dest_private = (GdkWindowPrivate*) window;
949 gc_private = (GdkGCPrivate*) gc;
951 if (!src_private->destroyed && !dest_private->destroyed)
953 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
962 gdk_window_raise (GdkWindow *window)
964 GdkWindowPrivate *private;
966 g_return_if_fail (window != NULL);
968 private = (GdkWindowPrivate*) window;
970 if (!private->destroyed)
971 XRaiseWindow (private->xdisplay, private->xwindow);
975 gdk_window_lower (GdkWindow *window)
977 GdkWindowPrivate *private;
979 g_return_if_fail (window != NULL);
981 private = (GdkWindowPrivate*) window;
983 if (!private->destroyed)
984 XLowerWindow (private->xdisplay, private->xwindow);
988 gdk_window_set_user_data (GdkWindow *window,
991 g_return_if_fail (window != NULL);
993 window->user_data = user_data;
997 gdk_window_set_hints (GdkWindow *window,
1006 GdkWindowPrivate *private;
1007 XSizeHints size_hints;
1009 g_return_if_fail (window != NULL);
1011 private = (GdkWindowPrivate*) window;
1012 if (private->destroyed)
1015 size_hints.flags = 0;
1017 if (flags & GDK_HINT_POS)
1019 size_hints.flags |= PPosition;
1024 if (flags & GDK_HINT_MIN_SIZE)
1026 size_hints.flags |= PMinSize;
1027 size_hints.min_width = min_width;
1028 size_hints.min_height = min_height;
1031 if (flags & GDK_HINT_MAX_SIZE)
1033 size_hints.flags |= PMaxSize;
1034 size_hints.max_width = max_width;
1035 size_hints.max_height = max_height;
1039 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1043 gdk_window_set_title (GdkWindow *window,
1046 GdkWindowPrivate *private;
1048 g_return_if_fail (window != NULL);
1050 private = (GdkWindowPrivate*) window;
1051 if (!private->destroyed)
1052 XmbSetWMProperties (private->xdisplay, private->xwindow,
1053 title, title, NULL, 0, NULL, NULL, NULL);
1057 gdk_window_set_background (GdkWindow *window,
1060 GdkWindowPrivate *private;
1062 g_return_if_fail (window != NULL);
1064 private = (GdkWindowPrivate*) window;
1065 if (!private->destroyed)
1066 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1070 gdk_window_set_back_pixmap (GdkWindow *window,
1072 gint parent_relative)
1074 GdkWindowPrivate *window_private;
1075 GdkPixmapPrivate *pixmap_private;
1078 g_return_if_fail (window != NULL);
1080 window_private = (GdkWindowPrivate*) window;
1081 pixmap_private = (GdkPixmapPrivate*) pixmap;
1084 xpixmap = pixmap_private->xwindow;
1088 if (parent_relative)
1089 xpixmap = ParentRelative;
1091 if (!window_private->destroyed)
1092 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1096 gdk_window_set_cursor (GdkWindow *window,
1099 GdkWindowPrivate *window_private;
1100 GdkCursorPrivate *cursor_private;
1103 g_return_if_fail (window != NULL);
1105 window_private = (GdkWindowPrivate*) window;
1106 cursor_private = (GdkCursorPrivate*) cursor;
1111 xcursor = cursor_private->xcursor;
1113 if (!window_private->destroyed)
1114 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1118 gdk_window_set_colormap (GdkWindow *window,
1119 GdkColormap *colormap)
1121 GdkWindowPrivate *window_private;
1122 GdkColormapPrivate *colormap_private;
1124 g_return_if_fail (window != NULL);
1125 g_return_if_fail (colormap != NULL);
1127 window_private = (GdkWindowPrivate*) window;
1128 colormap_private = (GdkColormapPrivate*) colormap;
1130 if (!window_private->destroyed)
1132 XSetWindowColormap (window_private->xdisplay,
1133 window_private->xwindow,
1134 colormap_private->xcolormap);
1136 if (window_private->colormap)
1137 gdk_colormap_unref (window_private->colormap);
1138 window_private->colormap = colormap;
1139 gdk_colormap_ref (window_private->colormap);
1141 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1142 gdk_window_add_colormap_windows (window);
1147 gdk_window_get_user_data (GdkWindow *window,
1150 g_return_if_fail (window != NULL);
1152 *data = window->user_data;
1156 gdk_window_get_geometry (GdkWindow *window,
1163 GdkWindowPrivate *window_private;
1169 guint tborder_width;
1173 window = (GdkWindow*) &gdk_root_parent;
1175 window_private = (GdkWindowPrivate*) window;
1177 if (!window_private->destroyed)
1179 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1180 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1196 gdk_window_get_position (GdkWindow *window,
1200 GdkWindowPrivate *window_private;
1202 g_return_if_fail (window != NULL);
1204 window_private = (GdkWindowPrivate*) window;
1207 *x = window_private->x;
1209 *y = window_private->y;
1213 gdk_window_get_size (GdkWindow *window,
1217 GdkWindowPrivate *window_private;
1219 g_return_if_fail (window != NULL);
1221 window_private = (GdkWindowPrivate*) window;
1224 *width = window_private->width;
1226 *height = window_private->height;
1230 gdk_window_get_visual (GdkWindow *window)
1232 GdkWindowPrivate *window_private;
1233 XWindowAttributes window_attributes;
1235 g_return_val_if_fail (window != NULL, NULL);
1237 window_private = (GdkWindowPrivate*) window;
1238 /* Huh? ->parent is never set for a pixmap. We should just return
1241 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1242 window_private = (GdkWindowPrivate*) window_private->parent;
1244 if (window_private && !window_private->destroyed)
1246 if (window_private->colormap == NULL)
1248 XGetWindowAttributes (window_private->xdisplay,
1249 window_private->xwindow,
1250 &window_attributes);
1251 return gdk_visual_lookup (window_attributes.visual);
1254 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1261 gdk_window_get_colormap (GdkWindow *window)
1263 GdkWindowPrivate *window_private;
1264 XWindowAttributes window_attributes;
1266 g_return_val_if_fail (window != NULL, NULL);
1267 window_private = (GdkWindowPrivate*) window;
1269 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1270 if (!window_private->destroyed)
1272 if (window_private->colormap == NULL)
1274 XGetWindowAttributes (window_private->xdisplay,
1275 window_private->xwindow,
1276 &window_attributes);
1277 return gdk_colormap_lookup (window_attributes.colormap);
1280 return window_private->colormap;
1287 gdk_window_get_type (GdkWindow *window)
1289 GdkWindowPrivate *window_private;
1291 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1293 window_private = (GdkWindowPrivate*) window;
1294 return window_private->window_type;
1298 gdk_window_get_origin (GdkWindow *window,
1302 GdkWindowPrivate *private;
1308 g_return_val_if_fail (window != NULL, 0);
1310 private = (GdkWindowPrivate*) window;
1312 if (!private->destroyed)
1314 return_val = XTranslateCoordinates (private->xdisplay,
1333 gdk_window_get_root_origin (GdkWindow *window,
1337 GdkWindowPrivate *private;
1342 unsigned int nchildren;
1344 g_return_if_fail (window != NULL);
1346 private = (GdkWindowPrivate*) window;
1351 if (private->destroyed)
1354 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1355 private = (GdkWindowPrivate*) private->parent;
1356 if (private->destroyed)
1359 xparent = private->xwindow;
1363 if (!XQueryTree (private->xdisplay, xwindow,
1365 &children, &nchildren))
1371 while (xparent != root);
1373 if (xparent == root)
1375 unsigned int ww, wh, wb, wd;
1378 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1389 gdk_window_get_pointer (GdkWindow *window,
1392 GdkModifierType *mask)
1394 GdkWindowPrivate *private;
1395 GdkWindow *return_val;
1401 unsigned int xmask = 0;
1404 window = (GdkWindow*) &gdk_root_parent;
1406 private = (GdkWindowPrivate*) window;
1409 if (!private->destroyed &&
1410 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1411 &rootx, &rooty, &winx, &winy, &xmask))
1414 return_val = gdk_window_lookup (child);
1428 gdk_window_at_pointer (gint *win_x,
1431 GdkWindowPrivate *private;
1435 Window xwindow_last = 0;
1436 int rootx = -1, rooty = -1;
1440 private = &gdk_root_parent;
1442 xwindow = private->xwindow;
1444 XGrabServer (private->xdisplay);
1447 xwindow_last = xwindow;
1448 XQueryPointer (private->xdisplay,
1455 XUngrabServer (private->xdisplay);
1457 window = gdk_window_lookup (xwindow_last);
1460 *win_x = window ? winx : -1;
1462 *win_y = window ? winy : -1;
1468 gdk_window_get_parent (GdkWindow *window)
1470 g_return_val_if_fail (window != NULL, NULL);
1472 return ((GdkWindowPrivate*) window)->parent;
1476 gdk_window_get_toplevel (GdkWindow *window)
1478 GdkWindowPrivate *private;
1480 g_return_val_if_fail (window != NULL, NULL);
1482 private = (GdkWindowPrivate*) window;
1484 while (private->window_type == GDK_WINDOW_CHILD)
1486 window = ((GdkWindowPrivate*) window)->parent;
1487 private = (GdkWindowPrivate*) window;
1494 gdk_window_get_children (GdkWindow *window)
1496 GdkWindowPrivate *private;
1502 unsigned int nchildren;
1505 g_return_val_if_fail (window != NULL, NULL);
1507 private = (GdkWindowPrivate*) window;
1508 if (private->destroyed)
1511 XQueryTree (private->xdisplay, private->xwindow,
1512 &root, &parent, &xchildren, &nchildren);
1518 for (i = 0; i < nchildren; i++)
1520 child = gdk_window_lookup (xchildren[i]);
1522 children = g_list_prepend (children, child);
1533 gdk_window_get_events (GdkWindow *window)
1535 GdkWindowPrivate *private;
1536 XWindowAttributes attrs;
1537 GdkEventMask event_mask;
1540 g_return_val_if_fail (window != NULL, 0);
1542 private = (GdkWindowPrivate*) window;
1543 if (private->destroyed)
1546 XGetWindowAttributes (gdk_display, private->xwindow,
1550 for (i = 0; i < nevent_masks; i++)
1552 if (attrs.your_event_mask & event_mask_table[i])
1553 event_mask |= 1 << (i + 1);
1560 gdk_window_set_events (GdkWindow *window,
1561 GdkEventMask event_mask)
1563 GdkWindowPrivate *private;
1567 g_return_if_fail (window != NULL);
1569 private = (GdkWindowPrivate*) window;
1570 if (private->destroyed)
1573 xevent_mask = StructureNotifyMask;
1574 for (i = 0; i < nevent_masks; i++)
1576 if (event_mask & (1 << (i + 1)))
1577 xevent_mask |= event_mask_table[i];
1580 XSelectInput (gdk_display, private->xwindow,
1585 gdk_window_add_colormap_windows (GdkWindow *window)
1587 GdkWindow *toplevel;
1588 GdkWindowPrivate *toplevel_private;
1589 GdkWindowPrivate *window_private;
1590 Window *old_windows;
1591 Window *new_windows;
1594 g_return_if_fail (window != NULL);
1596 toplevel = gdk_window_get_toplevel (window);
1597 toplevel_private = (GdkWindowPrivate*) toplevel;
1598 window_private = (GdkWindowPrivate*) window;
1599 if (window_private->destroyed)
1603 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1604 toplevel_private->xwindow,
1605 &old_windows, &count))
1610 for (i = 0; i < count; i++)
1611 if (old_windows[i] == window_private->xwindow)
1613 XFree (old_windows);
1617 new_windows = g_new (Window, count + 1);
1619 for (i = 0; i < count; i++)
1620 new_windows[i] = old_windows[i];
1621 new_windows[count] = window_private->xwindow;
1623 XSetWMColormapWindows (toplevel_private->xdisplay,
1624 toplevel_private->xwindow,
1625 new_windows, count + 1);
1627 g_free (new_windows);
1629 XFree (old_windows);
1633 * This needs the X11 shape extension.
1634 * If not available, shaped windows will look
1635 * ugly, but programs still work. Stefan Wille
1638 gdk_window_shape_combine_mask (GdkWindow *window,
1642 enum { UNKNOWN, NO, YES };
1644 static gint have_shape = UNKNOWN;
1646 GdkWindowPrivate *window_private;
1649 g_return_if_fail (window != NULL);
1651 #ifdef HAVE_SHAPE_EXT
1652 if (have_shape == UNKNOWN)
1655 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1661 if (have_shape == YES)
1663 window_private = (GdkWindowPrivate*) window;
1664 if (window_private->destroyed)
1669 GdkWindowPrivate *pixmap_private;
1671 pixmap_private = (GdkWindowPrivate*) mask;
1672 pixmap = (Pixmap) pixmap_private->xwindow;
1681 XShapeCombineMask (window_private->xdisplay,
1682 window_private->xwindow,
1688 #endif /* HAVE_SHAPE_EXT */
1692 gdk_window_add_filter (GdkWindow *window,
1693 GdkFilterFunc function,
1696 GdkWindowPrivate *private;
1698 GdkEventFilter *filter;
1700 private = (GdkWindowPrivate*) window;
1701 if (private && private->destroyed)
1705 tmp_list = private->filters;
1707 tmp_list = gdk_default_filters;
1711 filter = (GdkEventFilter *)tmp_list->data;
1712 if ((filter->function == function) && (filter->data == data))
1714 tmp_list = tmp_list->next;
1717 filter = g_new (GdkEventFilter, 1);
1718 filter->function = function;
1719 filter->data = data;
1722 private->filters = g_list_append (private->filters, filter);
1724 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1728 gdk_window_remove_filter (GdkWindow *window,
1729 GdkFilterFunc function,
1732 GdkWindowPrivate *private;
1733 GList *tmp_list, *node;
1734 GdkEventFilter *filter;
1736 private = (GdkWindowPrivate*) window;
1739 tmp_list = private->filters;
1741 tmp_list = gdk_default_filters;
1745 filter = (GdkEventFilter *)tmp_list->data;
1747 tmp_list = tmp_list->next;
1749 if ((filter->function == function) && (filter->data == data))
1752 private->filters = g_list_remove_link (private->filters, node);
1754 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1755 g_list_free_1 (node);
1764 gdk_window_set_override_redirect(GdkWindow *window,
1765 gboolean override_redirect)
1767 GdkWindowPrivate *private;
1768 XSetWindowAttributes attr;
1770 g_return_if_fail (window != NULL);
1771 private = (GdkWindowPrivate*) window;
1772 if (private->destroyed)
1775 attr.override_redirect = (override_redirect == FALSE)?False:True;
1776 XChangeWindowAttributes(gdk_display,
1777 ((GdkWindowPrivate *)window)->xwindow,
1783 gdk_window_set_icon (GdkWindow *window,
1784 GdkWindow *icon_window,
1789 GdkWindowPrivate *window_private;
1790 GdkWindowPrivate *private;
1792 g_return_if_fail (window != NULL);
1793 window_private = (GdkWindowPrivate*) window;
1794 if (window_private->destroyed)
1799 if (icon_window != NULL)
1801 private = (GdkWindowPrivate *)icon_window;
1802 wm_hints.flags |= IconWindowHint;
1803 wm_hints.icon_window = private->xwindow;
1808 private = (GdkWindowPrivate *)pixmap;
1809 wm_hints.flags |= IconPixmapHint;
1810 wm_hints.icon_pixmap = private->xwindow;
1815 private = (GdkWindowPrivate *)mask;
1816 wm_hints.flags |= IconMaskHint;
1817 wm_hints.icon_mask = private->xwindow;
1820 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1824 gdk_window_set_icon_name (GdkWindow *window,
1827 GdkWindowPrivate *window_private;
1828 XTextProperty property;
1831 g_return_if_fail (window != NULL);
1832 window_private = (GdkWindowPrivate*) window;
1833 if (window_private->destroyed)
1835 res = XmbTextListToTextProperty (window_private->xdisplay,
1836 &name, 1, XStdICCTextStyle,
1840 g_warning("Error converting icon name to text property: %d\n", res);
1844 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1848 XFree (property.value);
1852 gdk_window_set_group (GdkWindow *window,
1856 GdkWindowPrivate *window_private;
1857 GdkWindowPrivate *private;
1859 g_return_if_fail (window != NULL);
1860 g_return_if_fail (leader != NULL);
1861 window_private = (GdkWindowPrivate*) window;
1862 if (window_private->destroyed)
1865 private = (GdkWindowPrivate *)leader;
1866 wm_hints.flags = WindowGroupHint;
1867 wm_hints.window_group = private->xwindow;
1869 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1873 gdk_window_set_mwm_hints (GdkWindow *window,
1874 MotifWmHints *new_hints)
1876 static Atom hints_atom = None;
1877 MotifWmHints *hints;
1883 GdkWindowPrivate *window_private;
1885 g_return_if_fail (window != NULL);
1886 window_private = (GdkWindowPrivate*) window;
1887 if (window_private->destroyed)
1891 hints_atom = XInternAtom (window_private->xdisplay,
1892 _XA_MOTIF_WM_HINTS, FALSE);
1894 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1895 hints_atom, 0, sizeof(MotifWmHints)/4,
1896 False, AnyPropertyType, &type, &format, &nitems,
1897 &bytes_after, (guchar **)&hints);
1903 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1905 hints->flags |= MWM_HINTS_FUNCTIONS;
1906 hints->functions = new_hints->functions;
1908 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1910 hints->flags |= MWM_HINTS_DECORATIONS;
1911 hints->decorations = new_hints->decorations;
1915 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1916 hints_atom, hints_atom, 32, PropModeReplace,
1917 (guchar *)hints, sizeof(MotifWmHints)/4);
1919 if (hints != new_hints)
1924 gdk_window_set_decorations (GdkWindow *window,
1925 GdkWMDecoration decorations)
1929 hints.flags = MWM_HINTS_DECORATIONS;
1930 hints.decorations = decorations;
1932 gdk_window_set_mwm_hints (window, &hints);
1936 gdk_window_set_functions (GdkWindow *window,
1937 GdkWMFunction functions)
1941 hints.flags = MWM_HINTS_FUNCTIONS;
1942 hints.functions = functions;
1944 gdk_window_set_mwm_hints (window, &hints);
1948 gdk_window_get_toplevels (void)
1950 GList *new_list = NULL;
1953 tmp_list = gdk_root_parent.children;
1956 new_list = g_list_prepend (new_list, tmp_list->data);
1957 tmp_list = tmp_list->next;
1964 gdk_drawable_set_data (GdkDrawable *drawable,
1967 GDestroyNotify destroy_func)
1969 g_dataset_set_data_full (drawable, key, data, destroy_func);