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;
1291 g_return_val_if_fail (window != NULL, 0);
1293 private = (GdkWindowPrivate*) window;
1295 if (!private->destroyed)
1297 return_val = XTranslateCoordinates (private->xdisplay,
1316 gdk_window_get_pointer (GdkWindow *window,
1319 GdkModifierType *mask)
1321 GdkWindowPrivate *private;
1322 GdkWindow *return_val;
1328 unsigned int xmask = 0;
1331 window = (GdkWindow*) &gdk_root_parent;
1333 private = (GdkWindowPrivate*) window;
1336 if (!private->destroyed &&
1337 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1338 &rootx, &rooty, &winx, &winy, &xmask))
1341 return_val = gdk_window_lookup (child);
1355 gdk_window_at_pointer (gint *win_x,
1358 GdkWindowPrivate *private;
1362 Window xwindow_last = 0;
1363 int rootx = -1, rooty = -1;
1367 private = &gdk_root_parent;
1369 xwindow = private->xwindow;
1371 XGrabServer (private->xdisplay);
1374 xwindow_last = xwindow;
1375 XQueryPointer (private->xdisplay,
1382 XUngrabServer (private->xdisplay);
1384 window = gdk_window_lookup (xwindow_last);
1387 *win_x = window ? winx : -1;
1389 *win_y = window ? winy : -1;
1395 gdk_window_get_parent (GdkWindow *window)
1397 g_return_val_if_fail (window != NULL, NULL);
1399 return ((GdkWindowPrivate*) window)->parent;
1403 gdk_window_get_toplevel (GdkWindow *window)
1405 GdkWindowPrivate *private;
1407 g_return_val_if_fail (window != NULL, NULL);
1409 private = (GdkWindowPrivate*) window;
1411 while (private->window_type == GDK_WINDOW_CHILD)
1413 window = ((GdkWindowPrivate*) window)->parent;
1414 private = (GdkWindowPrivate*) window;
1421 gdk_window_get_children (GdkWindow *window)
1423 GdkWindowPrivate *private;
1429 unsigned int nchildren;
1432 g_return_val_if_fail (window != NULL, NULL);
1434 private = (GdkWindowPrivate*) window;
1435 if (private->destroyed)
1438 XQueryTree (private->xdisplay, private->xwindow,
1439 &root, &parent, &xchildren, &nchildren);
1445 for (i = 0; i < nchildren; i++)
1447 child = gdk_window_lookup (xchildren[i]);
1449 children = g_list_prepend (children, child);
1459 gdk_window_get_events (GdkWindow *window)
1461 GdkWindowPrivate *private;
1462 XWindowAttributes attrs;
1463 GdkEventMask event_mask;
1466 g_return_val_if_fail (window != NULL, 0);
1468 private = (GdkWindowPrivate*) window;
1469 if (private->destroyed)
1472 XGetWindowAttributes (gdk_display, private->xwindow,
1476 for (i = 0; i < nevent_masks; i++)
1478 if (attrs.your_event_mask & event_mask_table[i])
1479 event_mask |= 1 << (i + 1);
1486 gdk_window_set_events (GdkWindow *window,
1487 GdkEventMask event_mask)
1489 GdkWindowPrivate *private;
1493 g_return_if_fail (window != NULL);
1495 private = (GdkWindowPrivate*) window;
1496 if (private->destroyed)
1499 xevent_mask = StructureNotifyMask;
1500 for (i = 0; i < nevent_masks; i++)
1502 if (event_mask & (1 << (i + 1)))
1503 xevent_mask |= event_mask_table[i];
1506 XSelectInput (gdk_display, private->xwindow,
1511 gdk_window_add_colormap_windows (GdkWindow *window)
1513 GdkWindow *toplevel;
1514 GdkWindowPrivate *toplevel_private;
1515 GdkWindowPrivate *window_private;
1516 Window *old_windows;
1517 Window *new_windows;
1520 g_return_if_fail (window != NULL);
1522 toplevel = gdk_window_get_toplevel (window);
1523 toplevel_private = (GdkWindowPrivate*) toplevel;
1524 window_private = (GdkWindowPrivate*) window;
1525 if (window_private->destroyed)
1528 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1529 toplevel_private->xwindow,
1530 &old_windows, &count))
1536 for (i = 0; i < count; i++)
1537 if (old_windows[i] == window_private->xwindow)
1540 new_windows = g_new (Window, count + 1);
1542 for (i = 0; i < count; i++)
1543 new_windows[i] = old_windows[i];
1544 new_windows[count] = window_private->xwindow;
1546 XSetWMColormapWindows (toplevel_private->xdisplay,
1547 toplevel_private->xwindow,
1548 new_windows, count + 1);
1550 g_free (new_windows);
1552 XFree (old_windows);
1556 * This needs the X11 shape extension.
1557 * If not available, shaped windows will look
1558 * ugly, but programs still work. Stefan Wille
1561 gdk_window_shape_combine_mask (GdkWindow *window,
1565 enum { UNKNOWN, NO, YES };
1567 static gint have_shape = UNKNOWN;
1569 GdkWindowPrivate *window_private;
1572 g_return_if_fail (window != NULL);
1574 #ifdef HAVE_SHAPE_EXT
1575 if (have_shape == UNKNOWN)
1578 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1584 if (have_shape == YES)
1586 window_private = (GdkWindowPrivate*) window;
1587 if (window_private->destroyed)
1592 GdkWindowPrivate *pixmap_private;
1594 pixmap_private = (GdkWindowPrivate*) mask;
1595 pixmap = (Pixmap) pixmap_private->xwindow;
1604 XShapeCombineMask (window_private->xdisplay,
1605 window_private->xwindow,
1611 #endif /* HAVE_SHAPE_EXT */
1615 gdk_dnd_drag_addwindow (GdkWindow *window)
1617 GdkWindowPrivate *window_private;
1619 g_return_if_fail (window != NULL);
1621 window_private = (GdkWindowPrivate *) window;
1622 if (window_private->destroyed)
1625 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1627 gdk_dnd.drag_numwindows++;
1628 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1629 gdk_dnd.drag_numwindows
1630 * sizeof(GdkWindow *));
1631 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1632 window_private->dnd_drag_accepted = 0;
1635 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1639 gdk_window_dnd_drag_set (GdkWindow *window,
1644 GdkWindowPrivate *window_private;
1647 g_return_if_fail (window != NULL);
1648 window_private = (GdkWindowPrivate *) window;
1649 if (window_private->destroyed)
1652 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1656 g_return_if_fail(typelist != NULL);
1658 if (window_private->dnd_drag_data_numtypesavail > 3)
1660 window_private->dnd_drag_data_numtypesavail = numtypes;
1662 window_private->dnd_drag_data_typesavail =
1663 g_realloc (window_private->dnd_drag_data_typesavail,
1664 (numtypes + 1) * sizeof (GdkAtom));
1666 for (i = 0; i < numtypes; i++)
1668 /* Allow blanket use of ALL to get anything... */
1669 if (strcmp (typelist[i], "ALL"))
1670 window_private->dnd_drag_data_typesavail[i] =
1671 gdk_atom_intern (typelist[i], FALSE);
1673 window_private->dnd_drag_data_typesavail[i] = None;
1677 * set our extended type list if we need to
1680 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1681 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1682 (guchar *)(window_private->dnd_drag_data_typesavail
1683 + (sizeof(GdkAtom) * 3)),
1684 (numtypes - 3) * sizeof(GdkAtom));
1686 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1690 g_free (window_private->dnd_drag_data_typesavail);
1691 window_private->dnd_drag_data_typesavail = NULL;
1692 window_private->dnd_drag_data_numtypesavail = 0;
1697 gdk_window_dnd_drop_set (GdkWindow *window,
1701 guint8 destructive_op)
1703 GdkWindowPrivate *window_private;
1706 g_return_if_fail (window != NULL);
1707 window_private = (GdkWindowPrivate *) window;
1708 if (window_private->destroyed)
1711 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1714 g_return_if_fail(typelist != NULL);
1716 window_private->dnd_drop_data_numtypesavail = numtypes;
1718 window_private->dnd_drop_data_typesavail =
1719 g_realloc (window_private->dnd_drop_data_typesavail,
1720 (numtypes + 1) * sizeof (GdkAtom));
1722 for (i = 0; i < numtypes; i++)
1723 window_private->dnd_drop_data_typesavail[i] =
1724 gdk_atom_intern (typelist[i], FALSE);
1726 window_private->dnd_drop_destructive_op = destructive_op;
1731 * This is used to reply to a GDK_DRAG_REQUEST event
1732 * (which may be generated by XdeRequest or a confirmed drop...
1735 gdk_window_dnd_data_set (GdkWindow *window,
1738 gulong data_numbytes)
1740 GdkWindowPrivate *window_private;
1742 GdkEventDropDataAvailable tmp_ev;
1745 g_return_if_fail (window != NULL);
1746 g_return_if_fail (event != NULL);
1747 g_return_if_fail (data != NULL);
1748 g_return_if_fail (data_numbytes > 0);
1749 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1751 window_private = (GdkWindowPrivate *) window;
1752 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1753 if (window_private->destroyed)
1756 /* We set the property on our window... */
1757 gdk_property_change (window, window_private->dnd_drag_data_type,
1758 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1760 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1762 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1767 * Then we send the event to tell the receiving window that the
1770 tmp_ev.u.allflags = 0;
1771 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1772 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1774 sev.xclient.type = ClientMessage;
1775 sev.xclient.format = 32;
1776 sev.xclient.window = event->dragrequest.requestor;
1777 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1778 sev.xclient.data.l[0] = window_private->xwindow;
1779 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1780 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1782 if (event->dragrequest.isdrop)
1783 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1784 (event->dragrequest.drop_coords.y << 16);
1786 sev.xclient.data.l[3] = 0;
1788 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1790 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1791 StructureNotifyMask, &sev))
1792 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1793 event->dragrequest.requestor));
1798 gdk_window_add_filter (GdkWindow *window,
1799 GdkFilterFunc function,
1802 GdkWindowPrivate *private;
1804 GdkEventFilter *filter;
1806 private = (GdkWindowPrivate*) window;
1807 if (private && private->destroyed)
1811 tmp_list = private->filters;
1813 tmp_list = gdk_default_filters;
1817 filter = (GdkEventFilter *)tmp_list->data;
1818 if ((filter->function == function) && (filter->data == data))
1820 tmp_list = tmp_list->next;
1823 filter = g_new (GdkEventFilter, 1);
1824 filter->function = function;
1825 filter->data = data;
1828 private->filters = g_list_append (private->filters, filter);
1830 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1834 gdk_window_remove_filter (GdkWindow *window,
1835 GdkFilterFunc function,
1838 GdkWindowPrivate *private;
1840 GdkEventFilter *filter;
1842 private = (GdkWindowPrivate*) window;
1845 tmp_list = private->filters;
1847 tmp_list = gdk_default_filters;
1851 filter = (GdkEventFilter *)tmp_list->data;
1852 tmp_list = tmp_list->next;
1854 if ((filter->function == function) && (filter->data == data))
1857 private->filters = g_list_remove_link (private->filters, tmp_list);
1859 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1860 g_list_free_1 (tmp_list);
1869 gdk_window_set_override_redirect(GdkWindow *window,
1870 gboolean override_redirect)
1872 GdkWindowPrivate *private;
1873 XSetWindowAttributes attr;
1875 g_return_if_fail (window != NULL);
1876 private = (GdkWindowPrivate*) window;
1877 if (private->destroyed)
1880 attr.override_redirect = (override_redirect == FALSE)?False:True;
1881 XChangeWindowAttributes(gdk_display,
1882 ((GdkWindowPrivate *)window)->xwindow,
1888 gdk_window_set_icon (GdkWindow *window,
1889 GdkWindow *icon_window,
1894 GdkWindowPrivate *window_private;
1895 GdkWindowPrivate *private;
1897 g_return_if_fail (window != NULL);
1898 window_private = (GdkWindowPrivate*) window;
1899 if (window_private->destroyed)
1904 if (icon_window != NULL)
1906 private = (GdkWindowPrivate *)icon_window;
1907 wm_hints.flags |= IconWindowHint;
1908 wm_hints.icon_window = private->xwindow;
1913 private = (GdkWindowPrivate *)pixmap;
1914 wm_hints.flags |= IconPixmapHint;
1915 wm_hints.icon_pixmap = private->xwindow;
1920 private = (GdkWindowPrivate *)mask;
1921 wm_hints.flags |= IconMaskHint;
1922 wm_hints.icon_mask = private->xwindow;
1925 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1929 gdk_window_set_icon_name (GdkWindow *window,
1932 GdkWindowPrivate *window_private;
1933 XTextProperty property;
1936 g_return_if_fail (window != NULL);
1937 window_private = (GdkWindowPrivate*) window;
1938 if (window_private->destroyed)
1940 res = XmbTextListToTextProperty (window_private->xdisplay,
1941 &name, 1, XStdICCTextStyle,
1945 g_warning("Error converting icon name to text property: %d\n", res);
1949 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1952 XFree(property.value);
1956 gdk_window_set_group (GdkWindow *window,
1960 GdkWindowPrivate *window_private;
1961 GdkWindowPrivate *private;
1963 g_return_if_fail (window != NULL);
1964 g_return_if_fail (leader != NULL);
1965 window_private = (GdkWindowPrivate*) window;
1966 if (window_private->destroyed)
1969 private = (GdkWindowPrivate *)leader;
1970 wm_hints.flags = WindowGroupHint;
1971 wm_hints.window_group = private->xwindow;
1973 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1977 gdk_window_set_mwm_hints (GdkWindow *window,
1978 MotifWmHints *new_hints)
1980 static Atom hints_atom = None;
1981 MotifWmHints *hints;
1987 GdkWindowPrivate *window_private;
1989 g_return_if_fail (window != NULL);
1990 window_private = (GdkWindowPrivate*) window;
1991 if (window_private->destroyed)
1995 hints_atom = XInternAtom (window_private->xdisplay,
1996 _XA_MOTIF_WM_HINTS, FALSE);
1998 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1999 hints_atom, 0, sizeof(MotifWmHints)/4,
2000 False, AnyPropertyType, &type, &format, &nitems,
2001 &bytes_after, (guchar **)&hints);
2007 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2009 hints->flags |= MWM_HINTS_FUNCTIONS;
2010 hints->functions = new_hints->functions;
2012 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2014 hints->flags |= MWM_HINTS_DECORATIONS;
2015 hints->decorations = new_hints->decorations;
2019 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2020 hints_atom, hints_atom, 32, PropModeReplace,
2021 (guchar *)hints, sizeof(MotifWmHints)/4);
2023 if (hints != new_hints)
2028 gdk_window_set_decorations (GdkWindow *window,
2029 GdkWMDecoration decorations)
2033 hints.flags = MWM_HINTS_DECORATIONS;
2034 hints.decorations = decorations;
2036 gdk_window_set_mwm_hints (window, &hints);
2040 gdk_window_set_functions (GdkWindow *window,
2041 GdkWMFunction functions)
2045 hints.flags = MWM_HINTS_FUNCTIONS;
2046 hints.functions = functions;
2048 gdk_window_set_mwm_hints (window, &hints);
2052 gdk_window_get_toplevels (void)
2054 GList *new_list = NULL;
2057 tmp_list = gdk_root_parent.children;
2060 new_list = g_list_prepend (new_list, tmp_list->data);
2061 tmp_list = tmp_list->next;