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 = 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_pointer (GdkWindow *window,
1329 GdkModifierType *mask)
1331 GdkWindowPrivate *private;
1332 GdkWindow *return_val;
1338 unsigned int xmask = 0;
1341 window = (GdkWindow*) &gdk_root_parent;
1343 private = (GdkWindowPrivate*) window;
1346 if (!private->destroyed &&
1347 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1348 &rootx, &rooty, &winx, &winy, &xmask))
1351 return_val = gdk_window_lookup (child);
1365 gdk_window_at_pointer (gint *win_x,
1368 GdkWindowPrivate *private;
1372 Window xwindow_last = 0;
1373 int rootx = -1, rooty = -1;
1377 private = &gdk_root_parent;
1379 xwindow = private->xwindow;
1381 XGrabServer (private->xdisplay);
1384 xwindow_last = xwindow;
1385 XQueryPointer (private->xdisplay,
1392 XUngrabServer (private->xdisplay);
1394 window = gdk_window_lookup (xwindow_last);
1397 *win_x = window ? winx : -1;
1399 *win_y = window ? winy : -1;
1405 gdk_window_get_parent (GdkWindow *window)
1407 g_return_val_if_fail (window != NULL, NULL);
1409 return ((GdkWindowPrivate*) window)->parent;
1413 gdk_window_get_toplevel (GdkWindow *window)
1415 GdkWindowPrivate *private;
1417 g_return_val_if_fail (window != NULL, NULL);
1419 private = (GdkWindowPrivate*) window;
1421 while (private->window_type == GDK_WINDOW_CHILD)
1423 window = ((GdkWindowPrivate*) window)->parent;
1424 private = (GdkWindowPrivate*) window;
1431 gdk_window_get_children (GdkWindow *window)
1433 GdkWindowPrivate *private;
1439 unsigned int nchildren;
1442 g_return_val_if_fail (window != NULL, NULL);
1444 private = (GdkWindowPrivate*) window;
1445 if (private->destroyed)
1448 XQueryTree (private->xdisplay, private->xwindow,
1449 &root, &parent, &xchildren, &nchildren);
1455 for (i = 0; i < nchildren; i++)
1457 child = gdk_window_lookup (xchildren[i]);
1459 children = g_list_prepend (children, child);
1470 gdk_window_get_events (GdkWindow *window)
1472 GdkWindowPrivate *private;
1473 XWindowAttributes attrs;
1474 GdkEventMask event_mask;
1477 g_return_val_if_fail (window != NULL, 0);
1479 private = (GdkWindowPrivate*) window;
1480 if (private->destroyed)
1483 XGetWindowAttributes (gdk_display, private->xwindow,
1487 for (i = 0; i < nevent_masks; i++)
1489 if (attrs.your_event_mask & event_mask_table[i])
1490 event_mask |= 1 << (i + 1);
1497 gdk_window_set_events (GdkWindow *window,
1498 GdkEventMask event_mask)
1500 GdkWindowPrivate *private;
1504 g_return_if_fail (window != NULL);
1506 private = (GdkWindowPrivate*) window;
1507 if (private->destroyed)
1510 xevent_mask = StructureNotifyMask;
1511 for (i = 0; i < nevent_masks; i++)
1513 if (event_mask & (1 << (i + 1)))
1514 xevent_mask |= event_mask_table[i];
1517 XSelectInput (gdk_display, private->xwindow,
1522 gdk_window_add_colormap_windows (GdkWindow *window)
1524 GdkWindow *toplevel;
1525 GdkWindowPrivate *toplevel_private;
1526 GdkWindowPrivate *window_private;
1527 Window *old_windows;
1528 Window *new_windows;
1531 g_return_if_fail (window != NULL);
1533 toplevel = gdk_window_get_toplevel (window);
1534 toplevel_private = (GdkWindowPrivate*) toplevel;
1535 window_private = (GdkWindowPrivate*) window;
1536 if (window_private->destroyed)
1540 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1541 toplevel_private->xwindow,
1542 &old_windows, &count))
1547 for (i = 0; i < count; i++)
1548 if (old_windows[i] == window_private->xwindow)
1550 XFree (old_windows);
1554 new_windows = g_new (Window, count + 1);
1556 for (i = 0; i < count; i++)
1557 new_windows[i] = old_windows[i];
1558 new_windows[count] = window_private->xwindow;
1560 XSetWMColormapWindows (toplevel_private->xdisplay,
1561 toplevel_private->xwindow,
1562 new_windows, count + 1);
1564 g_free (new_windows);
1566 XFree (old_windows);
1570 * This needs the X11 shape extension.
1571 * If not available, shaped windows will look
1572 * ugly, but programs still work. Stefan Wille
1575 gdk_window_shape_combine_mask (GdkWindow *window,
1579 enum { UNKNOWN, NO, YES };
1581 static gint have_shape = UNKNOWN;
1583 GdkWindowPrivate *window_private;
1586 g_return_if_fail (window != NULL);
1588 #ifdef HAVE_SHAPE_EXT
1589 if (have_shape == UNKNOWN)
1592 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1598 if (have_shape == YES)
1600 window_private = (GdkWindowPrivate*) window;
1601 if (window_private->destroyed)
1606 GdkWindowPrivate *pixmap_private;
1608 pixmap_private = (GdkWindowPrivate*) mask;
1609 pixmap = (Pixmap) pixmap_private->xwindow;
1618 XShapeCombineMask (window_private->xdisplay,
1619 window_private->xwindow,
1625 #endif /* HAVE_SHAPE_EXT */
1629 gdk_dnd_drag_addwindow (GdkWindow *window)
1631 GdkWindowPrivate *window_private;
1633 g_return_if_fail (window != NULL);
1635 window_private = (GdkWindowPrivate *) window;
1636 if (window_private->destroyed)
1639 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1641 gdk_dnd.drag_numwindows++;
1642 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1643 gdk_dnd.drag_numwindows
1644 * sizeof(GdkWindow *));
1645 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1646 window_private->dnd_drag_accepted = 0;
1649 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1653 gdk_window_dnd_drag_set (GdkWindow *window,
1658 GdkWindowPrivate *window_private;
1661 g_return_if_fail (window != NULL);
1662 window_private = (GdkWindowPrivate *) window;
1663 if (window_private->destroyed)
1666 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1670 g_return_if_fail(typelist != NULL);
1672 if (window_private->dnd_drag_data_numtypesavail > 3)
1674 window_private->dnd_drag_data_numtypesavail = numtypes;
1676 window_private->dnd_drag_data_typesavail =
1677 g_realloc (window_private->dnd_drag_data_typesavail,
1678 (numtypes + 1) * sizeof (GdkAtom));
1680 for (i = 0; i < numtypes; i++)
1682 /* Allow blanket use of ALL to get anything... */
1683 if (strcmp (typelist[i], "ALL"))
1684 window_private->dnd_drag_data_typesavail[i] =
1685 gdk_atom_intern (typelist[i], FALSE);
1687 window_private->dnd_drag_data_typesavail[i] = None;
1691 * set our extended type list if we need to
1694 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1695 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1696 (guchar *)(window_private->dnd_drag_data_typesavail
1697 + (sizeof(GdkAtom) * 3)),
1698 (numtypes - 3) * sizeof(GdkAtom));
1700 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1704 g_free (window_private->dnd_drag_data_typesavail);
1705 window_private->dnd_drag_data_typesavail = NULL;
1706 window_private->dnd_drag_data_numtypesavail = 0;
1711 gdk_window_dnd_drop_set (GdkWindow *window,
1715 guint8 destructive_op)
1717 GdkWindowPrivate *window_private;
1720 g_return_if_fail (window != NULL);
1721 window_private = (GdkWindowPrivate *) window;
1722 if (window_private->destroyed)
1725 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1728 g_return_if_fail(typelist != NULL);
1730 window_private->dnd_drop_data_numtypesavail = numtypes;
1732 window_private->dnd_drop_data_typesavail =
1733 g_realloc (window_private->dnd_drop_data_typesavail,
1734 (numtypes + 1) * sizeof (GdkAtom));
1736 for (i = 0; i < numtypes; i++)
1737 window_private->dnd_drop_data_typesavail[i] =
1738 gdk_atom_intern (typelist[i], FALSE);
1740 window_private->dnd_drop_destructive_op = destructive_op;
1745 * This is used to reply to a GDK_DRAG_REQUEST event
1746 * (which may be generated by XdeRequest or a confirmed drop...
1749 gdk_window_dnd_data_set (GdkWindow *window,
1752 gulong data_numbytes)
1754 GdkWindowPrivate *window_private;
1756 GdkEventDropDataAvailable tmp_ev;
1759 g_return_if_fail (window != NULL);
1760 g_return_if_fail (event != NULL);
1761 g_return_if_fail (data != NULL);
1762 g_return_if_fail (data_numbytes > 0);
1763 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1765 window_private = (GdkWindowPrivate *) window;
1766 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1767 if (window_private->destroyed)
1770 /* We set the property on our window... */
1771 gdk_property_change (window, window_private->dnd_drag_data_type,
1772 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1774 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1776 g_message("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1781 * Then we send the event to tell the receiving window that the
1784 tmp_ev.u.allflags = 0;
1785 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1786 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1788 sev.xclient.type = ClientMessage;
1789 sev.xclient.format = 32;
1790 sev.xclient.window = event->dragrequest.requestor;
1791 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1792 sev.xclient.data.l[0] = window_private->xwindow;
1793 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1794 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1796 if (event->dragrequest.isdrop)
1797 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1798 (event->dragrequest.drop_coords.y << 16);
1800 sev.xclient.data.l[3] = 0;
1802 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1804 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1805 StructureNotifyMask, &sev))
1806 GDK_NOTE (DND, g_message("Sending XdeDataAvailable to %#x failed\n",
1807 event->dragrequest.requestor));
1811 gdk_window_add_filter (GdkWindow *window,
1812 GdkFilterFunc function,
1815 GdkWindowPrivate *private;
1817 GdkEventFilter *filter;
1819 private = (GdkWindowPrivate*) window;
1820 if (private && private->destroyed)
1824 tmp_list = private->filters;
1826 tmp_list = gdk_default_filters;
1830 filter = (GdkEventFilter *)tmp_list->data;
1831 if ((filter->function == function) && (filter->data == data))
1833 tmp_list = tmp_list->next;
1836 filter = g_new (GdkEventFilter, 1);
1837 filter->function = function;
1838 filter->data = data;
1841 private->filters = g_list_append (private->filters, filter);
1843 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1847 gdk_window_remove_filter (GdkWindow *window,
1848 GdkFilterFunc function,
1851 GdkWindowPrivate *private;
1853 GdkEventFilter *filter;
1855 private = (GdkWindowPrivate*) window;
1858 tmp_list = private->filters;
1860 tmp_list = gdk_default_filters;
1864 filter = (GdkEventFilter *)tmp_list->data;
1865 tmp_list = tmp_list->next;
1867 if ((filter->function == function) && (filter->data == data))
1870 private->filters = g_list_remove_link (private->filters, tmp_list);
1872 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1873 g_list_free_1 (tmp_list);
1882 gdk_window_set_override_redirect(GdkWindow *window,
1883 gboolean override_redirect)
1885 GdkWindowPrivate *private;
1886 XSetWindowAttributes attr;
1888 g_return_if_fail (window != NULL);
1889 private = (GdkWindowPrivate*) window;
1890 if (private->destroyed)
1893 attr.override_redirect = (override_redirect == FALSE)?False:True;
1894 XChangeWindowAttributes(gdk_display,
1895 ((GdkWindowPrivate *)window)->xwindow,
1901 gdk_window_set_icon (GdkWindow *window,
1902 GdkWindow *icon_window,
1907 GdkWindowPrivate *window_private;
1908 GdkWindowPrivate *private;
1910 g_return_if_fail (window != NULL);
1911 window_private = (GdkWindowPrivate*) window;
1912 if (window_private->destroyed)
1917 if (icon_window != NULL)
1919 private = (GdkWindowPrivate *)icon_window;
1920 wm_hints.flags |= IconWindowHint;
1921 wm_hints.icon_window = private->xwindow;
1926 private = (GdkWindowPrivate *)pixmap;
1927 wm_hints.flags |= IconPixmapHint;
1928 wm_hints.icon_pixmap = private->xwindow;
1933 private = (GdkWindowPrivate *)mask;
1934 wm_hints.flags |= IconMaskHint;
1935 wm_hints.icon_mask = private->xwindow;
1938 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1942 gdk_window_set_icon_name (GdkWindow *window,
1945 GdkWindowPrivate *window_private;
1946 XTextProperty property;
1949 g_return_if_fail (window != NULL);
1950 window_private = (GdkWindowPrivate*) window;
1951 if (window_private->destroyed)
1953 res = XmbTextListToTextProperty (window_private->xdisplay,
1954 &name, 1, XStdICCTextStyle,
1958 g_warning("Error converting icon name to text property: %d\n", res);
1962 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1966 XFree (property.value);
1970 gdk_window_set_group (GdkWindow *window,
1974 GdkWindowPrivate *window_private;
1975 GdkWindowPrivate *private;
1977 g_return_if_fail (window != NULL);
1978 g_return_if_fail (leader != NULL);
1979 window_private = (GdkWindowPrivate*) window;
1980 if (window_private->destroyed)
1983 private = (GdkWindowPrivate *)leader;
1984 wm_hints.flags = WindowGroupHint;
1985 wm_hints.window_group = private->xwindow;
1987 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1991 gdk_window_set_mwm_hints (GdkWindow *window,
1992 MotifWmHints *new_hints)
1994 static Atom hints_atom = None;
1995 MotifWmHints *hints;
2001 GdkWindowPrivate *window_private;
2003 g_return_if_fail (window != NULL);
2004 window_private = (GdkWindowPrivate*) window;
2005 if (window_private->destroyed)
2009 hints_atom = XInternAtom (window_private->xdisplay,
2010 _XA_MOTIF_WM_HINTS, FALSE);
2012 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2013 hints_atom, 0, sizeof(MotifWmHints)/4,
2014 False, AnyPropertyType, &type, &format, &nitems,
2015 &bytes_after, (guchar **)&hints);
2021 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2023 hints->flags |= MWM_HINTS_FUNCTIONS;
2024 hints->functions = new_hints->functions;
2026 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2028 hints->flags |= MWM_HINTS_DECORATIONS;
2029 hints->decorations = new_hints->decorations;
2033 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2034 hints_atom, hints_atom, 32, PropModeReplace,
2035 (guchar *)hints, sizeof(MotifWmHints)/4);
2037 if (hints != new_hints)
2042 gdk_window_set_decorations (GdkWindow *window,
2043 GdkWMDecoration decorations)
2047 hints.flags = MWM_HINTS_DECORATIONS;
2048 hints.decorations = decorations;
2050 gdk_window_set_mwm_hints (window, &hints);
2054 gdk_window_set_functions (GdkWindow *window,
2055 GdkWMFunction functions)
2059 hints.flags = MWM_HINTS_FUNCTIONS;
2060 hints.functions = functions;
2062 gdk_window_set_mwm_hints (window, &hints);
2066 gdk_window_get_toplevels (void)
2068 GList *new_list = NULL;
2071 tmp_list = gdk_root_parent.children;
2074 new_list = g_list_prepend (new_list, tmp_list->data);
2075 tmp_list = tmp_list->next;
2082 gdk_drawable_set_data (GdkDrawable *drawable,
2085 GDestroyNotify destroy_func)
2087 g_dataset_set_data_full (drawable, key, data, destroy_func);