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;
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 = g_get_prgname ();
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");
707 g_dataset_destroy (window);
714 gdk_window_show (GdkWindow *window)
716 GdkWindowPrivate *private;
718 g_return_if_fail (window != NULL);
720 private = (GdkWindowPrivate*) window;
721 if (!private->destroyed)
723 XRaiseWindow (private->xdisplay, private->xwindow);
724 XMapWindow (private->xdisplay, private->xwindow);
729 gdk_window_hide (GdkWindow *window)
731 GdkWindowPrivate *private;
733 g_return_if_fail (window != NULL);
735 private = (GdkWindowPrivate*) window;
736 if (!private->destroyed)
737 XUnmapWindow (private->xdisplay, private->xwindow);
741 gdk_window_withdraw (GdkWindow *window)
743 GdkWindowPrivate *private;
745 g_return_if_fail (window != NULL);
747 private = (GdkWindowPrivate*) window;
748 if (!private->destroyed)
749 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
753 gdk_window_move (GdkWindow *window,
757 GdkWindowPrivate *private;
759 g_return_if_fail (window != NULL);
761 private = (GdkWindowPrivate*) window;
762 if (!private->destroyed)
764 XMoveWindow (private->xdisplay, private->xwindow, x, y);
766 if (private->window_type == GDK_WINDOW_CHILD)
775 gdk_window_resize (GdkWindow *window,
779 GdkWindowPrivate *private;
781 g_return_if_fail (window != NULL);
788 private = (GdkWindowPrivate*) window;
790 if (!private->destroyed &&
791 ((private->resize_count > 0) ||
792 (private->width != (guint16) width) ||
793 (private->height != (guint16) height)))
795 XResizeWindow (private->xdisplay, private->xwindow, width, height);
796 private->resize_count += 1;
798 if (private->window_type == GDK_WINDOW_CHILD)
800 private->width = width;
801 private->height = height;
807 gdk_window_move_resize (GdkWindow *window,
813 GdkWindowPrivate *private;
815 g_return_if_fail (window != NULL);
822 private = (GdkWindowPrivate*) window;
823 if (!private->destroyed)
825 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
827 if (private->window_type == GDK_WINDOW_CHILD)
831 private->width = width;
832 private->height = height;
838 gdk_window_reparent (GdkWindow *window,
839 GdkWindow *new_parent,
843 GdkWindowPrivate *window_private;
844 GdkWindowPrivate *parent_private;
845 GdkWindowPrivate *old_parent_private;
847 g_return_if_fail (window != NULL);
850 new_parent = (GdkWindow*) &gdk_root_parent;
852 window_private = (GdkWindowPrivate*) window;
853 old_parent_private = (GdkWindowPrivate*)window_private->parent;
854 parent_private = (GdkWindowPrivate*) new_parent;
856 if (!window_private->destroyed && !parent_private->destroyed)
857 XReparentWindow (window_private->xdisplay,
858 window_private->xwindow,
859 parent_private->xwindow,
862 window_private->parent = new_parent;
864 if (old_parent_private)
865 old_parent_private->children = g_list_remove (old_parent_private->children, window);
866 parent_private->children = g_list_prepend (parent_private->children, window);
871 gdk_window_clear (GdkWindow *window)
873 GdkWindowPrivate *private;
875 g_return_if_fail (window != NULL);
877 private = (GdkWindowPrivate*) window;
879 if (!private->destroyed)
880 XClearWindow (private->xdisplay, private->xwindow);
884 gdk_window_clear_area (GdkWindow *window,
890 GdkWindowPrivate *private;
892 g_return_if_fail (window != NULL);
894 private = (GdkWindowPrivate*) window;
896 if (!private->destroyed)
897 XClearArea (private->xdisplay, private->xwindow,
898 x, y, width, height, False);
902 gdk_window_clear_area_e (GdkWindow *window,
908 GdkWindowPrivate *private;
910 g_return_if_fail (window != NULL);
912 private = (GdkWindowPrivate*) window;
914 if (!private->destroyed)
915 XClearArea (private->xdisplay, private->xwindow,
916 x, y, width, height, True);
920 gdk_window_copy_area (GdkWindow *window,
924 GdkWindow *source_window,
930 GdkWindowPrivate *src_private;
931 GdkWindowPrivate *dest_private;
932 GdkGCPrivate *gc_private;
934 g_return_if_fail (window != NULL);
935 g_return_if_fail (gc != NULL);
937 if (source_window == NULL)
938 source_window = window;
940 src_private = (GdkWindowPrivate*) source_window;
941 dest_private = (GdkWindowPrivate*) window;
942 gc_private = (GdkGCPrivate*) gc;
944 if (!src_private->destroyed && !dest_private->destroyed)
946 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
955 gdk_window_raise (GdkWindow *window)
957 GdkWindowPrivate *private;
959 g_return_if_fail (window != NULL);
961 private = (GdkWindowPrivate*) window;
963 if (!private->destroyed)
964 XRaiseWindow (private->xdisplay, private->xwindow);
968 gdk_window_lower (GdkWindow *window)
970 GdkWindowPrivate *private;
972 g_return_if_fail (window != NULL);
974 private = (GdkWindowPrivate*) window;
976 if (!private->destroyed)
977 XLowerWindow (private->xdisplay, private->xwindow);
981 gdk_window_set_user_data (GdkWindow *window,
984 g_return_if_fail (window != NULL);
986 window->user_data = user_data;
990 gdk_window_set_hints (GdkWindow *window,
999 GdkWindowPrivate *private;
1000 XSizeHints size_hints;
1002 g_return_if_fail (window != NULL);
1004 private = (GdkWindowPrivate*) window;
1005 if (private->destroyed)
1008 size_hints.flags = 0;
1010 if (flags & GDK_HINT_POS)
1012 size_hints.flags |= PPosition;
1017 if (flags & GDK_HINT_MIN_SIZE)
1019 size_hints.flags |= PMinSize;
1020 size_hints.min_width = min_width;
1021 size_hints.min_height = min_height;
1024 if (flags & GDK_HINT_MAX_SIZE)
1026 size_hints.flags |= PMaxSize;
1027 size_hints.max_width = max_width;
1028 size_hints.max_height = max_height;
1032 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1036 gdk_window_set_title (GdkWindow *window,
1039 GdkWindowPrivate *private;
1041 g_return_if_fail (window != NULL);
1043 private = (GdkWindowPrivate*) window;
1044 if (!private->destroyed)
1045 XmbSetWMProperties (private->xdisplay, private->xwindow,
1046 title, title, NULL, 0, NULL, NULL, NULL);
1050 gdk_window_set_background (GdkWindow *window,
1053 GdkWindowPrivate *private;
1055 g_return_if_fail (window != NULL);
1057 private = (GdkWindowPrivate*) window;
1058 if (!private->destroyed)
1059 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1063 gdk_window_set_back_pixmap (GdkWindow *window,
1065 gint parent_relative)
1067 GdkWindowPrivate *window_private;
1068 GdkPixmapPrivate *pixmap_private;
1071 g_return_if_fail (window != NULL);
1073 window_private = (GdkWindowPrivate*) window;
1074 pixmap_private = (GdkPixmapPrivate*) pixmap;
1077 xpixmap = pixmap_private->xwindow;
1081 if (parent_relative)
1082 xpixmap = ParentRelative;
1084 if (!window_private->destroyed)
1085 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1089 gdk_window_set_cursor (GdkWindow *window,
1092 GdkWindowPrivate *window_private;
1093 GdkCursorPrivate *cursor_private;
1096 g_return_if_fail (window != NULL);
1098 window_private = (GdkWindowPrivate*) window;
1099 cursor_private = (GdkCursorPrivate*) cursor;
1104 xcursor = cursor_private->xcursor;
1106 if (!window_private->destroyed)
1107 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1111 gdk_window_set_colormap (GdkWindow *window,
1112 GdkColormap *colormap)
1114 GdkWindowPrivate *window_private;
1115 GdkColormapPrivate *colormap_private;
1117 g_return_if_fail (window != NULL);
1118 g_return_if_fail (colormap != NULL);
1120 window_private = (GdkWindowPrivate*) window;
1121 colormap_private = (GdkColormapPrivate*) colormap;
1123 if (!window_private->destroyed)
1125 XSetWindowColormap (window_private->xdisplay,
1126 window_private->xwindow,
1127 colormap_private->xcolormap);
1129 if (window_private->colormap)
1130 gdk_colormap_unref (window_private->colormap);
1131 window_private->colormap = colormap;
1132 gdk_colormap_ref (window_private->colormap);
1134 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1135 gdk_window_add_colormap_windows (window);
1140 gdk_window_get_user_data (GdkWindow *window,
1143 g_return_if_fail (window != NULL);
1145 *data = window->user_data;
1149 gdk_window_get_geometry (GdkWindow *window,
1156 GdkWindowPrivate *window_private;
1162 guint tborder_width;
1166 window = (GdkWindow*) &gdk_root_parent;
1168 window_private = (GdkWindowPrivate*) window;
1170 if (!window_private->destroyed)
1172 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1173 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1189 gdk_window_get_position (GdkWindow *window,
1193 GdkWindowPrivate *window_private;
1195 g_return_if_fail (window != NULL);
1197 window_private = (GdkWindowPrivate*) window;
1200 *x = window_private->x;
1202 *y = window_private->y;
1206 gdk_window_get_size (GdkWindow *window,
1210 GdkWindowPrivate *window_private;
1212 g_return_if_fail (window != NULL);
1214 window_private = (GdkWindowPrivate*) window;
1217 *width = window_private->width;
1219 *height = window_private->height;
1223 gdk_window_get_visual (GdkWindow *window)
1225 GdkWindowPrivate *window_private;
1226 XWindowAttributes window_attributes;
1228 g_return_val_if_fail (window != NULL, NULL);
1230 window_private = (GdkWindowPrivate*) window;
1231 /* Huh? ->parent is never set for a pixmap. We should just return
1234 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1235 window_private = (GdkWindowPrivate*) window_private->parent;
1237 if (window_private && !window_private->destroyed)
1239 if (window_private->colormap == NULL)
1241 XGetWindowAttributes (window_private->xdisplay,
1242 window_private->xwindow,
1243 &window_attributes);
1244 return gdk_visual_lookup (window_attributes.visual);
1247 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1254 gdk_window_get_colormap (GdkWindow *window)
1256 GdkWindowPrivate *window_private;
1257 XWindowAttributes window_attributes;
1259 g_return_val_if_fail (window != NULL, NULL);
1260 window_private = (GdkWindowPrivate*) window;
1262 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1263 if (!window_private->destroyed)
1265 if (window_private->colormap == NULL)
1267 XGetWindowAttributes (window_private->xdisplay,
1268 window_private->xwindow,
1269 &window_attributes);
1270 return gdk_colormap_lookup (window_attributes.colormap);
1273 return window_private->colormap;
1280 gdk_window_get_type (GdkWindow *window)
1282 GdkWindowPrivate *window_private;
1284 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1286 window_private = (GdkWindowPrivate*) window;
1287 return window_private->window_type;
1291 gdk_window_get_origin (GdkWindow *window,
1295 GdkWindowPrivate *private;
1301 g_return_val_if_fail (window != NULL, 0);
1303 private = (GdkWindowPrivate*) window;
1305 if (!private->destroyed)
1307 return_val = XTranslateCoordinates (private->xdisplay,
1326 gdk_window_get_root_origin (GdkWindow *window,
1330 GdkWindowPrivate *private;
1335 unsigned int nchildren;
1337 g_return_if_fail (window != NULL);
1339 private = (GdkWindowPrivate*) window;
1344 if (private->destroyed)
1347 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1348 private = (GdkWindowPrivate*) private->parent;
1349 if (private->destroyed)
1352 xparent = private->xwindow;
1356 if (!XQueryTree (private->xdisplay, xwindow,
1358 &children, &nchildren))
1364 while (xparent != root);
1366 if (xparent == root)
1368 unsigned int ww, wh, wb, wd;
1371 if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1382 gdk_window_get_pointer (GdkWindow *window,
1385 GdkModifierType *mask)
1387 GdkWindowPrivate *private;
1388 GdkWindow *return_val;
1394 unsigned int xmask = 0;
1397 window = (GdkWindow*) &gdk_root_parent;
1399 private = (GdkWindowPrivate*) window;
1402 if (!private->destroyed &&
1403 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1404 &rootx, &rooty, &winx, &winy, &xmask))
1407 return_val = gdk_window_lookup (child);
1421 gdk_window_at_pointer (gint *win_x,
1424 GdkWindowPrivate *private;
1428 Window xwindow_last = 0;
1429 int rootx = -1, rooty = -1;
1433 private = &gdk_root_parent;
1435 xwindow = private->xwindow;
1437 XGrabServer (private->xdisplay);
1440 xwindow_last = xwindow;
1441 XQueryPointer (private->xdisplay,
1448 XUngrabServer (private->xdisplay);
1450 window = gdk_window_lookup (xwindow_last);
1453 *win_x = window ? winx : -1;
1455 *win_y = window ? winy : -1;
1461 gdk_window_get_parent (GdkWindow *window)
1463 g_return_val_if_fail (window != NULL, NULL);
1465 return ((GdkWindowPrivate*) window)->parent;
1469 gdk_window_get_toplevel (GdkWindow *window)
1471 GdkWindowPrivate *private;
1473 g_return_val_if_fail (window != NULL, NULL);
1475 private = (GdkWindowPrivate*) window;
1477 while (private->window_type == GDK_WINDOW_CHILD)
1479 window = ((GdkWindowPrivate*) window)->parent;
1480 private = (GdkWindowPrivate*) window;
1487 gdk_window_get_children (GdkWindow *window)
1489 GdkWindowPrivate *private;
1495 unsigned int nchildren;
1498 g_return_val_if_fail (window != NULL, NULL);
1500 private = (GdkWindowPrivate*) window;
1501 if (private->destroyed)
1504 XQueryTree (private->xdisplay, private->xwindow,
1505 &root, &parent, &xchildren, &nchildren);
1511 for (i = 0; i < nchildren; i++)
1513 child = gdk_window_lookup (xchildren[i]);
1515 children = g_list_prepend (children, child);
1526 gdk_window_get_events (GdkWindow *window)
1528 GdkWindowPrivate *private;
1529 XWindowAttributes attrs;
1530 GdkEventMask event_mask;
1533 g_return_val_if_fail (window != NULL, 0);
1535 private = (GdkWindowPrivate*) window;
1536 if (private->destroyed)
1539 XGetWindowAttributes (gdk_display, private->xwindow,
1543 for (i = 0; i < nevent_masks; i++)
1545 if (attrs.your_event_mask & event_mask_table[i])
1546 event_mask |= 1 << (i + 1);
1553 gdk_window_set_events (GdkWindow *window,
1554 GdkEventMask event_mask)
1556 GdkWindowPrivate *private;
1560 g_return_if_fail (window != NULL);
1562 private = (GdkWindowPrivate*) window;
1563 if (private->destroyed)
1566 xevent_mask = StructureNotifyMask;
1567 for (i = 0; i < nevent_masks; i++)
1569 if (event_mask & (1 << (i + 1)))
1570 xevent_mask |= event_mask_table[i];
1573 XSelectInput (gdk_display, private->xwindow,
1578 gdk_window_add_colormap_windows (GdkWindow *window)
1580 GdkWindow *toplevel;
1581 GdkWindowPrivate *toplevel_private;
1582 GdkWindowPrivate *window_private;
1583 Window *old_windows;
1584 Window *new_windows;
1587 g_return_if_fail (window != NULL);
1589 toplevel = gdk_window_get_toplevel (window);
1590 toplevel_private = (GdkWindowPrivate*) toplevel;
1591 window_private = (GdkWindowPrivate*) window;
1592 if (window_private->destroyed)
1596 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1597 toplevel_private->xwindow,
1598 &old_windows, &count))
1603 for (i = 0; i < count; i++)
1604 if (old_windows[i] == window_private->xwindow)
1606 XFree (old_windows);
1610 new_windows = g_new (Window, count + 1);
1612 for (i = 0; i < count; i++)
1613 new_windows[i] = old_windows[i];
1614 new_windows[count] = window_private->xwindow;
1616 XSetWMColormapWindows (toplevel_private->xdisplay,
1617 toplevel_private->xwindow,
1618 new_windows, count + 1);
1620 g_free (new_windows);
1622 XFree (old_windows);
1626 * This needs the X11 shape extension.
1627 * If not available, shaped windows will look
1628 * ugly, but programs still work. Stefan Wille
1631 gdk_window_shape_combine_mask (GdkWindow *window,
1635 enum { UNKNOWN, NO, YES };
1637 static gint have_shape = UNKNOWN;
1639 GdkWindowPrivate *window_private;
1642 g_return_if_fail (window != NULL);
1644 #ifdef HAVE_SHAPE_EXT
1645 if (have_shape == UNKNOWN)
1648 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1654 if (have_shape == YES)
1656 window_private = (GdkWindowPrivate*) window;
1657 if (window_private->destroyed)
1662 GdkWindowPrivate *pixmap_private;
1664 pixmap_private = (GdkWindowPrivate*) mask;
1665 pixmap = (Pixmap) pixmap_private->xwindow;
1674 XShapeCombineMask (window_private->xdisplay,
1675 window_private->xwindow,
1681 #endif /* HAVE_SHAPE_EXT */
1685 gdk_dnd_drag_addwindow (GdkWindow *window)
1687 GdkWindowPrivate *window_private;
1689 g_return_if_fail (window != NULL);
1691 window_private = (GdkWindowPrivate *) window;
1692 if (window_private->destroyed)
1695 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1697 gdk_dnd.drag_numwindows++;
1698 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1699 gdk_dnd.drag_numwindows
1700 * sizeof(GdkWindow *));
1701 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1702 window_private->dnd_drag_accepted = 0;
1705 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1709 gdk_window_dnd_drag_set (GdkWindow *window,
1714 GdkWindowPrivate *window_private;
1717 g_return_if_fail (window != NULL);
1718 window_private = (GdkWindowPrivate *) window;
1719 if (window_private->destroyed)
1722 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1726 g_return_if_fail(typelist != NULL);
1728 if (window_private->dnd_drag_data_numtypesavail > 3)
1730 window_private->dnd_drag_data_numtypesavail = numtypes;
1732 window_private->dnd_drag_data_typesavail =
1733 g_realloc (window_private->dnd_drag_data_typesavail,
1734 (numtypes + 1) * sizeof (GdkAtom));
1736 for (i = 0; i < numtypes; i++)
1738 /* Allow blanket use of ALL to get anything... */
1739 if (strcmp (typelist[i], "ALL"))
1740 window_private->dnd_drag_data_typesavail[i] =
1741 gdk_atom_intern (typelist[i], FALSE);
1743 window_private->dnd_drag_data_typesavail[i] = None;
1747 * set our extended type list if we need to
1750 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1751 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1752 (guchar *)(window_private->dnd_drag_data_typesavail
1753 + (sizeof(GdkAtom) * 3)),
1754 (numtypes - 3) * sizeof(GdkAtom));
1756 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1760 g_free (window_private->dnd_drag_data_typesavail);
1761 window_private->dnd_drag_data_typesavail = NULL;
1762 window_private->dnd_drag_data_numtypesavail = 0;
1767 gdk_window_dnd_drop_set (GdkWindow *window,
1771 guint8 destructive_op)
1773 GdkWindowPrivate *window_private;
1776 g_return_if_fail (window != NULL);
1777 window_private = (GdkWindowPrivate *) window;
1778 if (window_private->destroyed)
1781 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1784 g_return_if_fail(typelist != NULL);
1786 window_private->dnd_drop_data_numtypesavail = numtypes;
1788 window_private->dnd_drop_data_typesavail =
1789 g_realloc (window_private->dnd_drop_data_typesavail,
1790 (numtypes + 1) * sizeof (GdkAtom));
1792 for (i = 0; i < numtypes; i++)
1793 window_private->dnd_drop_data_typesavail[i] =
1794 gdk_atom_intern (typelist[i], FALSE);
1796 window_private->dnd_drop_destructive_op = destructive_op;
1801 * This is used to reply to a GDK_DRAG_REQUEST event
1802 * (which may be generated by XdeRequest or a confirmed drop...
1805 gdk_window_dnd_data_set (GdkWindow *window,
1808 gulong data_numbytes)
1810 GdkWindowPrivate *window_private;
1812 GdkEventDropDataAvailable tmp_ev;
1815 g_return_if_fail (window != NULL);
1816 g_return_if_fail (event != NULL);
1817 g_return_if_fail (data != NULL);
1818 g_return_if_fail (data_numbytes > 0);
1819 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1821 window_private = (GdkWindowPrivate *) window;
1822 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1823 if (window_private->destroyed)
1826 /* We set the property on our window... */
1827 gdk_property_change (window, window_private->dnd_drag_data_type,
1828 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1830 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1832 g_message("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1837 * Then we send the event to tell the receiving window that the
1840 tmp_ev.u.allflags = 0;
1841 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1842 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1844 sev.xclient.type = ClientMessage;
1845 sev.xclient.format = 32;
1846 sev.xclient.window = event->dragrequest.requestor;
1847 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1848 sev.xclient.data.l[0] = window_private->xwindow;
1849 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1850 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1852 if (event->dragrequest.isdrop)
1853 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1854 (event->dragrequest.drop_coords.y << 16);
1856 sev.xclient.data.l[3] = 0;
1858 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1860 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1861 StructureNotifyMask, &sev))
1862 GDK_NOTE (DND, g_message("Sending XdeDataAvailable to %#x failed\n",
1863 event->dragrequest.requestor));
1867 gdk_window_add_filter (GdkWindow *window,
1868 GdkFilterFunc function,
1871 GdkWindowPrivate *private;
1873 GdkEventFilter *filter;
1875 private = (GdkWindowPrivate*) window;
1876 if (private && private->destroyed)
1880 tmp_list = private->filters;
1882 tmp_list = gdk_default_filters;
1886 filter = (GdkEventFilter *)tmp_list->data;
1887 if ((filter->function == function) && (filter->data == data))
1889 tmp_list = tmp_list->next;
1892 filter = g_new (GdkEventFilter, 1);
1893 filter->function = function;
1894 filter->data = data;
1897 private->filters = g_list_append (private->filters, filter);
1899 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1903 gdk_window_remove_filter (GdkWindow *window,
1904 GdkFilterFunc function,
1907 GdkWindowPrivate *private;
1909 GdkEventFilter *filter;
1911 private = (GdkWindowPrivate*) window;
1914 tmp_list = private->filters;
1916 tmp_list = gdk_default_filters;
1920 filter = (GdkEventFilter *)tmp_list->data;
1921 tmp_list = tmp_list->next;
1923 if ((filter->function == function) && (filter->data == data))
1926 private->filters = g_list_remove_link (private->filters, tmp_list);
1928 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1929 g_list_free_1 (tmp_list);
1938 gdk_window_set_override_redirect(GdkWindow *window,
1939 gboolean override_redirect)
1941 GdkWindowPrivate *private;
1942 XSetWindowAttributes attr;
1944 g_return_if_fail (window != NULL);
1945 private = (GdkWindowPrivate*) window;
1946 if (private->destroyed)
1949 attr.override_redirect = (override_redirect == FALSE)?False:True;
1950 XChangeWindowAttributes(gdk_display,
1951 ((GdkWindowPrivate *)window)->xwindow,
1957 gdk_window_set_icon (GdkWindow *window,
1958 GdkWindow *icon_window,
1963 GdkWindowPrivate *window_private;
1964 GdkWindowPrivate *private;
1966 g_return_if_fail (window != NULL);
1967 window_private = (GdkWindowPrivate*) window;
1968 if (window_private->destroyed)
1973 if (icon_window != NULL)
1975 private = (GdkWindowPrivate *)icon_window;
1976 wm_hints.flags |= IconWindowHint;
1977 wm_hints.icon_window = private->xwindow;
1982 private = (GdkWindowPrivate *)pixmap;
1983 wm_hints.flags |= IconPixmapHint;
1984 wm_hints.icon_pixmap = private->xwindow;
1989 private = (GdkWindowPrivate *)mask;
1990 wm_hints.flags |= IconMaskHint;
1991 wm_hints.icon_mask = private->xwindow;
1994 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1998 gdk_window_set_icon_name (GdkWindow *window,
2001 GdkWindowPrivate *window_private;
2002 XTextProperty property;
2005 g_return_if_fail (window != NULL);
2006 window_private = (GdkWindowPrivate*) window;
2007 if (window_private->destroyed)
2009 res = XmbTextListToTextProperty (window_private->xdisplay,
2010 &name, 1, XStdICCTextStyle,
2014 g_warning("Error converting icon name to text property: %d\n", res);
2018 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
2022 XFree (property.value);
2026 gdk_window_set_group (GdkWindow *window,
2030 GdkWindowPrivate *window_private;
2031 GdkWindowPrivate *private;
2033 g_return_if_fail (window != NULL);
2034 g_return_if_fail (leader != NULL);
2035 window_private = (GdkWindowPrivate*) window;
2036 if (window_private->destroyed)
2039 private = (GdkWindowPrivate *)leader;
2040 wm_hints.flags = WindowGroupHint;
2041 wm_hints.window_group = private->xwindow;
2043 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
2047 gdk_window_set_mwm_hints (GdkWindow *window,
2048 MotifWmHints *new_hints)
2050 static Atom hints_atom = None;
2051 MotifWmHints *hints;
2057 GdkWindowPrivate *window_private;
2059 g_return_if_fail (window != NULL);
2060 window_private = (GdkWindowPrivate*) window;
2061 if (window_private->destroyed)
2065 hints_atom = XInternAtom (window_private->xdisplay,
2066 _XA_MOTIF_WM_HINTS, FALSE);
2068 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2069 hints_atom, 0, sizeof(MotifWmHints)/4,
2070 False, AnyPropertyType, &type, &format, &nitems,
2071 &bytes_after, (guchar **)&hints);
2077 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2079 hints->flags |= MWM_HINTS_FUNCTIONS;
2080 hints->functions = new_hints->functions;
2082 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2084 hints->flags |= MWM_HINTS_DECORATIONS;
2085 hints->decorations = new_hints->decorations;
2089 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2090 hints_atom, hints_atom, 32, PropModeReplace,
2091 (guchar *)hints, sizeof(MotifWmHints)/4);
2093 if (hints != new_hints)
2098 gdk_window_set_decorations (GdkWindow *window,
2099 GdkWMDecoration decorations)
2103 hints.flags = MWM_HINTS_DECORATIONS;
2104 hints.decorations = decorations;
2106 gdk_window_set_mwm_hints (window, &hints);
2110 gdk_window_set_functions (GdkWindow *window,
2111 GdkWMFunction functions)
2115 hints.flags = MWM_HINTS_FUNCTIONS;
2116 hints.functions = functions;
2118 gdk_window_set_mwm_hints (window, &hints);
2122 gdk_window_get_toplevels (void)
2124 GList *new_list = NULL;
2127 tmp_list = gdk_root_parent.children;
2130 new_list = g_list_prepend (new_list, tmp_list->data);
2131 tmp_list = tmp_list->next;
2138 gdk_drawable_set_data (GdkDrawable *drawable,
2141 GDestroyNotify destroy_func)
2143 g_dataset_set_data_full (drawable, key, data, destroy_func);