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.xdisplay = gdk_display;
212 gdk_root_parent.xwindow = gdk_root_window;
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;
222 gdk_window_new (GdkWindow *parent,
223 GdkWindowAttr *attributes,
224 gint attributes_mask)
227 GdkWindowPrivate *private;
228 GdkWindowPrivate *parent_private;
230 Display *parent_display;
233 XSetWindowAttributes xattributes;
234 long xattributes_mask;
235 XSizeHints size_hints;
237 XClassHint *class_hint;
243 g_return_val_if_fail (attributes != NULL, NULL);
246 parent = (GdkWindow*) &gdk_root_parent;
248 parent_private = (GdkWindowPrivate*) parent;
249 if (parent_private->destroyed)
252 xparent = parent_private->xwindow;
253 parent_display = parent_private->xdisplay;
255 private = g_new (GdkWindowPrivate, 1);
256 window = (GdkWindow*) private;
258 private->parent = parent;
261 parent_private->children = g_list_prepend (parent_private->children, window);
263 private->xdisplay = parent_display;
264 private->destroyed = FALSE;
265 private->resize_count = 0;
266 private->ref_count = 1;
267 xattributes_mask = 0;
269 if (attributes_mask & GDK_WA_X)
274 if (attributes_mask & GDK_WA_Y)
281 private->width = (attributes->width > 1) ? (attributes->width) : (1);
282 private->height = (attributes->height > 1) ? (attributes->height) : (1);
283 private->window_type = attributes->window_type;
284 private->extension_events = FALSE;
285 private->dnd_drag_data_type = None;
286 private->dnd_drag_data_typesavail =
287 private->dnd_drop_data_typesavail = NULL;
288 private->dnd_drop_enabled = private->dnd_drag_enabled =
289 private->dnd_drag_accepted = private->dnd_drag_datashow =
290 private->dnd_drop_data_numtypesavail =
291 private->dnd_drag_data_numtypesavail = 0;
292 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
294 private->filters = NULL;
295 private->children = NULL;
297 window->user_data = NULL;
299 if (attributes_mask & GDK_WA_VISUAL)
300 visual = attributes->visual;
302 visual = gdk_visual_get_system ();
303 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
305 xattributes.event_mask = StructureNotifyMask;
306 for (i = 0; i < nevent_masks; i++)
308 if (attributes->event_mask & (1 << (i + 1)))
309 xattributes.event_mask |= event_mask_table[i];
312 if (xattributes.event_mask)
313 xattributes_mask |= CWEventMask;
315 if(attributes_mask & GDK_WA_NOREDIR) {
316 xattributes.override_redirect =
317 (attributes->override_redirect == FALSE)?False:True;
318 xattributes_mask |= CWOverrideRedirect;
320 xattributes.override_redirect = False;
322 if (attributes->wclass == GDK_INPUT_OUTPUT)
325 depth = visual->depth;
327 if (attributes_mask & GDK_WA_COLORMAP)
328 private->colormap = attributes->colormap;
330 private->colormap = gdk_colormap_get_system ();
332 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
333 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
334 xattributes_mask |= CWBorderPixel | CWBackPixel;
336 switch (private->window_type)
338 case GDK_WINDOW_TOPLEVEL:
339 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
340 xattributes_mask |= CWColormap;
342 xparent = gdk_root_window;
345 case GDK_WINDOW_CHILD:
346 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
347 xattributes_mask |= CWColormap;
350 case GDK_WINDOW_DIALOG:
351 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
352 xattributes_mask |= CWColormap;
354 xparent = gdk_root_window;
357 case GDK_WINDOW_TEMP:
358 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
359 xattributes_mask |= CWColormap;
361 xparent = gdk_root_window;
363 xattributes.save_under = True;
364 xattributes.override_redirect = True;
365 xattributes.cursor = None;
366 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
368 case GDK_WINDOW_ROOT:
369 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
371 case GDK_WINDOW_PIXMAP:
372 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
380 private->colormap = NULL;
383 private->xwindow = XCreateWindow (private->xdisplay, xparent,
384 x, y, private->width, private->height,
385 0, depth, class, xvisual,
386 xattributes_mask, &xattributes);
387 gdk_window_ref (window);
388 gdk_xid_table_insert (&private->xwindow, window);
390 if (private->colormap)
391 gdk_colormap_ref (private->colormap);
393 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
394 (attributes->cursor) :
397 switch (private->window_type)
399 case GDK_WINDOW_DIALOG:
400 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
401 case GDK_WINDOW_TOPLEVEL:
402 case GDK_WINDOW_TEMP:
403 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
405 case GDK_WINDOW_CHILD:
406 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
407 (private->colormap != gdk_colormap_get_system ()) &&
408 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
410 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
411 gdk_window_add_colormap_windows (window);
420 size_hints.flags = PSize;
421 size_hints.width = private->width;
422 size_hints.height = private->height;
424 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
425 wm_hints.window_group = gdk_leader_window;
426 wm_hints.input = True;
427 wm_hints.initial_state = NormalState;
429 /* FIXME: Is there any point in doing this? Do any WM's pay
430 * attention to PSize, and even if they do, is this the
433 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
435 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
437 if (attributes_mask & GDK_WA_TITLE)
438 title = attributes->title;
440 title = gdk_progname;
442 XmbSetWMProperties (private->xdisplay, private->xwindow,
447 if (attributes_mask & GDK_WA_WMCLASS)
449 class_hint = XAllocClassHint ();
450 class_hint->res_name = attributes->wmclass_name;
451 class_hint->res_class = attributes->wmclass_class;
452 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
461 gdk_window_foreign_new (guint32 anid)
464 GdkWindowPrivate *private;
465 GdkWindowPrivate *parent_private;
466 XWindowAttributes attrs;
468 Window *children = NULL;
471 if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
472 g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
476 private = g_new (GdkWindowPrivate, 1);
477 window = (GdkWindow*) private;
479 /* FIXME: This is pretty expensive. Maybe the caller should supply
481 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
485 private->parent = gdk_xid_table_lookup (parent);
487 parent_private = (GdkWindowPrivate *)private->parent;
490 parent_private->children = g_list_prepend (parent_private->children, window);
492 private->xwindow = anid;
493 private->xdisplay = gdk_display;
494 private->x = attrs.x;
495 private->y = attrs.y;
496 private->width = attrs.width;
497 private->height = attrs.height;
498 private->resize_count = 0;
499 private->ref_count = 1;
500 private->window_type = GDK_WINDOW_FOREIGN;
501 private->destroyed = FALSE;
502 private->extension_events = 0;
504 private->colormap = NULL;
506 private->dnd_drag_data_type = None;
507 private->dnd_drag_data_typesavail =
508 private->dnd_drop_data_typesavail = NULL;
509 private->dnd_drop_enabled = private->dnd_drag_enabled =
510 private->dnd_drag_accepted = private->dnd_drag_datashow =
511 private->dnd_drop_data_numtypesavail =
512 private->dnd_drag_data_numtypesavail = 0;
513 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
515 private->filters = NULL;
516 private->children = NULL;
518 window->user_data = NULL;
520 gdk_window_ref (window);
521 gdk_xid_table_insert (&private->xwindow, window);
526 /* Call this function when you want a window and all its children to
527 disappear. When xdestroy is true, a request to destroy the XWindow
528 is sent out. When it is false, it is assumed that the XWindow has
529 been or will be destroyed by destroying some ancestor of this
533 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
534 gboolean our_destroy)
536 GdkWindowPrivate *private;
537 GdkWindowPrivate *temp_private;
538 GdkWindow *temp_window;
542 g_return_if_fail (window != NULL);
544 private = (GdkWindowPrivate*) window;
546 switch (private->window_type)
548 case GDK_WINDOW_TOPLEVEL:
549 case GDK_WINDOW_CHILD:
550 case GDK_WINDOW_DIALOG:
551 case GDK_WINDOW_TEMP:
552 case GDK_WINDOW_FOREIGN:
553 if (!private->destroyed)
557 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
558 if (parent_private->children)
559 parent_private->children = g_list_remove (parent_private->children, window);
562 if (private->window_type != GDK_WINDOW_FOREIGN)
564 children = tmp = private->children;
565 private->children = NULL;
569 temp_window = tmp->data;
572 temp_private = (GdkWindowPrivate*) temp_window;
574 gdk_window_internal_destroy (temp_window, FALSE,
578 g_list_free (children);
581 if (private->extension_events != 0)
582 gdk_input_window_destroy (window);
584 if(private->dnd_drag_data_numtypesavail > 0)
586 g_free (private->dnd_drag_data_typesavail);
587 private->dnd_drag_data_typesavail = NULL;
589 if(private->dnd_drop_data_numtypesavail > 0)
591 g_free (private->dnd_drop_data_typesavail);
592 private->dnd_drop_data_typesavail = NULL;
595 if (private->filters)
597 tmp = private->filters;
605 g_list_free (private->filters);
606 private->filters = NULL;
609 if (private->window_type == GDK_WINDOW_FOREIGN)
611 if (our_destroy && (private->parent != NULL))
613 /* It's somebody elses window, but in our heirarchy,
614 * so reparent it to the root window, and then send
615 * it a delete event, as if we were a WM
617 XClientMessageEvent xevent;
619 gdk_window_hide (window);
620 gdk_window_reparent (window, NULL, 0, 0);
622 xevent.type = ClientMessage;
623 xevent.window = private->xwindow;
624 xevent.message_type = gdk_wm_protocols;
626 xevent.data.l[0] = gdk_wm_delete_window;
627 xevent.data.l[1] = CurrentTime;
629 XSendEvent (private->xdisplay, private->xwindow,
630 False, 0, (XEvent *)&xevent);
634 XDestroyWindow (private->xdisplay, private->xwindow);
636 if (private->colormap)
637 gdk_colormap_unref (private->colormap);
639 private->destroyed = TRUE;
643 case GDK_WINDOW_ROOT:
644 g_error ("attempted to destroy root window");
647 case GDK_WINDOW_PIXMAP:
648 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
653 /* Like internal_destroy, but also destroys the reference created by
657 gdk_window_destroy (GdkWindow *window)
659 gdk_window_internal_destroy (window, TRUE, TRUE);
660 gdk_window_unref (window);
663 /* This function is called when the XWindow is really gone. */
666 gdk_window_destroy_notify (GdkWindow *window)
668 GdkWindowPrivate *private;
670 g_return_if_fail (window != NULL);
672 private = (GdkWindowPrivate*) window;
674 if (!private->destroyed)
676 if (private->window_type == GDK_WINDOW_FOREIGN)
677 gdk_window_internal_destroy (window, FALSE, FALSE);
679 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
682 gdk_xid_table_remove (private->xwindow);
683 gdk_window_unref (window);
687 gdk_window_ref (GdkWindow *window)
689 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
690 g_return_val_if_fail (window != NULL, NULL);
692 private->ref_count += 1;
697 gdk_window_unref (GdkWindow *window)
699 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
700 g_return_if_fail (window != NULL);
702 private->ref_count -= 1;
703 if (private->ref_count == 0)
705 if (!private->destroyed)
706 g_warning ("losing last reference to undestroyed window\n");
712 gdk_window_show (GdkWindow *window)
714 GdkWindowPrivate *private;
716 g_return_if_fail (window != NULL);
718 private = (GdkWindowPrivate*) window;
719 if (!private->destroyed)
721 XRaiseWindow (private->xdisplay, private->xwindow);
722 XMapWindow (private->xdisplay, private->xwindow);
727 gdk_window_hide (GdkWindow *window)
729 GdkWindowPrivate *private;
731 g_return_if_fail (window != NULL);
733 private = (GdkWindowPrivate*) window;
734 if (!private->destroyed)
735 XUnmapWindow (private->xdisplay, private->xwindow);
739 gdk_window_withdraw (GdkWindow *window)
741 GdkWindowPrivate *private;
743 g_return_if_fail (window != NULL);
745 private = (GdkWindowPrivate*) window;
746 if (!private->destroyed)
747 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
751 gdk_window_move (GdkWindow *window,
755 GdkWindowPrivate *private;
757 g_return_if_fail (window != NULL);
759 private = (GdkWindowPrivate*) window;
760 if (!private->destroyed)
762 XMoveWindow (private->xdisplay, private->xwindow, x, y);
764 if (private->window_type == GDK_WINDOW_CHILD)
773 gdk_window_resize (GdkWindow *window,
777 GdkWindowPrivate *private;
779 g_return_if_fail (window != NULL);
786 private = (GdkWindowPrivate*) window;
788 if (!private->destroyed &&
789 ((private->resize_count > 0) ||
790 (private->width != (guint16) width) ||
791 (private->height != (guint16) height)))
793 XResizeWindow (private->xdisplay, private->xwindow, width, height);
794 private->resize_count += 1;
796 if (private->window_type == GDK_WINDOW_CHILD)
798 private->width = width;
799 private->height = height;
805 gdk_window_move_resize (GdkWindow *window,
811 GdkWindowPrivate *private;
813 g_return_if_fail (window != NULL);
820 private = (GdkWindowPrivate*) window;
821 if (!private->destroyed)
823 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
825 if (private->window_type == GDK_WINDOW_CHILD)
829 private->width = width;
830 private->height = height;
836 gdk_window_reparent (GdkWindow *window,
837 GdkWindow *new_parent,
841 GdkWindowPrivate *window_private;
842 GdkWindowPrivate *parent_private;
843 GdkWindowPrivate *old_parent_private;
845 g_return_if_fail (window != NULL);
848 new_parent = (GdkWindow*) &gdk_root_parent;
850 window_private = (GdkWindowPrivate*) window;
851 old_parent_private = (GdkWindowPrivate*)window_private->parent;
852 parent_private = (GdkWindowPrivate*) new_parent;
854 if (!window_private->destroyed && !parent_private->destroyed)
855 XReparentWindow (window_private->xdisplay,
856 window_private->xwindow,
857 parent_private->xwindow,
860 window_private->parent = new_parent;
862 if (old_parent_private)
863 old_parent_private->children = g_list_remove (old_parent_private->children, window);
864 parent_private->children = g_list_prepend (parent_private->children, window);
869 gdk_window_clear (GdkWindow *window)
871 GdkWindowPrivate *private;
873 g_return_if_fail (window != NULL);
875 private = (GdkWindowPrivate*) window;
877 if (!private->destroyed)
878 XClearWindow (private->xdisplay, private->xwindow);
882 gdk_window_clear_area (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, False);
900 gdk_window_clear_area_e (GdkWindow *window,
906 GdkWindowPrivate *private;
908 g_return_if_fail (window != NULL);
910 private = (GdkWindowPrivate*) window;
912 if (!private->destroyed)
913 XClearArea (private->xdisplay, private->xwindow,
914 x, y, width, height, True);
918 gdk_window_copy_area (GdkWindow *window,
922 GdkWindow *source_window,
928 GdkWindowPrivate *src_private;
929 GdkWindowPrivate *dest_private;
930 GdkGCPrivate *gc_private;
932 g_return_if_fail (window != NULL);
933 g_return_if_fail (gc != NULL);
935 if (source_window == NULL)
936 source_window = window;
938 src_private = (GdkWindowPrivate*) source_window;
939 dest_private = (GdkWindowPrivate*) window;
940 gc_private = (GdkGCPrivate*) gc;
942 if (!src_private->destroyed && !dest_private->destroyed)
944 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
953 gdk_window_raise (GdkWindow *window)
955 GdkWindowPrivate *private;
957 g_return_if_fail (window != NULL);
959 private = (GdkWindowPrivate*) window;
961 if (!private->destroyed)
962 XRaiseWindow (private->xdisplay, private->xwindow);
966 gdk_window_lower (GdkWindow *window)
968 GdkWindowPrivate *private;
970 g_return_if_fail (window != NULL);
972 private = (GdkWindowPrivate*) window;
974 if (!private->destroyed)
975 XLowerWindow (private->xdisplay, private->xwindow);
979 gdk_window_set_user_data (GdkWindow *window,
982 g_return_if_fail (window != NULL);
984 window->user_data = user_data;
988 gdk_window_set_hints (GdkWindow *window,
997 GdkWindowPrivate *private;
998 XSizeHints size_hints;
1000 g_return_if_fail (window != NULL);
1002 private = (GdkWindowPrivate*) window;
1003 if (private->destroyed)
1006 size_hints.flags = 0;
1008 if (flags & GDK_HINT_POS)
1010 size_hints.flags |= PPosition;
1015 if (flags & GDK_HINT_MIN_SIZE)
1017 size_hints.flags |= PMinSize;
1018 size_hints.min_width = min_width;
1019 size_hints.min_height = min_height;
1022 if (flags & GDK_HINT_MAX_SIZE)
1024 size_hints.flags |= PMaxSize;
1025 size_hints.max_width = max_width;
1026 size_hints.max_height = max_height;
1030 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1034 gdk_window_set_title (GdkWindow *window,
1037 GdkWindowPrivate *private;
1039 g_return_if_fail (window != NULL);
1041 private = (GdkWindowPrivate*) window;
1042 if (!private->destroyed)
1043 XmbSetWMProperties (private->xdisplay, private->xwindow,
1044 title, title, NULL, 0, NULL, NULL, NULL);
1048 gdk_window_set_background (GdkWindow *window,
1051 GdkWindowPrivate *private;
1053 g_return_if_fail (window != NULL);
1055 private = (GdkWindowPrivate*) window;
1056 if (!private->destroyed)
1057 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1061 gdk_window_set_back_pixmap (GdkWindow *window,
1063 gint parent_relative)
1065 GdkWindowPrivate *window_private;
1066 GdkPixmapPrivate *pixmap_private;
1069 g_return_if_fail (window != NULL);
1071 window_private = (GdkWindowPrivate*) window;
1072 pixmap_private = (GdkPixmapPrivate*) pixmap;
1075 xpixmap = pixmap_private->xwindow;
1079 if (parent_relative)
1080 xpixmap = ParentRelative;
1082 if (!window_private->destroyed)
1083 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1087 gdk_window_set_cursor (GdkWindow *window,
1090 GdkWindowPrivate *window_private;
1091 GdkCursorPrivate *cursor_private;
1094 g_return_if_fail (window != NULL);
1096 window_private = (GdkWindowPrivate*) window;
1097 cursor_private = (GdkCursorPrivate*) cursor;
1102 xcursor = cursor_private->xcursor;
1104 if (!window_private->destroyed)
1105 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1109 gdk_window_set_colormap (GdkWindow *window,
1110 GdkColormap *colormap)
1112 GdkWindowPrivate *window_private;
1113 GdkColormapPrivate *colormap_private;
1115 g_return_if_fail (window != NULL);
1116 g_return_if_fail (colormap != NULL);
1118 window_private = (GdkWindowPrivate*) window;
1119 colormap_private = (GdkColormapPrivate*) colormap;
1121 if (!window_private->destroyed)
1123 XSetWindowColormap (window_private->xdisplay,
1124 window_private->xwindow,
1125 colormap_private->xcolormap);
1127 if (window_private->colormap)
1128 gdk_colormap_unref (window_private->colormap);
1129 window_private->colormap = colormap;
1130 gdk_colormap_ref (window_private->colormap);
1132 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1133 gdk_window_add_colormap_windows (window);
1138 gdk_window_get_user_data (GdkWindow *window,
1141 g_return_if_fail (window != NULL);
1143 *data = window->user_data;
1147 gdk_window_get_geometry (GdkWindow *window,
1154 GdkWindowPrivate *window_private;
1160 guint tborder_width;
1164 window = (GdkWindow*) &gdk_root_parent;
1166 window_private = (GdkWindowPrivate*) window;
1168 if (!window_private->destroyed)
1170 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1171 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1187 gdk_window_get_position (GdkWindow *window,
1191 GdkWindowPrivate *window_private;
1193 g_return_if_fail (window != NULL);
1195 window_private = (GdkWindowPrivate*) window;
1198 *x = window_private->x;
1200 *y = window_private->y;
1204 gdk_window_get_size (GdkWindow *window,
1208 GdkWindowPrivate *window_private;
1210 g_return_if_fail (window != NULL);
1212 window_private = (GdkWindowPrivate*) window;
1215 *width = window_private->width;
1217 *height = window_private->height;
1221 gdk_window_get_visual (GdkWindow *window)
1223 GdkWindowPrivate *window_private;
1224 XWindowAttributes window_attributes;
1226 g_return_val_if_fail (window != NULL, NULL);
1228 window_private = (GdkWindowPrivate*) window;
1229 /* Huh? ->parent is never set for a pixmap. We should just return
1232 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1233 window_private = (GdkWindowPrivate*) window_private->parent;
1235 if (window_private && !window_private->destroyed)
1237 if (window_private->colormap == NULL)
1239 XGetWindowAttributes (window_private->xdisplay,
1240 window_private->xwindow,
1241 &window_attributes);
1242 return gdk_visual_lookup (window_attributes.visual);
1245 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1252 gdk_window_get_colormap (GdkWindow *window)
1254 GdkWindowPrivate *window_private;
1255 XWindowAttributes window_attributes;
1257 g_return_val_if_fail (window != NULL, NULL);
1258 window_private = (GdkWindowPrivate*) window;
1260 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1261 if (!window_private->destroyed)
1263 if (window_private->colormap == NULL)
1265 XGetWindowAttributes (window_private->xdisplay,
1266 window_private->xwindow,
1267 &window_attributes);
1268 return gdk_colormap_lookup (window_attributes.colormap);
1271 return window_private->colormap;
1278 gdk_window_get_type (GdkWindow *window)
1280 GdkWindowPrivate *window_private;
1282 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1284 window_private = (GdkWindowPrivate*) window;
1285 return window_private->window_type;
1289 gdk_window_get_origin (GdkWindow *window,
1293 GdkWindowPrivate *private;
1299 g_return_val_if_fail (window != NULL, 0);
1301 private = (GdkWindowPrivate*) window;
1303 if (!private->destroyed)
1305 return_val = XTranslateCoordinates (private->xdisplay,
1324 gdk_window_get_pointer (GdkWindow *window,
1327 GdkModifierType *mask)
1329 GdkWindowPrivate *private;
1330 GdkWindow *return_val;
1336 unsigned int xmask = 0;
1339 window = (GdkWindow*) &gdk_root_parent;
1341 private = (GdkWindowPrivate*) window;
1344 if (!private->destroyed &&
1345 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1346 &rootx, &rooty, &winx, &winy, &xmask))
1349 return_val = gdk_window_lookup (child);
1363 gdk_window_at_pointer (gint *win_x,
1366 GdkWindowPrivate *private;
1370 Window xwindow_last = 0;
1371 int rootx = -1, rooty = -1;
1375 private = &gdk_root_parent;
1377 xwindow = private->xwindow;
1379 XGrabServer (private->xdisplay);
1382 xwindow_last = xwindow;
1383 XQueryPointer (private->xdisplay,
1390 XUngrabServer (private->xdisplay);
1392 window = gdk_window_lookup (xwindow_last);
1395 *win_x = window ? winx : -1;
1397 *win_y = window ? winy : -1;
1403 gdk_window_get_parent (GdkWindow *window)
1405 g_return_val_if_fail (window != NULL, NULL);
1407 return ((GdkWindowPrivate*) window)->parent;
1411 gdk_window_get_toplevel (GdkWindow *window)
1413 GdkWindowPrivate *private;
1415 g_return_val_if_fail (window != NULL, NULL);
1417 private = (GdkWindowPrivate*) window;
1419 while (private->window_type == GDK_WINDOW_CHILD)
1421 window = ((GdkWindowPrivate*) window)->parent;
1422 private = (GdkWindowPrivate*) window;
1429 gdk_window_get_children (GdkWindow *window)
1431 GdkWindowPrivate *private;
1437 unsigned int nchildren;
1440 g_return_val_if_fail (window != NULL, NULL);
1442 private = (GdkWindowPrivate*) window;
1443 if (private->destroyed)
1446 XQueryTree (private->xdisplay, private->xwindow,
1447 &root, &parent, &xchildren, &nchildren);
1453 for (i = 0; i < nchildren; i++)
1455 child = gdk_window_lookup (xchildren[i]);
1457 children = g_list_prepend (children, child);
1468 gdk_window_get_events (GdkWindow *window)
1470 GdkWindowPrivate *private;
1471 XWindowAttributes attrs;
1472 GdkEventMask event_mask;
1475 g_return_val_if_fail (window != NULL, 0);
1477 private = (GdkWindowPrivate*) window;
1478 if (private->destroyed)
1481 XGetWindowAttributes (gdk_display, private->xwindow,
1485 for (i = 0; i < nevent_masks; i++)
1487 if (attrs.your_event_mask & event_mask_table[i])
1488 event_mask |= 1 << (i + 1);
1495 gdk_window_set_events (GdkWindow *window,
1496 GdkEventMask event_mask)
1498 GdkWindowPrivate *private;
1502 g_return_if_fail (window != NULL);
1504 private = (GdkWindowPrivate*) window;
1505 if (private->destroyed)
1508 xevent_mask = StructureNotifyMask;
1509 for (i = 0; i < nevent_masks; i++)
1511 if (event_mask & (1 << (i + 1)))
1512 xevent_mask |= event_mask_table[i];
1515 XSelectInput (gdk_display, private->xwindow,
1520 gdk_window_add_colormap_windows (GdkWindow *window)
1522 GdkWindow *toplevel;
1523 GdkWindowPrivate *toplevel_private;
1524 GdkWindowPrivate *window_private;
1525 Window *old_windows;
1526 Window *new_windows;
1529 g_return_if_fail (window != NULL);
1531 toplevel = gdk_window_get_toplevel (window);
1532 toplevel_private = (GdkWindowPrivate*) toplevel;
1533 window_private = (GdkWindowPrivate*) window;
1534 if (window_private->destroyed)
1538 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1539 toplevel_private->xwindow,
1540 &old_windows, &count))
1545 for (i = 0; i < count; i++)
1546 if (old_windows[i] == window_private->xwindow)
1548 XFree (old_windows);
1552 new_windows = g_new (Window, count + 1);
1554 for (i = 0; i < count; i++)
1555 new_windows[i] = old_windows[i];
1556 new_windows[count] = window_private->xwindow;
1558 XSetWMColormapWindows (toplevel_private->xdisplay,
1559 toplevel_private->xwindow,
1560 new_windows, count + 1);
1562 g_free (new_windows);
1564 XFree (old_windows);
1568 * This needs the X11 shape extension.
1569 * If not available, shaped windows will look
1570 * ugly, but programs still work. Stefan Wille
1573 gdk_window_shape_combine_mask (GdkWindow *window,
1577 enum { UNKNOWN, NO, YES };
1579 static gint have_shape = UNKNOWN;
1581 GdkWindowPrivate *window_private;
1584 g_return_if_fail (window != NULL);
1586 #ifdef HAVE_SHAPE_EXT
1587 if (have_shape == UNKNOWN)
1590 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1596 if (have_shape == YES)
1598 window_private = (GdkWindowPrivate*) window;
1599 if (window_private->destroyed)
1604 GdkWindowPrivate *pixmap_private;
1606 pixmap_private = (GdkWindowPrivate*) mask;
1607 pixmap = (Pixmap) pixmap_private->xwindow;
1616 XShapeCombineMask (window_private->xdisplay,
1617 window_private->xwindow,
1623 #endif /* HAVE_SHAPE_EXT */
1627 gdk_dnd_drag_addwindow (GdkWindow *window)
1629 GdkWindowPrivate *window_private;
1631 g_return_if_fail (window != NULL);
1633 window_private = (GdkWindowPrivate *) window;
1634 if (window_private->destroyed)
1637 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1639 gdk_dnd.drag_numwindows++;
1640 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1641 gdk_dnd.drag_numwindows
1642 * sizeof(GdkWindow *));
1643 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1644 window_private->dnd_drag_accepted = 0;
1647 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1651 gdk_window_dnd_drag_set (GdkWindow *window,
1656 GdkWindowPrivate *window_private;
1659 g_return_if_fail (window != NULL);
1660 window_private = (GdkWindowPrivate *) window;
1661 if (window_private->destroyed)
1664 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1668 g_return_if_fail(typelist != NULL);
1670 if (window_private->dnd_drag_data_numtypesavail > 3)
1672 window_private->dnd_drag_data_numtypesavail = numtypes;
1674 window_private->dnd_drag_data_typesavail =
1675 g_realloc (window_private->dnd_drag_data_typesavail,
1676 (numtypes + 1) * sizeof (GdkAtom));
1678 for (i = 0; i < numtypes; i++)
1680 /* Allow blanket use of ALL to get anything... */
1681 if (strcmp (typelist[i], "ALL"))
1682 window_private->dnd_drag_data_typesavail[i] =
1683 gdk_atom_intern (typelist[i], FALSE);
1685 window_private->dnd_drag_data_typesavail[i] = None;
1689 * set our extended type list if we need to
1692 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1693 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1694 (guchar *)(window_private->dnd_drag_data_typesavail
1695 + (sizeof(GdkAtom) * 3)),
1696 (numtypes - 3) * sizeof(GdkAtom));
1698 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1702 g_free (window_private->dnd_drag_data_typesavail);
1703 window_private->dnd_drag_data_typesavail = NULL;
1704 window_private->dnd_drag_data_numtypesavail = 0;
1709 gdk_window_dnd_drop_set (GdkWindow *window,
1713 guint8 destructive_op)
1715 GdkWindowPrivate *window_private;
1718 g_return_if_fail (window != NULL);
1719 window_private = (GdkWindowPrivate *) window;
1720 if (window_private->destroyed)
1723 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1726 g_return_if_fail(typelist != NULL);
1728 window_private->dnd_drop_data_numtypesavail = numtypes;
1730 window_private->dnd_drop_data_typesavail =
1731 g_realloc (window_private->dnd_drop_data_typesavail,
1732 (numtypes + 1) * sizeof (GdkAtom));
1734 for (i = 0; i < numtypes; i++)
1735 window_private->dnd_drop_data_typesavail[i] =
1736 gdk_atom_intern (typelist[i], FALSE);
1738 window_private->dnd_drop_destructive_op = destructive_op;
1743 * This is used to reply to a GDK_DRAG_REQUEST event
1744 * (which may be generated by XdeRequest or a confirmed drop...
1747 gdk_window_dnd_data_set (GdkWindow *window,
1750 gulong data_numbytes)
1752 GdkWindowPrivate *window_private;
1754 GdkEventDropDataAvailable tmp_ev;
1757 g_return_if_fail (window != NULL);
1758 g_return_if_fail (event != NULL);
1759 g_return_if_fail (data != NULL);
1760 g_return_if_fail (data_numbytes > 0);
1761 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1763 window_private = (GdkWindowPrivate *) window;
1764 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1765 if (window_private->destroyed)
1768 /* We set the property on our window... */
1769 gdk_property_change (window, window_private->dnd_drag_data_type,
1770 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1772 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1774 g_message("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1779 * Then we send the event to tell the receiving window that the
1782 tmp_ev.u.allflags = 0;
1783 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1784 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1786 sev.xclient.type = ClientMessage;
1787 sev.xclient.format = 32;
1788 sev.xclient.window = event->dragrequest.requestor;
1789 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1790 sev.xclient.data.l[0] = window_private->xwindow;
1791 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1792 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1794 if (event->dragrequest.isdrop)
1795 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1796 (event->dragrequest.drop_coords.y << 16);
1798 sev.xclient.data.l[3] = 0;
1800 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1802 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1803 StructureNotifyMask, &sev))
1804 GDK_NOTE (DND, g_message("Sending XdeDataAvailable to %#x failed\n",
1805 event->dragrequest.requestor));
1809 gdk_window_add_filter (GdkWindow *window,
1810 GdkFilterFunc function,
1813 GdkWindowPrivate *private;
1815 GdkEventFilter *filter;
1817 private = (GdkWindowPrivate*) window;
1818 if (private && private->destroyed)
1822 tmp_list = private->filters;
1824 tmp_list = gdk_default_filters;
1828 filter = (GdkEventFilter *)tmp_list->data;
1829 if ((filter->function == function) && (filter->data == data))
1831 tmp_list = tmp_list->next;
1834 filter = g_new (GdkEventFilter, 1);
1835 filter->function = function;
1836 filter->data = data;
1839 private->filters = g_list_append (private->filters, filter);
1841 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1845 gdk_window_remove_filter (GdkWindow *window,
1846 GdkFilterFunc function,
1849 GdkWindowPrivate *private;
1851 GdkEventFilter *filter;
1853 private = (GdkWindowPrivate*) window;
1856 tmp_list = private->filters;
1858 tmp_list = gdk_default_filters;
1862 filter = (GdkEventFilter *)tmp_list->data;
1863 tmp_list = tmp_list->next;
1865 if ((filter->function == function) && (filter->data == data))
1868 private->filters = g_list_remove_link (private->filters, tmp_list);
1870 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1871 g_list_free_1 (tmp_list);
1880 gdk_window_set_override_redirect(GdkWindow *window,
1881 gboolean override_redirect)
1883 GdkWindowPrivate *private;
1884 XSetWindowAttributes attr;
1886 g_return_if_fail (window != NULL);
1887 private = (GdkWindowPrivate*) window;
1888 if (private->destroyed)
1891 attr.override_redirect = (override_redirect == FALSE)?False:True;
1892 XChangeWindowAttributes(gdk_display,
1893 ((GdkWindowPrivate *)window)->xwindow,
1899 gdk_window_set_icon (GdkWindow *window,
1900 GdkWindow *icon_window,
1905 GdkWindowPrivate *window_private;
1906 GdkWindowPrivate *private;
1908 g_return_if_fail (window != NULL);
1909 window_private = (GdkWindowPrivate*) window;
1910 if (window_private->destroyed)
1915 if (icon_window != NULL)
1917 private = (GdkWindowPrivate *)icon_window;
1918 wm_hints.flags |= IconWindowHint;
1919 wm_hints.icon_window = private->xwindow;
1924 private = (GdkWindowPrivate *)pixmap;
1925 wm_hints.flags |= IconPixmapHint;
1926 wm_hints.icon_pixmap = private->xwindow;
1931 private = (GdkWindowPrivate *)mask;
1932 wm_hints.flags |= IconMaskHint;
1933 wm_hints.icon_mask = private->xwindow;
1936 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1940 gdk_window_set_icon_name (GdkWindow *window,
1943 GdkWindowPrivate *window_private;
1944 XTextProperty property;
1947 g_return_if_fail (window != NULL);
1948 window_private = (GdkWindowPrivate*) window;
1949 if (window_private->destroyed)
1951 res = XmbTextListToTextProperty (window_private->xdisplay,
1952 &name, 1, XStdICCTextStyle,
1956 g_warning("Error converting icon name to text property: %d\n", res);
1960 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1964 XFree (property.value);
1968 gdk_window_set_group (GdkWindow *window,
1972 GdkWindowPrivate *window_private;
1973 GdkWindowPrivate *private;
1975 g_return_if_fail (window != NULL);
1976 g_return_if_fail (leader != NULL);
1977 window_private = (GdkWindowPrivate*) window;
1978 if (window_private->destroyed)
1981 private = (GdkWindowPrivate *)leader;
1982 wm_hints.flags = WindowGroupHint;
1983 wm_hints.window_group = private->xwindow;
1985 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1989 gdk_window_set_mwm_hints (GdkWindow *window,
1990 MotifWmHints *new_hints)
1992 static Atom hints_atom = None;
1993 MotifWmHints *hints;
1999 GdkWindowPrivate *window_private;
2001 g_return_if_fail (window != NULL);
2002 window_private = (GdkWindowPrivate*) window;
2003 if (window_private->destroyed)
2007 hints_atom = XInternAtom (window_private->xdisplay,
2008 _XA_MOTIF_WM_HINTS, FALSE);
2010 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2011 hints_atom, 0, sizeof(MotifWmHints)/4,
2012 False, AnyPropertyType, &type, &format, &nitems,
2013 &bytes_after, (guchar **)&hints);
2019 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2021 hints->flags |= MWM_HINTS_FUNCTIONS;
2022 hints->functions = new_hints->functions;
2024 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2026 hints->flags |= MWM_HINTS_DECORATIONS;
2027 hints->decorations = new_hints->decorations;
2031 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2032 hints_atom, hints_atom, 32, PropModeReplace,
2033 (guchar *)hints, sizeof(MotifWmHints)/4);
2035 if (hints != new_hints)
2040 gdk_window_set_decorations (GdkWindow *window,
2041 GdkWMDecoration decorations)
2045 hints.flags = MWM_HINTS_DECORATIONS;
2046 hints.decorations = decorations;
2048 gdk_window_set_mwm_hints (window, &hints);
2052 gdk_window_set_functions (GdkWindow *window,
2053 GdkWMFunction functions)
2057 hints.flags = MWM_HINTS_FUNCTIONS;
2058 hints.functions = functions;
2060 gdk_window_set_mwm_hints (window, &hints);
2064 gdk_window_get_toplevels (void)
2066 GList *new_list = NULL;
2069 tmp_list = gdk_root_parent.children;
2072 new_list = g_list_prepend (new_list, tmp_list->data);
2073 tmp_list = tmp_list->next;