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);
481 private->parent = gdk_xid_table_lookup (parent);
483 parent_private = (GdkWindowPrivate *)private->parent;
486 parent_private->children = g_list_prepend (parent_private->children, window);
488 private->xwindow = anid;
489 private->xdisplay = gdk_display;
490 private->x = attrs.x;
491 private->y = attrs.y;
492 private->width = attrs.width;
493 private->height = attrs.height;
494 private->resize_count = 0;
495 private->ref_count = 1;
496 private->window_type = GDK_WINDOW_FOREIGN;
497 private->destroyed = FALSE;
498 private->extension_events = 0;
500 private->colormap = NULL;
502 private->dnd_drag_data_type = None;
503 private->dnd_drag_data_typesavail =
504 private->dnd_drop_data_typesavail = NULL;
505 private->dnd_drop_enabled = private->dnd_drag_enabled =
506 private->dnd_drag_accepted = private->dnd_drag_datashow =
507 private->dnd_drop_data_numtypesavail =
508 private->dnd_drag_data_numtypesavail = 0;
509 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
511 private->filters = NULL;
512 private->children = NULL;
514 window->user_data = NULL;
516 gdk_window_ref (window);
517 gdk_xid_table_insert (&private->xwindow, window);
522 /* Call this function when you want a window and all its children to
523 disappear. When xdestroy is true, a request to destroy the XWindow
524 is sent out. When it is false, it is assumed that the XWindow has
525 been or will be destroyed by destroying some ancestor of this
529 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
530 gboolean our_destroy)
532 GdkWindowPrivate *private;
533 GdkWindowPrivate *temp_private;
534 GdkWindow *temp_window;
538 g_return_if_fail (window != NULL);
540 private = (GdkWindowPrivate*) window;
542 switch (private->window_type)
544 case GDK_WINDOW_TOPLEVEL:
545 case GDK_WINDOW_CHILD:
546 case GDK_WINDOW_DIALOG:
547 case GDK_WINDOW_TEMP:
548 case GDK_WINDOW_FOREIGN:
549 if (!private->destroyed)
553 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
554 if (parent_private->children)
555 parent_private->children = g_list_remove (parent_private->children, window);
558 if (private->window_type != GDK_WINDOW_FOREIGN)
560 children = tmp = private->children;
561 private->children = NULL;
565 temp_window = tmp->data;
568 temp_private = (GdkWindowPrivate*) temp_window;
570 gdk_window_internal_destroy (temp_window, FALSE,
574 g_list_free (children);
577 if (private->extension_events != 0)
578 gdk_input_window_destroy (window);
580 if(private->dnd_drag_data_numtypesavail > 0)
582 g_free (private->dnd_drag_data_typesavail);
583 private->dnd_drag_data_typesavail = NULL;
585 if(private->dnd_drop_data_numtypesavail > 0)
587 g_free (private->dnd_drop_data_typesavail);
588 private->dnd_drop_data_typesavail = NULL;
591 if (private->filters)
593 tmp = private->filters;
601 g_list_free (private->filters);
602 private->filters = NULL;
605 if (private->window_type == GDK_WINDOW_FOREIGN)
607 if (our_destroy && (private->parent != NULL))
609 /* It's somebody elses window, but in our heirarchy,
610 * so reparent it to the root window, and then send
611 * it a delete event, as if we were a WM
613 XClientMessageEvent xevent;
615 gdk_window_hide (window);
616 gdk_window_reparent (window, NULL, 0, 0);
618 xevent.type = ClientMessage;
619 xevent.window = private->xwindow;
620 xevent.message_type = gdk_wm_protocols;
622 xevent.data.l[0] = gdk_wm_delete_window;
623 xevent.data.l[1] = CurrentTime;
625 XSendEvent (private->xdisplay, private->xwindow,
626 False, 0, (XEvent *)&xevent);
630 XDestroyWindow (private->xdisplay, private->xwindow);
632 if (private->colormap)
633 gdk_colormap_unref (private->colormap);
635 private->destroyed = TRUE;
639 case GDK_WINDOW_ROOT:
640 g_error ("attempted to destroy root window");
643 case GDK_WINDOW_PIXMAP:
644 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
649 /* Like internal_destroy, but also destroys the reference created by
653 gdk_window_destroy (GdkWindow *window)
655 gdk_window_internal_destroy (window, TRUE, TRUE);
656 gdk_window_unref (window);
659 /* This function is called when the XWindow is really gone. */
662 gdk_window_destroy_notify (GdkWindow *window)
664 GdkWindowPrivate *private;
666 g_return_if_fail (window != NULL);
668 private = (GdkWindowPrivate*) window;
670 if (!private->destroyed)
672 if (private->window_type == GDK_WINDOW_FOREIGN)
673 gdk_window_internal_destroy (window, FALSE, FALSE);
675 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
678 gdk_xid_table_remove (private->xwindow);
679 gdk_window_unref (window);
683 gdk_window_ref (GdkWindow *window)
685 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
686 g_return_val_if_fail (window != NULL, NULL);
688 private->ref_count += 1;
693 gdk_window_unref (GdkWindow *window)
695 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
696 g_return_if_fail (window != NULL);
698 private->ref_count -= 1;
699 if (private->ref_count == 0)
701 if (!private->destroyed)
702 g_warning ("losing last reference to undestroyed window\n");
708 gdk_window_show (GdkWindow *window)
710 GdkWindowPrivate *private;
712 g_return_if_fail (window != NULL);
714 private = (GdkWindowPrivate*) window;
715 if (!private->destroyed)
717 XRaiseWindow (private->xdisplay, private->xwindow);
718 XMapWindow (private->xdisplay, private->xwindow);
723 gdk_window_hide (GdkWindow *window)
725 GdkWindowPrivate *private;
727 g_return_if_fail (window != NULL);
729 private = (GdkWindowPrivate*) window;
730 if (!private->destroyed)
731 XUnmapWindow (private->xdisplay, private->xwindow);
735 gdk_window_withdraw (GdkWindow *window)
737 GdkWindowPrivate *private;
739 g_return_if_fail (window != NULL);
741 private = (GdkWindowPrivate*) window;
742 if (!private->destroyed)
743 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
747 gdk_window_move (GdkWindow *window,
751 GdkWindowPrivate *private;
753 g_return_if_fail (window != NULL);
755 private = (GdkWindowPrivate*) window;
756 if (!private->destroyed)
758 XMoveWindow (private->xdisplay, private->xwindow, x, y);
760 if (private->window_type == GDK_WINDOW_CHILD)
769 gdk_window_resize (GdkWindow *window,
773 GdkWindowPrivate *private;
775 g_return_if_fail (window != NULL);
782 private = (GdkWindowPrivate*) window;
784 if (!private->destroyed &&
785 ((private->resize_count > 0) ||
786 (private->width != (guint16) width) ||
787 (private->height != (guint16) height)))
789 XResizeWindow (private->xdisplay, private->xwindow, width, height);
790 private->resize_count += 1;
792 if (private->window_type == GDK_WINDOW_CHILD)
794 private->width = width;
795 private->height = height;
801 gdk_window_move_resize (GdkWindow *window,
807 GdkWindowPrivate *private;
809 g_return_if_fail (window != NULL);
816 private = (GdkWindowPrivate*) window;
817 if (!private->destroyed)
819 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
821 if (private->window_type == GDK_WINDOW_CHILD)
825 private->width = width;
826 private->height = height;
832 gdk_window_reparent (GdkWindow *window,
833 GdkWindow *new_parent,
837 GdkWindowPrivate *window_private;
838 GdkWindowPrivate *parent_private;
839 GdkWindowPrivate *old_parent_private;
841 g_return_if_fail (window != NULL);
844 new_parent = (GdkWindow*) &gdk_root_parent;
846 window_private = (GdkWindowPrivate*) window;
847 old_parent_private = (GdkWindowPrivate*)window_private->parent;
848 parent_private = (GdkWindowPrivate*) new_parent;
850 if (!window_private->destroyed && !parent_private->destroyed)
851 XReparentWindow (window_private->xdisplay,
852 window_private->xwindow,
853 parent_private->xwindow,
856 old_parent_private->children = g_list_remove (old_parent_private->children, window);
857 parent_private->children = g_list_prepend (parent_private->children, window);
862 gdk_window_clear (GdkWindow *window)
864 GdkWindowPrivate *private;
866 g_return_if_fail (window != NULL);
868 private = (GdkWindowPrivate*) window;
870 if (!private->destroyed)
871 XClearWindow (private->xdisplay, private->xwindow);
875 gdk_window_clear_area (GdkWindow *window,
881 GdkWindowPrivate *private;
883 g_return_if_fail (window != NULL);
885 private = (GdkWindowPrivate*) window;
887 if (!private->destroyed)
888 XClearArea (private->xdisplay, private->xwindow,
889 x, y, width, height, False);
893 gdk_window_clear_area_e (GdkWindow *window,
899 GdkWindowPrivate *private;
901 g_return_if_fail (window != NULL);
903 private = (GdkWindowPrivate*) window;
905 if (!private->destroyed)
906 XClearArea (private->xdisplay, private->xwindow,
907 x, y, width, height, True);
911 gdk_window_copy_area (GdkWindow *window,
915 GdkWindow *source_window,
921 GdkWindowPrivate *src_private;
922 GdkWindowPrivate *dest_private;
923 GdkGCPrivate *gc_private;
925 g_return_if_fail (window != NULL);
926 g_return_if_fail (gc != NULL);
928 if (source_window == NULL)
929 source_window = window;
931 src_private = (GdkWindowPrivate*) source_window;
932 dest_private = (GdkWindowPrivate*) window;
933 gc_private = (GdkGCPrivate*) gc;
935 if (!src_private->destroyed && !dest_private->destroyed)
937 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
946 gdk_window_raise (GdkWindow *window)
948 GdkWindowPrivate *private;
950 g_return_if_fail (window != NULL);
952 private = (GdkWindowPrivate*) window;
954 if (!private->destroyed)
955 XRaiseWindow (private->xdisplay, private->xwindow);
959 gdk_window_lower (GdkWindow *window)
961 GdkWindowPrivate *private;
963 g_return_if_fail (window != NULL);
965 private = (GdkWindowPrivate*) window;
967 if (!private->destroyed)
968 XLowerWindow (private->xdisplay, private->xwindow);
972 gdk_window_set_user_data (GdkWindow *window,
975 g_return_if_fail (window != NULL);
977 window->user_data = user_data;
981 gdk_window_set_hints (GdkWindow *window,
990 GdkWindowPrivate *private;
991 XSizeHints size_hints;
993 g_return_if_fail (window != NULL);
995 private = (GdkWindowPrivate*) window;
996 if (private->destroyed)
999 size_hints.flags = 0;
1001 if (flags & GDK_HINT_POS)
1003 size_hints.flags |= PPosition;
1008 if (flags & GDK_HINT_MIN_SIZE)
1010 size_hints.flags |= PMinSize;
1011 size_hints.min_width = min_width;
1012 size_hints.min_height = min_height;
1015 if (flags & GDK_HINT_MAX_SIZE)
1017 size_hints.flags |= PMaxSize;
1018 size_hints.max_width = max_width;
1019 size_hints.max_height = max_height;
1023 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1027 gdk_window_set_title (GdkWindow *window,
1030 GdkWindowPrivate *private;
1032 g_return_if_fail (window != NULL);
1034 private = (GdkWindowPrivate*) window;
1035 if (!private->destroyed)
1036 XmbSetWMProperties (private->xdisplay, private->xwindow,
1037 title, title, NULL, 0, NULL, NULL, NULL);
1041 gdk_window_set_background (GdkWindow *window,
1044 GdkWindowPrivate *private;
1046 g_return_if_fail (window != NULL);
1048 private = (GdkWindowPrivate*) window;
1049 if (!private->destroyed)
1050 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1054 gdk_window_set_back_pixmap (GdkWindow *window,
1056 gint parent_relative)
1058 GdkWindowPrivate *window_private;
1059 GdkPixmapPrivate *pixmap_private;
1062 g_return_if_fail (window != NULL);
1064 window_private = (GdkWindowPrivate*) window;
1065 pixmap_private = (GdkPixmapPrivate*) pixmap;
1068 xpixmap = pixmap_private->xwindow;
1072 if (parent_relative)
1073 xpixmap = ParentRelative;
1075 if (!window_private->destroyed)
1076 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1080 gdk_window_set_cursor (GdkWindow *window,
1083 GdkWindowPrivate *window_private;
1084 GdkCursorPrivate *cursor_private;
1087 g_return_if_fail (window != NULL);
1089 window_private = (GdkWindowPrivate*) window;
1090 cursor_private = (GdkCursorPrivate*) cursor;
1095 xcursor = cursor_private->xcursor;
1097 if (!window_private->destroyed)
1098 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1102 gdk_window_set_colormap (GdkWindow *window,
1103 GdkColormap *colormap)
1105 GdkWindowPrivate *window_private;
1106 GdkColormapPrivate *colormap_private;
1108 g_return_if_fail (window != NULL);
1109 g_return_if_fail (colormap != NULL);
1111 window_private = (GdkWindowPrivate*) window;
1112 colormap_private = (GdkColormapPrivate*) colormap;
1114 if (!window_private->destroyed)
1116 XSetWindowColormap (window_private->xdisplay,
1117 window_private->xwindow,
1118 colormap_private->xcolormap);
1120 if (window_private->colormap)
1121 gdk_colormap_unref (window_private->colormap);
1122 window_private->colormap = colormap;
1123 gdk_colormap_ref (window_private->colormap);
1125 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1126 gdk_window_add_colormap_windows (window);
1131 gdk_window_get_user_data (GdkWindow *window,
1134 g_return_if_fail (window != NULL);
1136 *data = window->user_data;
1140 gdk_window_get_geometry (GdkWindow *window,
1147 GdkWindowPrivate *window_private;
1153 guint tborder_width;
1157 window = (GdkWindow*) &gdk_root_parent;
1159 window_private = (GdkWindowPrivate*) window;
1161 if (!window_private->destroyed)
1163 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1164 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1180 gdk_window_get_position (GdkWindow *window,
1184 GdkWindowPrivate *window_private;
1186 g_return_if_fail (window != NULL);
1188 window_private = (GdkWindowPrivate*) window;
1191 *x = window_private->x;
1193 *y = window_private->y;
1197 gdk_window_get_size (GdkWindow *window,
1201 GdkWindowPrivate *window_private;
1203 g_return_if_fail (window != NULL);
1205 window_private = (GdkWindowPrivate*) window;
1208 *width = window_private->width;
1210 *height = window_private->height;
1214 gdk_window_get_visual (GdkWindow *window)
1216 GdkWindowPrivate *window_private;
1217 XWindowAttributes window_attributes;
1219 g_return_val_if_fail (window != NULL, NULL);
1221 window_private = (GdkWindowPrivate*) window;
1222 /* Huh? ->parent is never set for a pixmap. We should just return
1225 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1226 window_private = (GdkWindowPrivate*) window_private->parent;
1228 if (window_private && !window_private->destroyed)
1230 if (window_private->colormap == NULL)
1232 XGetWindowAttributes (window_private->xdisplay,
1233 window_private->xwindow,
1234 &window_attributes);
1235 return gdk_visual_lookup (window_attributes.visual);
1238 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1245 gdk_window_get_colormap (GdkWindow *window)
1247 GdkWindowPrivate *window_private;
1248 XWindowAttributes window_attributes;
1250 g_return_val_if_fail (window != NULL, NULL);
1251 window_private = (GdkWindowPrivate*) window;
1253 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1254 if (!window_private->destroyed)
1256 if (window_private->colormap == NULL)
1258 XGetWindowAttributes (window_private->xdisplay,
1259 window_private->xwindow,
1260 &window_attributes);
1261 return gdk_colormap_lookup (window_attributes.colormap);
1264 return window_private->colormap;
1271 gdk_window_get_type (GdkWindow *window)
1273 GdkWindowPrivate *window_private;
1275 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1277 window_private = (GdkWindowPrivate*) window;
1278 return window_private->window_type;
1282 gdk_window_get_origin (GdkWindow *window,
1286 GdkWindowPrivate *private;
1292 g_return_val_if_fail (window != NULL, 0);
1294 private = (GdkWindowPrivate*) window;
1296 if (!private->destroyed)
1298 return_val = XTranslateCoordinates (private->xdisplay,
1317 gdk_window_get_pointer (GdkWindow *window,
1320 GdkModifierType *mask)
1322 GdkWindowPrivate *private;
1323 GdkWindow *return_val;
1329 unsigned int xmask = 0;
1332 window = (GdkWindow*) &gdk_root_parent;
1334 private = (GdkWindowPrivate*) window;
1337 if (!private->destroyed &&
1338 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1339 &rootx, &rooty, &winx, &winy, &xmask))
1342 return_val = gdk_window_lookup (child);
1356 gdk_window_at_pointer (gint *win_x,
1359 GdkWindowPrivate *private;
1363 Window xwindow_last = 0;
1364 int rootx = -1, rooty = -1;
1368 private = &gdk_root_parent;
1370 xwindow = private->xwindow;
1372 XGrabServer (private->xdisplay);
1375 xwindow_last = xwindow;
1376 XQueryPointer (private->xdisplay,
1383 XUngrabServer (private->xdisplay);
1385 window = gdk_window_lookup (xwindow_last);
1388 *win_x = window ? winx : -1;
1390 *win_y = window ? winy : -1;
1396 gdk_window_get_parent (GdkWindow *window)
1398 g_return_val_if_fail (window != NULL, NULL);
1400 return ((GdkWindowPrivate*) window)->parent;
1404 gdk_window_get_toplevel (GdkWindow *window)
1406 GdkWindowPrivate *private;
1408 g_return_val_if_fail (window != NULL, NULL);
1410 private = (GdkWindowPrivate*) window;
1412 while (private->window_type == GDK_WINDOW_CHILD)
1414 window = ((GdkWindowPrivate*) window)->parent;
1415 private = (GdkWindowPrivate*) window;
1422 gdk_window_get_children (GdkWindow *window)
1424 GdkWindowPrivate *private;
1430 unsigned int nchildren;
1433 g_return_val_if_fail (window != NULL, NULL);
1435 private = (GdkWindowPrivate*) window;
1436 if (private->destroyed)
1439 XQueryTree (private->xdisplay, private->xwindow,
1440 &root, &parent, &xchildren, &nchildren);
1446 for (i = 0; i < nchildren; i++)
1448 child = gdk_window_lookup (xchildren[i]);
1450 children = g_list_prepend (children, child);
1461 gdk_window_get_events (GdkWindow *window)
1463 GdkWindowPrivate *private;
1464 XWindowAttributes attrs;
1465 GdkEventMask event_mask;
1468 g_return_val_if_fail (window != NULL, 0);
1470 private = (GdkWindowPrivate*) window;
1471 if (private->destroyed)
1474 XGetWindowAttributes (gdk_display, private->xwindow,
1478 for (i = 0; i < nevent_masks; i++)
1480 if (attrs.your_event_mask & event_mask_table[i])
1481 event_mask |= 1 << (i + 1);
1488 gdk_window_set_events (GdkWindow *window,
1489 GdkEventMask event_mask)
1491 GdkWindowPrivate *private;
1495 g_return_if_fail (window != NULL);
1497 private = (GdkWindowPrivate*) window;
1498 if (private->destroyed)
1501 xevent_mask = StructureNotifyMask;
1502 for (i = 0; i < nevent_masks; i++)
1504 if (event_mask & (1 << (i + 1)))
1505 xevent_mask |= event_mask_table[i];
1508 XSelectInput (gdk_display, private->xwindow,
1513 gdk_window_add_colormap_windows (GdkWindow *window)
1515 GdkWindow *toplevel;
1516 GdkWindowPrivate *toplevel_private;
1517 GdkWindowPrivate *window_private;
1518 Window *old_windows;
1519 Window *new_windows;
1522 g_return_if_fail (window != NULL);
1524 toplevel = gdk_window_get_toplevel (window);
1525 toplevel_private = (GdkWindowPrivate*) toplevel;
1526 window_private = (GdkWindowPrivate*) window;
1527 if (window_private->destroyed)
1531 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1532 toplevel_private->xwindow,
1533 &old_windows, &count))
1538 for (i = 0; i < count; i++)
1539 if (old_windows[i] == window_private->xwindow)
1541 XFree (old_windows);
1545 new_windows = g_new (Window, count + 1);
1547 for (i = 0; i < count; i++)
1548 new_windows[i] = old_windows[i];
1549 new_windows[count] = window_private->xwindow;
1551 XSetWMColormapWindows (toplevel_private->xdisplay,
1552 toplevel_private->xwindow,
1553 new_windows, count + 1);
1555 g_free (new_windows);
1557 XFree (old_windows);
1561 * This needs the X11 shape extension.
1562 * If not available, shaped windows will look
1563 * ugly, but programs still work. Stefan Wille
1566 gdk_window_shape_combine_mask (GdkWindow *window,
1570 enum { UNKNOWN, NO, YES };
1572 static gint have_shape = UNKNOWN;
1574 GdkWindowPrivate *window_private;
1577 g_return_if_fail (window != NULL);
1579 #ifdef HAVE_SHAPE_EXT
1580 if (have_shape == UNKNOWN)
1583 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1589 if (have_shape == YES)
1591 window_private = (GdkWindowPrivate*) window;
1592 if (window_private->destroyed)
1597 GdkWindowPrivate *pixmap_private;
1599 pixmap_private = (GdkWindowPrivate*) mask;
1600 pixmap = (Pixmap) pixmap_private->xwindow;
1609 XShapeCombineMask (window_private->xdisplay,
1610 window_private->xwindow,
1616 #endif /* HAVE_SHAPE_EXT */
1620 gdk_dnd_drag_addwindow (GdkWindow *window)
1622 GdkWindowPrivate *window_private;
1624 g_return_if_fail (window != NULL);
1626 window_private = (GdkWindowPrivate *) window;
1627 if (window_private->destroyed)
1630 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1632 gdk_dnd.drag_numwindows++;
1633 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1634 gdk_dnd.drag_numwindows
1635 * sizeof(GdkWindow *));
1636 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1637 window_private->dnd_drag_accepted = 0;
1640 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1644 gdk_window_dnd_drag_set (GdkWindow *window,
1649 GdkWindowPrivate *window_private;
1652 g_return_if_fail (window != NULL);
1653 window_private = (GdkWindowPrivate *) window;
1654 if (window_private->destroyed)
1657 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1661 g_return_if_fail(typelist != NULL);
1663 if (window_private->dnd_drag_data_numtypesavail > 3)
1665 window_private->dnd_drag_data_numtypesavail = numtypes;
1667 window_private->dnd_drag_data_typesavail =
1668 g_realloc (window_private->dnd_drag_data_typesavail,
1669 (numtypes + 1) * sizeof (GdkAtom));
1671 for (i = 0; i < numtypes; i++)
1673 /* Allow blanket use of ALL to get anything... */
1674 if (strcmp (typelist[i], "ALL"))
1675 window_private->dnd_drag_data_typesavail[i] =
1676 gdk_atom_intern (typelist[i], FALSE);
1678 window_private->dnd_drag_data_typesavail[i] = None;
1682 * set our extended type list if we need to
1685 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1686 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1687 (guchar *)(window_private->dnd_drag_data_typesavail
1688 + (sizeof(GdkAtom) * 3)),
1689 (numtypes - 3) * sizeof(GdkAtom));
1691 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1695 g_free (window_private->dnd_drag_data_typesavail);
1696 window_private->dnd_drag_data_typesavail = NULL;
1697 window_private->dnd_drag_data_numtypesavail = 0;
1702 gdk_window_dnd_drop_set (GdkWindow *window,
1706 guint8 destructive_op)
1708 GdkWindowPrivate *window_private;
1711 g_return_if_fail (window != NULL);
1712 window_private = (GdkWindowPrivate *) window;
1713 if (window_private->destroyed)
1716 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1719 g_return_if_fail(typelist != NULL);
1721 window_private->dnd_drop_data_numtypesavail = numtypes;
1723 window_private->dnd_drop_data_typesavail =
1724 g_realloc (window_private->dnd_drop_data_typesavail,
1725 (numtypes + 1) * sizeof (GdkAtom));
1727 for (i = 0; i < numtypes; i++)
1728 window_private->dnd_drop_data_typesavail[i] =
1729 gdk_atom_intern (typelist[i], FALSE);
1731 window_private->dnd_drop_destructive_op = destructive_op;
1736 * This is used to reply to a GDK_DRAG_REQUEST event
1737 * (which may be generated by XdeRequest or a confirmed drop...
1740 gdk_window_dnd_data_set (GdkWindow *window,
1743 gulong data_numbytes)
1745 GdkWindowPrivate *window_private;
1747 GdkEventDropDataAvailable tmp_ev;
1750 g_return_if_fail (window != NULL);
1751 g_return_if_fail (event != NULL);
1752 g_return_if_fail (data != NULL);
1753 g_return_if_fail (data_numbytes > 0);
1754 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1756 window_private = (GdkWindowPrivate *) window;
1757 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1758 if (window_private->destroyed)
1761 /* We set the property on our window... */
1762 gdk_property_change (window, window_private->dnd_drag_data_type,
1763 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1765 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1767 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1772 * Then we send the event to tell the receiving window that the
1775 tmp_ev.u.allflags = 0;
1776 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1777 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1779 sev.xclient.type = ClientMessage;
1780 sev.xclient.format = 32;
1781 sev.xclient.window = event->dragrequest.requestor;
1782 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1783 sev.xclient.data.l[0] = window_private->xwindow;
1784 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1785 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1787 if (event->dragrequest.isdrop)
1788 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1789 (event->dragrequest.drop_coords.y << 16);
1791 sev.xclient.data.l[3] = 0;
1793 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1795 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1796 StructureNotifyMask, &sev))
1797 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1798 event->dragrequest.requestor));
1803 gdk_window_add_filter (GdkWindow *window,
1804 GdkFilterFunc function,
1807 GdkWindowPrivate *private;
1809 GdkEventFilter *filter;
1811 private = (GdkWindowPrivate*) window;
1812 if (private && private->destroyed)
1816 tmp_list = private->filters;
1818 tmp_list = gdk_default_filters;
1822 filter = (GdkEventFilter *)tmp_list->data;
1823 if ((filter->function == function) && (filter->data == data))
1825 tmp_list = tmp_list->next;
1828 filter = g_new (GdkEventFilter, 1);
1829 filter->function = function;
1830 filter->data = data;
1833 private->filters = g_list_append (private->filters, filter);
1835 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1839 gdk_window_remove_filter (GdkWindow *window,
1840 GdkFilterFunc function,
1843 GdkWindowPrivate *private;
1845 GdkEventFilter *filter;
1847 private = (GdkWindowPrivate*) window;
1850 tmp_list = private->filters;
1852 tmp_list = gdk_default_filters;
1856 filter = (GdkEventFilter *)tmp_list->data;
1857 tmp_list = tmp_list->next;
1859 if ((filter->function == function) && (filter->data == data))
1862 private->filters = g_list_remove_link (private->filters, tmp_list);
1864 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1865 g_list_free_1 (tmp_list);
1874 gdk_window_set_override_redirect(GdkWindow *window,
1875 gboolean override_redirect)
1877 GdkWindowPrivate *private;
1878 XSetWindowAttributes attr;
1880 g_return_if_fail (window != NULL);
1881 private = (GdkWindowPrivate*) window;
1882 if (private->destroyed)
1885 attr.override_redirect = (override_redirect == FALSE)?False:True;
1886 XChangeWindowAttributes(gdk_display,
1887 ((GdkWindowPrivate *)window)->xwindow,
1893 gdk_window_set_icon (GdkWindow *window,
1894 GdkWindow *icon_window,
1899 GdkWindowPrivate *window_private;
1900 GdkWindowPrivate *private;
1902 g_return_if_fail (window != NULL);
1903 window_private = (GdkWindowPrivate*) window;
1904 if (window_private->destroyed)
1909 if (icon_window != NULL)
1911 private = (GdkWindowPrivate *)icon_window;
1912 wm_hints.flags |= IconWindowHint;
1913 wm_hints.icon_window = private->xwindow;
1918 private = (GdkWindowPrivate *)pixmap;
1919 wm_hints.flags |= IconPixmapHint;
1920 wm_hints.icon_pixmap = private->xwindow;
1925 private = (GdkWindowPrivate *)mask;
1926 wm_hints.flags |= IconMaskHint;
1927 wm_hints.icon_mask = private->xwindow;
1930 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1934 gdk_window_set_icon_name (GdkWindow *window,
1937 GdkWindowPrivate *window_private;
1938 XTextProperty property;
1941 g_return_if_fail (window != NULL);
1942 window_private = (GdkWindowPrivate*) window;
1943 if (window_private->destroyed)
1945 res = XmbTextListToTextProperty (window_private->xdisplay,
1946 &name, 1, XStdICCTextStyle,
1950 g_warning("Error converting icon name to text property: %d\n", res);
1954 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1958 XFree (property.value);
1962 gdk_window_set_group (GdkWindow *window,
1966 GdkWindowPrivate *window_private;
1967 GdkWindowPrivate *private;
1969 g_return_if_fail (window != NULL);
1970 g_return_if_fail (leader != NULL);
1971 window_private = (GdkWindowPrivate*) window;
1972 if (window_private->destroyed)
1975 private = (GdkWindowPrivate *)leader;
1976 wm_hints.flags = WindowGroupHint;
1977 wm_hints.window_group = private->xwindow;
1979 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1983 gdk_window_set_mwm_hints (GdkWindow *window,
1984 MotifWmHints *new_hints)
1986 static Atom hints_atom = None;
1987 MotifWmHints *hints;
1993 GdkWindowPrivate *window_private;
1995 g_return_if_fail (window != NULL);
1996 window_private = (GdkWindowPrivate*) window;
1997 if (window_private->destroyed)
2001 hints_atom = XInternAtom (window_private->xdisplay,
2002 _XA_MOTIF_WM_HINTS, FALSE);
2004 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2005 hints_atom, 0, sizeof(MotifWmHints)/4,
2006 False, AnyPropertyType, &type, &format, &nitems,
2007 &bytes_after, (guchar **)&hints);
2013 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2015 hints->flags |= MWM_HINTS_FUNCTIONS;
2016 hints->functions = new_hints->functions;
2018 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2020 hints->flags |= MWM_HINTS_DECORATIONS;
2021 hints->decorations = new_hints->decorations;
2025 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2026 hints_atom, hints_atom, 32, PropModeReplace,
2027 (guchar *)hints, sizeof(MotifWmHints)/4);
2029 if (hints != new_hints)
2034 gdk_window_set_decorations (GdkWindow *window,
2035 GdkWMDecoration decorations)
2039 hints.flags = MWM_HINTS_DECORATIONS;
2040 hints.decorations = decorations;
2042 gdk_window_set_mwm_hints (window, &hints);
2046 gdk_window_set_functions (GdkWindow *window,
2047 GdkWMFunction functions)
2051 hints.flags = MWM_HINTS_FUNCTIONS;
2052 hints.functions = functions;
2054 gdk_window_set_mwm_hints (window, &hints);
2058 gdk_window_get_toplevels (void)
2060 GList *new_list = NULL;
2063 tmp_list = gdk_root_parent.children;
2066 new_list = g_list_prepend (new_list, tmp_list->data);
2067 tmp_list = tmp_list->next;