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_print ("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;
471 private = g_new (GdkWindowPrivate, 1);
472 window = (GdkWindow*) private;
474 XGetWindowAttributes (gdk_display, anid, &attrs);
476 /* FIXME: This is pretty expensive. Maybe the caller should supply
478 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
480 private->parent = gdk_xid_table_lookup (parent);
482 parent_private = (GdkWindowPrivate *)private->parent;
485 parent_private->children = g_list_prepend (parent_private->children, window);
487 private->xwindow = anid;
488 private->xdisplay = gdk_display;
489 private->x = attrs.x;
490 private->y = attrs.y;
491 private->width = attrs.width;
492 private->height = attrs.height;
493 private->resize_count = 0;
494 private->ref_count = 1;
495 private->window_type = GDK_WINDOW_FOREIGN;
496 private->destroyed = FALSE;
497 private->extension_events = 0;
499 private->colormap = NULL;
501 private->dnd_drag_data_type = None;
502 private->dnd_drag_data_typesavail =
503 private->dnd_drop_data_typesavail = NULL;
504 private->dnd_drop_enabled = private->dnd_drag_enabled =
505 private->dnd_drag_accepted = private->dnd_drag_datashow =
506 private->dnd_drop_data_numtypesavail =
507 private->dnd_drag_data_numtypesavail = 0;
508 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
510 private->filters = NULL;
511 private->children = NULL;
513 window->user_data = NULL;
515 gdk_window_ref (window);
516 gdk_xid_table_insert (&private->xwindow, window);
521 /* Call this function when you want a window and all its children to
522 disappear. When xdestroy is true, a request to destroy the XWindow
523 is sent out. When it is false, it is assumed that the XWindow has
524 been or will be destroyed by destroying some ancestor of this
528 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
529 gboolean our_destroy)
531 GdkWindowPrivate *private;
532 GdkWindowPrivate *temp_private;
533 GdkWindow *temp_window;
537 g_return_if_fail (window != NULL);
539 private = (GdkWindowPrivate*) window;
541 switch (private->window_type)
543 case GDK_WINDOW_TOPLEVEL:
544 case GDK_WINDOW_CHILD:
545 case GDK_WINDOW_DIALOG:
546 case GDK_WINDOW_TEMP:
547 case GDK_WINDOW_FOREIGN:
548 if (!private->destroyed)
552 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
553 if (parent_private->children)
554 parent_private->children = g_list_remove (parent_private->children, window);
557 if (private->window_type != GDK_WINDOW_FOREIGN)
559 children = tmp = private->children;
560 private->children = NULL;
564 temp_window = tmp->data;
567 temp_private = (GdkWindowPrivate*) temp_window;
569 gdk_window_internal_destroy (temp_window, FALSE,
573 g_list_free (children);
576 if (private->extension_events != 0)
577 gdk_input_window_destroy (window);
579 if(private->dnd_drag_data_numtypesavail > 0)
581 g_free (private->dnd_drag_data_typesavail);
582 private->dnd_drag_data_typesavail = NULL;
584 if(private->dnd_drop_data_numtypesavail > 0)
586 g_free (private->dnd_drop_data_typesavail);
587 private->dnd_drop_data_typesavail = NULL;
590 if (private->filters)
592 tmp = private->filters;
600 g_list_free (private->filters);
601 private->filters = NULL;
604 if (private->window_type == GDK_WINDOW_FOREIGN)
606 if (our_destroy && (private->parent != NULL))
608 /* It's somebody elses window, but in our heirarchy,
609 * so reparent it to the root window, and then send
610 * it a delete event, as if we were a WM
612 XClientMessageEvent xevent;
614 gdk_window_hide (window);
615 gdk_window_reparent (window, NULL, 0, 0);
617 xevent.type = ClientMessage;
618 xevent.window = private->xwindow;
619 xevent.message_type = gdk_wm_protocols;
621 xevent.data.l[0] = gdk_wm_delete_window;
622 xevent.data.l[1] = CurrentTime;
624 XSendEvent (private->xdisplay, private->xwindow,
625 False, 0, (XEvent *)&xevent);
629 XDestroyWindow (private->xdisplay, private->xwindow);
631 if (private->colormap)
632 gdk_colormap_unref (private->colormap);
634 private->destroyed = TRUE;
638 case GDK_WINDOW_ROOT:
639 g_error ("attempted to destroy root window");
642 case GDK_WINDOW_PIXMAP:
643 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
648 /* Like internal_destroy, but also destroys the reference created by
652 gdk_window_destroy (GdkWindow *window)
654 gdk_window_internal_destroy (window, TRUE, TRUE);
655 gdk_window_unref (window);
658 /* This function is called when the XWindow is really gone. */
661 gdk_window_destroy_notify (GdkWindow *window)
663 GdkWindowPrivate *private;
665 g_return_if_fail (window != NULL);
667 private = (GdkWindowPrivate*) window;
669 if (!private->destroyed)
671 if (private->window_type == GDK_WINDOW_FOREIGN)
672 gdk_window_internal_destroy (window, FALSE, FALSE);
674 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
677 gdk_xid_table_remove (private->xwindow);
678 gdk_window_unref (window);
682 gdk_window_ref (GdkWindow *window)
684 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
685 g_return_val_if_fail (window != NULL, NULL);
687 private->ref_count += 1;
692 gdk_window_unref (GdkWindow *window)
694 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
695 g_return_if_fail (window != NULL);
697 private->ref_count -= 1;
698 if (private->ref_count == 0)
700 if (!private->destroyed)
701 g_warning ("losing last reference to undestroyed window\n");
707 gdk_window_show (GdkWindow *window)
709 GdkWindowPrivate *private;
711 g_return_if_fail (window != NULL);
713 private = (GdkWindowPrivate*) window;
714 if (!private->destroyed)
716 XRaiseWindow (private->xdisplay, private->xwindow);
717 XMapWindow (private->xdisplay, private->xwindow);
722 gdk_window_hide (GdkWindow *window)
724 GdkWindowPrivate *private;
726 g_return_if_fail (window != NULL);
728 private = (GdkWindowPrivate*) window;
729 if (!private->destroyed)
730 XUnmapWindow (private->xdisplay, private->xwindow);
734 gdk_window_withdraw (GdkWindow *window)
736 GdkWindowPrivate *private;
738 g_return_if_fail (window != NULL);
740 private = (GdkWindowPrivate*) window;
741 if (!private->destroyed)
742 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
746 gdk_window_move (GdkWindow *window,
750 GdkWindowPrivate *private;
752 g_return_if_fail (window != NULL);
754 private = (GdkWindowPrivate*) window;
755 if (!private->destroyed)
757 XMoveWindow (private->xdisplay, private->xwindow, x, y);
759 if (private->window_type == GDK_WINDOW_CHILD)
768 gdk_window_resize (GdkWindow *window,
772 GdkWindowPrivate *private;
774 g_return_if_fail (window != NULL);
781 private = (GdkWindowPrivate*) window;
783 if (!private->destroyed &&
784 ((private->resize_count > 0) ||
785 (private->width != (guint16) width) ||
786 (private->height != (guint16) height)))
788 XResizeWindow (private->xdisplay, private->xwindow, width, height);
789 private->resize_count += 1;
791 if (private->window_type == GDK_WINDOW_CHILD)
793 private->width = width;
794 private->height = height;
800 gdk_window_move_resize (GdkWindow *window,
806 GdkWindowPrivate *private;
808 g_return_if_fail (window != NULL);
815 private = (GdkWindowPrivate*) window;
816 if (!private->destroyed)
818 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
820 if (private->window_type == GDK_WINDOW_CHILD)
824 private->width = width;
825 private->height = height;
831 gdk_window_reparent (GdkWindow *window,
832 GdkWindow *new_parent,
836 GdkWindowPrivate *window_private;
837 GdkWindowPrivate *parent_private;
838 GdkWindowPrivate *old_parent_private;
840 g_return_if_fail (window != NULL);
843 new_parent = (GdkWindow*) &gdk_root_parent;
845 window_private = (GdkWindowPrivate*) window;
846 old_parent_private = (GdkWindowPrivate*)window_private->parent;
847 parent_private = (GdkWindowPrivate*) new_parent;
849 if (!window_private->destroyed && !parent_private->destroyed)
850 XReparentWindow (window_private->xdisplay,
851 window_private->xwindow,
852 parent_private->xwindow,
855 old_parent_private->children = g_list_remove (old_parent_private->children, window);
856 parent_private->children = g_list_prepend (parent_private->children, window);
861 gdk_window_clear (GdkWindow *window)
863 GdkWindowPrivate *private;
865 g_return_if_fail (window != NULL);
867 private = (GdkWindowPrivate*) window;
869 if (!private->destroyed)
870 XClearWindow (private->xdisplay, private->xwindow);
874 gdk_window_clear_area (GdkWindow *window,
880 GdkWindowPrivate *private;
882 g_return_if_fail (window != NULL);
884 private = (GdkWindowPrivate*) window;
886 if (!private->destroyed)
887 XClearArea (private->xdisplay, private->xwindow,
888 x, y, width, height, False);
892 gdk_window_clear_area_e (GdkWindow *window,
898 GdkWindowPrivate *private;
900 g_return_if_fail (window != NULL);
902 private = (GdkWindowPrivate*) window;
904 if (!private->destroyed)
905 XClearArea (private->xdisplay, private->xwindow,
906 x, y, width, height, True);
910 gdk_window_copy_area (GdkWindow *window,
914 GdkWindow *source_window,
920 GdkWindowPrivate *src_private;
921 GdkWindowPrivate *dest_private;
922 GdkGCPrivate *gc_private;
924 g_return_if_fail (window != NULL);
925 g_return_if_fail (gc != NULL);
927 if (source_window == NULL)
928 source_window = window;
930 src_private = (GdkWindowPrivate*) source_window;
931 dest_private = (GdkWindowPrivate*) window;
932 gc_private = (GdkGCPrivate*) gc;
934 if (!src_private->destroyed && !dest_private->destroyed)
936 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
945 gdk_window_raise (GdkWindow *window)
947 GdkWindowPrivate *private;
949 g_return_if_fail (window != NULL);
951 private = (GdkWindowPrivate*) window;
953 if (!private->destroyed)
954 XRaiseWindow (private->xdisplay, private->xwindow);
958 gdk_window_lower (GdkWindow *window)
960 GdkWindowPrivate *private;
962 g_return_if_fail (window != NULL);
964 private = (GdkWindowPrivate*) window;
966 if (!private->destroyed)
967 XLowerWindow (private->xdisplay, private->xwindow);
971 gdk_window_set_user_data (GdkWindow *window,
974 g_return_if_fail (window != NULL);
976 window->user_data = user_data;
980 gdk_window_set_hints (GdkWindow *window,
989 GdkWindowPrivate *private;
990 XSizeHints size_hints;
992 g_return_if_fail (window != NULL);
994 private = (GdkWindowPrivate*) window;
995 if (private->destroyed)
998 size_hints.flags = 0;
1000 if (flags & GDK_HINT_POS)
1002 size_hints.flags |= PPosition;
1007 if (flags & GDK_HINT_MIN_SIZE)
1009 size_hints.flags |= PMinSize;
1010 size_hints.min_width = min_width;
1011 size_hints.min_height = min_height;
1014 if (flags & GDK_HINT_MAX_SIZE)
1016 size_hints.flags |= PMaxSize;
1017 size_hints.max_width = max_width;
1018 size_hints.max_height = max_height;
1022 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1026 gdk_window_set_title (GdkWindow *window,
1029 GdkWindowPrivate *private;
1031 g_return_if_fail (window != NULL);
1033 private = (GdkWindowPrivate*) window;
1034 if (!private->destroyed)
1035 XmbSetWMProperties (private->xdisplay, private->xwindow,
1036 title, title, NULL, 0, NULL, NULL, NULL);
1040 gdk_window_set_background (GdkWindow *window,
1043 GdkWindowPrivate *private;
1045 g_return_if_fail (window != NULL);
1047 private = (GdkWindowPrivate*) window;
1048 if (!private->destroyed)
1049 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1053 gdk_window_set_back_pixmap (GdkWindow *window,
1055 gint parent_relative)
1057 GdkWindowPrivate *window_private;
1058 GdkPixmapPrivate *pixmap_private;
1061 g_return_if_fail (window != NULL);
1063 window_private = (GdkWindowPrivate*) window;
1064 pixmap_private = (GdkPixmapPrivate*) pixmap;
1067 xpixmap = pixmap_private->xwindow;
1071 if (parent_relative)
1072 xpixmap = ParentRelative;
1074 if (!window_private->destroyed)
1075 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1079 gdk_window_set_cursor (GdkWindow *window,
1082 GdkWindowPrivate *window_private;
1083 GdkCursorPrivate *cursor_private;
1086 g_return_if_fail (window != NULL);
1088 window_private = (GdkWindowPrivate*) window;
1089 cursor_private = (GdkCursorPrivate*) cursor;
1094 xcursor = cursor_private->xcursor;
1096 if (!window_private->destroyed)
1097 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1101 gdk_window_set_colormap (GdkWindow *window,
1102 GdkColormap *colormap)
1104 GdkWindowPrivate *window_private;
1105 GdkColormapPrivate *colormap_private;
1107 g_return_if_fail (window != NULL);
1108 g_return_if_fail (colormap != NULL);
1110 window_private = (GdkWindowPrivate*) window;
1111 colormap_private = (GdkColormapPrivate*) colormap;
1113 if (!window_private->destroyed)
1115 XSetWindowColormap (window_private->xdisplay,
1116 window_private->xwindow,
1117 colormap_private->xcolormap);
1119 if (window_private->colormap)
1120 gdk_colormap_unref (window_private->colormap);
1121 window_private->colormap = colormap;
1122 gdk_colormap_ref (window_private->colormap);
1124 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1125 gdk_window_add_colormap_windows (window);
1130 gdk_window_get_user_data (GdkWindow *window,
1133 g_return_if_fail (window != NULL);
1135 *data = window->user_data;
1139 gdk_window_get_geometry (GdkWindow *window,
1146 GdkWindowPrivate *window_private;
1152 guint tborder_width;
1156 window = (GdkWindow*) &gdk_root_parent;
1158 window_private = (GdkWindowPrivate*) window;
1160 if (!window_private->destroyed)
1162 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1163 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1179 gdk_window_get_position (GdkWindow *window,
1183 GdkWindowPrivate *window_private;
1185 g_return_if_fail (window != NULL);
1187 window_private = (GdkWindowPrivate*) window;
1190 *x = window_private->x;
1192 *y = window_private->y;
1196 gdk_window_get_size (GdkWindow *window,
1200 GdkWindowPrivate *window_private;
1202 g_return_if_fail (window != NULL);
1204 window_private = (GdkWindowPrivate*) window;
1207 *width = window_private->width;
1209 *height = window_private->height;
1213 gdk_window_get_visual (GdkWindow *window)
1215 GdkWindowPrivate *window_private;
1216 XWindowAttributes window_attributes;
1218 g_return_val_if_fail (window != NULL, NULL);
1220 window_private = (GdkWindowPrivate*) window;
1221 /* Huh? ->parent is never set for a pixmap. We should just return
1224 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1225 window_private = (GdkWindowPrivate*) window_private->parent;
1227 if (window_private && !window_private->destroyed)
1229 if (window_private->colormap == NULL)
1231 XGetWindowAttributes (window_private->xdisplay,
1232 window_private->xwindow,
1233 &window_attributes);
1234 return gdk_visual_lookup (window_attributes.visual);
1237 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1244 gdk_window_get_colormap (GdkWindow *window)
1246 GdkWindowPrivate *window_private;
1247 XWindowAttributes window_attributes;
1249 g_return_val_if_fail (window != NULL, NULL);
1250 window_private = (GdkWindowPrivate*) window;
1252 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1253 if (!window_private->destroyed)
1255 if (window_private->colormap == NULL)
1257 XGetWindowAttributes (window_private->xdisplay,
1258 window_private->xwindow,
1259 &window_attributes);
1260 return gdk_colormap_lookup (window_attributes.colormap);
1263 return window_private->colormap;
1270 gdk_window_get_type (GdkWindow *window)
1272 GdkWindowPrivate *window_private;
1274 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1276 window_private = (GdkWindowPrivate*) window;
1277 return window_private->window_type;
1281 gdk_window_get_origin (GdkWindow *window,
1285 GdkWindowPrivate *private;
1290 g_return_val_if_fail (window != NULL, 0);
1292 private = (GdkWindowPrivate*) window;
1294 if (!private->destroyed)
1296 return_val = XTranslateCoordinates (private->xdisplay,
1314 gdk_window_get_pointer (GdkWindow *window,
1317 GdkModifierType *mask)
1319 GdkWindowPrivate *private;
1320 GdkWindow *return_val;
1328 window = (GdkWindow*) &gdk_root_parent;
1330 private = (GdkWindowPrivate*) window;
1333 if (!private->destroyed &&
1334 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1335 &rootx, &rooty, &winx, &winy, &xmask))
1339 if (mask) *mask = xmask;
1342 return_val = gdk_window_lookup (child);
1349 gdk_window_at_pointer (gint *win_x,
1352 GdkWindowPrivate *private;
1356 Window xwindow_last = 0;
1357 int rootx = -1, rooty = -1;
1361 private = &gdk_root_parent;
1363 xwindow = private->xwindow;
1365 XGrabServer (private->xdisplay);
1368 xwindow_last = xwindow;
1369 XQueryPointer (private->xdisplay,
1376 XUngrabServer (private->xdisplay);
1378 window = gdk_window_lookup (xwindow_last);
1381 *win_x = window ? winx : -1;
1383 *win_y = window ? winy : -1;
1389 gdk_window_get_parent (GdkWindow *window)
1391 g_return_val_if_fail (window != NULL, NULL);
1393 return ((GdkWindowPrivate*) window)->parent;
1397 gdk_window_get_toplevel (GdkWindow *window)
1399 GdkWindowPrivate *private;
1401 g_return_val_if_fail (window != NULL, NULL);
1403 private = (GdkWindowPrivate*) window;
1405 while (private->window_type == GDK_WINDOW_CHILD)
1407 window = ((GdkWindowPrivate*) window)->parent;
1408 private = (GdkWindowPrivate*) window;
1415 gdk_window_get_children (GdkWindow *window)
1417 GdkWindowPrivate *private;
1423 unsigned int nchildren;
1426 g_return_val_if_fail (window != NULL, NULL);
1428 private = (GdkWindowPrivate*) window;
1429 if (private->destroyed)
1432 XQueryTree (private->xdisplay, private->xwindow,
1433 &root, &parent, &xchildren, &nchildren);
1439 for (i = 0; i < nchildren; i++)
1441 child = gdk_window_lookup (xchildren[i]);
1443 children = g_list_prepend (children, child);
1453 gdk_window_get_events (GdkWindow *window)
1455 GdkWindowPrivate *private;
1456 XWindowAttributes attrs;
1457 GdkEventMask event_mask;
1460 g_return_val_if_fail (window != NULL, 0);
1462 private = (GdkWindowPrivate*) window;
1463 if (private->destroyed)
1466 XGetWindowAttributes (gdk_display, private->xwindow,
1470 for (i = 0; i < nevent_masks; i++)
1472 if (attrs.your_event_mask & event_mask_table[i])
1473 event_mask |= 1 << (i + 1);
1480 gdk_window_set_events (GdkWindow *window,
1481 GdkEventMask event_mask)
1483 GdkWindowPrivate *private;
1487 g_return_if_fail (window != NULL);
1489 private = (GdkWindowPrivate*) window;
1490 if (private->destroyed)
1493 xevent_mask = StructureNotifyMask;
1494 for (i = 0; i < nevent_masks; i++)
1496 if (event_mask & (1 << (i + 1)))
1497 xevent_mask |= event_mask_table[i];
1500 XSelectInput (gdk_display, private->xwindow,
1505 gdk_window_add_colormap_windows (GdkWindow *window)
1507 GdkWindow *toplevel;
1508 GdkWindowPrivate *toplevel_private;
1509 GdkWindowPrivate *window_private;
1510 Window *old_windows;
1511 Window *new_windows;
1514 g_return_if_fail (window != NULL);
1516 toplevel = gdk_window_get_toplevel (window);
1517 toplevel_private = (GdkWindowPrivate*) toplevel;
1518 window_private = (GdkWindowPrivate*) window;
1519 if (window_private->destroyed)
1522 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1523 toplevel_private->xwindow,
1524 &old_windows, &count))
1530 for (i = 0; i < count; i++)
1531 if (old_windows[i] == window_private->xwindow)
1534 new_windows = g_new (Window, count + 1);
1536 for (i = 0; i < count; i++)
1537 new_windows[i] = old_windows[i];
1538 new_windows[count] = window_private->xwindow;
1540 XSetWMColormapWindows (toplevel_private->xdisplay,
1541 toplevel_private->xwindow,
1542 new_windows, count + 1);
1544 g_free (new_windows);
1546 XFree (old_windows);
1550 * This needs the X11 shape extension.
1551 * If not available, shaped windows will look
1552 * ugly, but programs still work. Stefan Wille
1555 gdk_window_shape_combine_mask (GdkWindow *window,
1559 enum { UNKNOWN, NO, YES };
1561 static gint have_shape = UNKNOWN;
1563 GdkWindowPrivate *window_private;
1566 g_return_if_fail (window != NULL);
1568 #ifdef HAVE_SHAPE_EXT
1569 if (have_shape == UNKNOWN)
1572 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1578 if (have_shape == YES)
1580 window_private = (GdkWindowPrivate*) window;
1581 if (window_private->destroyed)
1586 GdkWindowPrivate *pixmap_private;
1588 pixmap_private = (GdkWindowPrivate*) mask;
1589 pixmap = (Pixmap) pixmap_private->xwindow;
1598 XShapeCombineMask (window_private->xdisplay,
1599 window_private->xwindow,
1605 #endif /* HAVE_SHAPE_EXT */
1609 gdk_dnd_drag_addwindow (GdkWindow *window)
1611 GdkWindowPrivate *window_private;
1613 g_return_if_fail (window != NULL);
1615 window_private = (GdkWindowPrivate *) window;
1616 if (window_private->destroyed)
1619 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1621 gdk_dnd.drag_numwindows++;
1622 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1623 gdk_dnd.drag_numwindows
1624 * sizeof(GdkWindow *));
1625 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1626 window_private->dnd_drag_accepted = 0;
1629 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1633 gdk_window_dnd_drag_set (GdkWindow *window,
1638 GdkWindowPrivate *window_private;
1641 g_return_if_fail (window != NULL);
1642 window_private = (GdkWindowPrivate *) window;
1643 if (window_private->destroyed)
1646 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1650 g_return_if_fail(typelist != NULL);
1652 if (window_private->dnd_drag_data_numtypesavail > 3)
1654 window_private->dnd_drag_data_numtypesavail = numtypes;
1656 window_private->dnd_drag_data_typesavail =
1657 g_realloc (window_private->dnd_drag_data_typesavail,
1658 (numtypes + 1) * sizeof (GdkAtom));
1660 for (i = 0; i < numtypes; i++)
1662 /* Allow blanket use of ALL to get anything... */
1663 if (strcmp (typelist[i], "ALL"))
1664 window_private->dnd_drag_data_typesavail[i] =
1665 gdk_atom_intern (typelist[i], FALSE);
1667 window_private->dnd_drag_data_typesavail[i] = None;
1671 * set our extended type list if we need to
1674 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1675 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1676 (guchar *)(window_private->dnd_drag_data_typesavail
1677 + (sizeof(GdkAtom) * 3)),
1678 (numtypes - 3) * sizeof(GdkAtom));
1680 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1684 g_free (window_private->dnd_drag_data_typesavail);
1685 window_private->dnd_drag_data_typesavail = NULL;
1686 window_private->dnd_drag_data_numtypesavail = 0;
1691 gdk_window_dnd_drop_set (GdkWindow *window,
1695 guint8 destructive_op)
1697 GdkWindowPrivate *window_private;
1700 g_return_if_fail (window != NULL);
1701 window_private = (GdkWindowPrivate *) window;
1702 if (window_private->destroyed)
1705 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1708 g_return_if_fail(typelist != NULL);
1710 window_private->dnd_drop_data_numtypesavail = numtypes;
1712 window_private->dnd_drop_data_typesavail =
1713 g_realloc (window_private->dnd_drop_data_typesavail,
1714 (numtypes + 1) * sizeof (GdkAtom));
1716 for (i = 0; i < numtypes; i++)
1717 window_private->dnd_drop_data_typesavail[i] =
1718 gdk_atom_intern (typelist[i], FALSE);
1720 window_private->dnd_drop_destructive_op = destructive_op;
1725 * This is used to reply to a GDK_DRAG_REQUEST event
1726 * (which may be generated by XdeRequest or a confirmed drop...
1729 gdk_window_dnd_data_set (GdkWindow *window,
1732 gulong data_numbytes)
1734 GdkWindowPrivate *window_private;
1736 GdkEventDropDataAvailable tmp_ev;
1739 g_return_if_fail (window != NULL);
1740 g_return_if_fail (event != NULL);
1741 g_return_if_fail (data != NULL);
1742 g_return_if_fail (data_numbytes > 0);
1743 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1745 window_private = (GdkWindowPrivate *) window;
1746 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1747 if (window_private->destroyed)
1750 /* We set the property on our window... */
1751 gdk_property_change (window, window_private->dnd_drag_data_type,
1752 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1754 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1756 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1761 * Then we send the event to tell the receiving window that the
1764 tmp_ev.u.allflags = 0;
1765 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1766 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1768 sev.xclient.type = ClientMessage;
1769 sev.xclient.format = 32;
1770 sev.xclient.window = event->dragrequest.requestor;
1771 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1772 sev.xclient.data.l[0] = window_private->xwindow;
1773 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1774 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1776 if (event->dragrequest.isdrop)
1777 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1778 (event->dragrequest.drop_coords.y << 16);
1780 sev.xclient.data.l[3] = 0;
1782 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1784 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1785 StructureNotifyMask, &sev))
1786 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1787 event->dragrequest.requestor));
1792 gdk_window_add_filter (GdkWindow *window,
1793 GdkFilterFunc function,
1796 GdkWindowPrivate *private;
1798 GdkEventFilter *filter;
1800 private = (GdkWindowPrivate*) window;
1801 if (private && private->destroyed)
1805 tmp_list = private->filters;
1807 tmp_list = gdk_default_filters;
1811 filter = (GdkEventFilter *)tmp_list->data;
1812 if ((filter->function == function) && (filter->data == data))
1814 tmp_list = tmp_list->next;
1817 filter = g_new (GdkEventFilter, 1);
1818 filter->function = function;
1819 filter->data = data;
1822 private->filters = g_list_append (private->filters, filter);
1824 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1828 gdk_window_remove_filter (GdkWindow *window,
1829 GdkFilterFunc function,
1832 GdkWindowPrivate *private;
1834 GdkEventFilter *filter;
1836 private = (GdkWindowPrivate*) window;
1839 tmp_list = private->filters;
1841 tmp_list = gdk_default_filters;
1845 filter = (GdkEventFilter *)tmp_list->data;
1846 tmp_list = tmp_list->next;
1848 if ((filter->function == function) && (filter->data == data))
1851 private->filters = g_list_remove_link (private->filters, tmp_list);
1853 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1854 g_list_free_1 (tmp_list);
1863 gdk_window_set_override_redirect(GdkWindow *window,
1864 gboolean override_redirect)
1866 GdkWindowPrivate *private;
1867 XSetWindowAttributes attr;
1869 g_return_if_fail (window != NULL);
1870 private = (GdkWindowPrivate*) window;
1871 if (private->destroyed)
1874 attr.override_redirect = (override_redirect == FALSE)?False:True;
1875 XChangeWindowAttributes(gdk_display,
1876 ((GdkWindowPrivate *)window)->xwindow,
1882 gdk_window_set_icon (GdkWindow *window,
1883 GdkWindow *icon_window,
1888 GdkWindowPrivate *window_private;
1889 GdkWindowPrivate *private;
1891 g_return_if_fail (window != NULL);
1892 window_private = (GdkWindowPrivate*) window;
1893 if (window_private->destroyed)
1898 if (icon_window != NULL)
1900 private = (GdkWindowPrivate *)icon_window;
1901 wm_hints.flags |= IconWindowHint;
1902 wm_hints.icon_window = private->xwindow;
1907 private = (GdkWindowPrivate *)pixmap;
1908 wm_hints.flags |= IconPixmapHint;
1909 wm_hints.icon_pixmap = private->xwindow;
1914 private = (GdkWindowPrivate *)mask;
1915 wm_hints.flags |= IconMaskHint;
1916 wm_hints.icon_mask = private->xwindow;
1919 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1923 gdk_window_set_icon_name (GdkWindow *window,
1926 GdkWindowPrivate *window_private;
1927 XTextProperty property;
1930 g_return_if_fail (window != NULL);
1931 window_private = (GdkWindowPrivate*) window;
1932 if (window_private->destroyed)
1934 res = XmbTextListToTextProperty (window_private->xdisplay,
1935 &name, 1, XStdICCTextStyle,
1939 g_warning("Error converting icon name to text property: %d\n", res);
1943 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1946 XFree(property.value);
1950 gdk_window_set_group (GdkWindow *window,
1954 GdkWindowPrivate *window_private;
1955 GdkWindowPrivate *private;
1957 g_return_if_fail (window != NULL);
1958 g_return_if_fail (leader != NULL);
1959 window_private = (GdkWindowPrivate*) window;
1960 if (window_private->destroyed)
1963 private = (GdkWindowPrivate *)leader;
1964 wm_hints.flags = WindowGroupHint;
1965 wm_hints.window_group = private->xwindow;
1967 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1971 gdk_window_set_mwm_hints (GdkWindow *window,
1972 MotifWmHints *new_hints)
1974 static Atom hints_atom = None;
1975 MotifWmHints *hints;
1981 GdkWindowPrivate *window_private;
1983 g_return_if_fail (window != NULL);
1984 window_private = (GdkWindowPrivate*) window;
1985 if (window_private->destroyed)
1989 hints_atom = XInternAtom (window_private->xdisplay,
1990 _XA_MOTIF_WM_HINTS, FALSE);
1992 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1993 hints_atom, 0, sizeof(MotifWmHints)/4,
1994 False, AnyPropertyType, &type, &format, &nitems,
1995 &bytes_after, (guchar **)&hints);
2001 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2003 hints->flags |= MWM_HINTS_FUNCTIONS;
2004 hints->functions = new_hints->functions;
2006 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2008 hints->flags |= MWM_HINTS_DECORATIONS;
2009 hints->decorations = new_hints->decorations;
2013 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2014 hints_atom, hints_atom, 32, PropModeReplace,
2015 (guchar *)hints, sizeof(MotifWmHints)/4);
2017 if (hints != new_hints)
2022 gdk_window_set_decorations (GdkWindow *window,
2023 GdkWMDecoration decorations)
2027 hints.flags = MWM_HINTS_DECORATIONS;
2028 hints.decorations = decorations;
2030 gdk_window_set_mwm_hints (window, &hints);
2034 gdk_window_set_functions (GdkWindow *window,
2035 GdkWMFunction functions)
2039 hints.flags = MWM_HINTS_FUNCTIONS;
2040 hints.functions = functions;
2042 gdk_window_set_mwm_hints (window, &hints);
2046 gdk_window_get_toplevels (void)
2048 GList *new_list = NULL;
2051 tmp_list = gdk_root_parent.children;
2054 new_list = g_list_prepend (new_list, tmp_list->data);
2055 tmp_list = tmp_list->next;