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 if (old_parent_private)
857 old_parent_private->children = g_list_remove (old_parent_private->children, window);
858 parent_private->children = g_list_prepend (parent_private->children, window);
863 gdk_window_clear (GdkWindow *window)
865 GdkWindowPrivate *private;
867 g_return_if_fail (window != NULL);
869 private = (GdkWindowPrivate*) window;
871 if (!private->destroyed)
872 XClearWindow (private->xdisplay, private->xwindow);
876 gdk_window_clear_area (GdkWindow *window,
882 GdkWindowPrivate *private;
884 g_return_if_fail (window != NULL);
886 private = (GdkWindowPrivate*) window;
888 if (!private->destroyed)
889 XClearArea (private->xdisplay, private->xwindow,
890 x, y, width, height, False);
894 gdk_window_clear_area_e (GdkWindow *window,
900 GdkWindowPrivate *private;
902 g_return_if_fail (window != NULL);
904 private = (GdkWindowPrivate*) window;
906 if (!private->destroyed)
907 XClearArea (private->xdisplay, private->xwindow,
908 x, y, width, height, True);
912 gdk_window_copy_area (GdkWindow *window,
916 GdkWindow *source_window,
922 GdkWindowPrivate *src_private;
923 GdkWindowPrivate *dest_private;
924 GdkGCPrivate *gc_private;
926 g_return_if_fail (window != NULL);
927 g_return_if_fail (gc != NULL);
929 if (source_window == NULL)
930 source_window = window;
932 src_private = (GdkWindowPrivate*) source_window;
933 dest_private = (GdkWindowPrivate*) window;
934 gc_private = (GdkGCPrivate*) gc;
936 if (!src_private->destroyed && !dest_private->destroyed)
938 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
947 gdk_window_raise (GdkWindow *window)
949 GdkWindowPrivate *private;
951 g_return_if_fail (window != NULL);
953 private = (GdkWindowPrivate*) window;
955 if (!private->destroyed)
956 XRaiseWindow (private->xdisplay, private->xwindow);
960 gdk_window_lower (GdkWindow *window)
962 GdkWindowPrivate *private;
964 g_return_if_fail (window != NULL);
966 private = (GdkWindowPrivate*) window;
968 if (!private->destroyed)
969 XLowerWindow (private->xdisplay, private->xwindow);
973 gdk_window_set_user_data (GdkWindow *window,
976 g_return_if_fail (window != NULL);
978 window->user_data = user_data;
982 gdk_window_set_hints (GdkWindow *window,
991 GdkWindowPrivate *private;
992 XSizeHints size_hints;
994 g_return_if_fail (window != NULL);
996 private = (GdkWindowPrivate*) window;
997 if (private->destroyed)
1000 size_hints.flags = 0;
1002 if (flags & GDK_HINT_POS)
1004 size_hints.flags |= PPosition;
1009 if (flags & GDK_HINT_MIN_SIZE)
1011 size_hints.flags |= PMinSize;
1012 size_hints.min_width = min_width;
1013 size_hints.min_height = min_height;
1016 if (flags & GDK_HINT_MAX_SIZE)
1018 size_hints.flags |= PMaxSize;
1019 size_hints.max_width = max_width;
1020 size_hints.max_height = max_height;
1024 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1028 gdk_window_set_title (GdkWindow *window,
1031 GdkWindowPrivate *private;
1033 g_return_if_fail (window != NULL);
1035 private = (GdkWindowPrivate*) window;
1036 if (!private->destroyed)
1037 XmbSetWMProperties (private->xdisplay, private->xwindow,
1038 title, title, NULL, 0, NULL, NULL, NULL);
1042 gdk_window_set_background (GdkWindow *window,
1045 GdkWindowPrivate *private;
1047 g_return_if_fail (window != NULL);
1049 private = (GdkWindowPrivate*) window;
1050 if (!private->destroyed)
1051 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1055 gdk_window_set_back_pixmap (GdkWindow *window,
1057 gint parent_relative)
1059 GdkWindowPrivate *window_private;
1060 GdkPixmapPrivate *pixmap_private;
1063 g_return_if_fail (window != NULL);
1065 window_private = (GdkWindowPrivate*) window;
1066 pixmap_private = (GdkPixmapPrivate*) pixmap;
1069 xpixmap = pixmap_private->xwindow;
1073 if (parent_relative)
1074 xpixmap = ParentRelative;
1076 if (!window_private->destroyed)
1077 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1081 gdk_window_set_cursor (GdkWindow *window,
1084 GdkWindowPrivate *window_private;
1085 GdkCursorPrivate *cursor_private;
1088 g_return_if_fail (window != NULL);
1090 window_private = (GdkWindowPrivate*) window;
1091 cursor_private = (GdkCursorPrivate*) cursor;
1096 xcursor = cursor_private->xcursor;
1098 if (!window_private->destroyed)
1099 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1103 gdk_window_set_colormap (GdkWindow *window,
1104 GdkColormap *colormap)
1106 GdkWindowPrivate *window_private;
1107 GdkColormapPrivate *colormap_private;
1109 g_return_if_fail (window != NULL);
1110 g_return_if_fail (colormap != NULL);
1112 window_private = (GdkWindowPrivate*) window;
1113 colormap_private = (GdkColormapPrivate*) colormap;
1115 if (!window_private->destroyed)
1117 XSetWindowColormap (window_private->xdisplay,
1118 window_private->xwindow,
1119 colormap_private->xcolormap);
1121 if (window_private->colormap)
1122 gdk_colormap_unref (window_private->colormap);
1123 window_private->colormap = colormap;
1124 gdk_colormap_ref (window_private->colormap);
1126 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1127 gdk_window_add_colormap_windows (window);
1132 gdk_window_get_user_data (GdkWindow *window,
1135 g_return_if_fail (window != NULL);
1137 *data = window->user_data;
1141 gdk_window_get_geometry (GdkWindow *window,
1148 GdkWindowPrivate *window_private;
1154 guint tborder_width;
1158 window = (GdkWindow*) &gdk_root_parent;
1160 window_private = (GdkWindowPrivate*) window;
1162 if (!window_private->destroyed)
1164 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1165 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1181 gdk_window_get_position (GdkWindow *window,
1185 GdkWindowPrivate *window_private;
1187 g_return_if_fail (window != NULL);
1189 window_private = (GdkWindowPrivate*) window;
1192 *x = window_private->x;
1194 *y = window_private->y;
1198 gdk_window_get_size (GdkWindow *window,
1202 GdkWindowPrivate *window_private;
1204 g_return_if_fail (window != NULL);
1206 window_private = (GdkWindowPrivate*) window;
1209 *width = window_private->width;
1211 *height = window_private->height;
1215 gdk_window_get_visual (GdkWindow *window)
1217 GdkWindowPrivate *window_private;
1218 XWindowAttributes window_attributes;
1220 g_return_val_if_fail (window != NULL, NULL);
1222 window_private = (GdkWindowPrivate*) window;
1223 /* Huh? ->parent is never set for a pixmap. We should just return
1226 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1227 window_private = (GdkWindowPrivate*) window_private->parent;
1229 if (window_private && !window_private->destroyed)
1231 if (window_private->colormap == NULL)
1233 XGetWindowAttributes (window_private->xdisplay,
1234 window_private->xwindow,
1235 &window_attributes);
1236 return gdk_visual_lookup (window_attributes.visual);
1239 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1246 gdk_window_get_colormap (GdkWindow *window)
1248 GdkWindowPrivate *window_private;
1249 XWindowAttributes window_attributes;
1251 g_return_val_if_fail (window != NULL, NULL);
1252 window_private = (GdkWindowPrivate*) window;
1254 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1255 if (!window_private->destroyed)
1257 if (window_private->colormap == NULL)
1259 XGetWindowAttributes (window_private->xdisplay,
1260 window_private->xwindow,
1261 &window_attributes);
1262 return gdk_colormap_lookup (window_attributes.colormap);
1265 return window_private->colormap;
1272 gdk_window_get_type (GdkWindow *window)
1274 GdkWindowPrivate *window_private;
1276 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1278 window_private = (GdkWindowPrivate*) window;
1279 return window_private->window_type;
1283 gdk_window_get_origin (GdkWindow *window,
1287 GdkWindowPrivate *private;
1293 g_return_val_if_fail (window != NULL, 0);
1295 private = (GdkWindowPrivate*) window;
1297 if (!private->destroyed)
1299 return_val = XTranslateCoordinates (private->xdisplay,
1318 gdk_window_get_pointer (GdkWindow *window,
1321 GdkModifierType *mask)
1323 GdkWindowPrivate *private;
1324 GdkWindow *return_val;
1330 unsigned int xmask = 0;
1333 window = (GdkWindow*) &gdk_root_parent;
1335 private = (GdkWindowPrivate*) window;
1338 if (!private->destroyed &&
1339 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1340 &rootx, &rooty, &winx, &winy, &xmask))
1343 return_val = gdk_window_lookup (child);
1357 gdk_window_at_pointer (gint *win_x,
1360 GdkWindowPrivate *private;
1364 Window xwindow_last = 0;
1365 int rootx = -1, rooty = -1;
1369 private = &gdk_root_parent;
1371 xwindow = private->xwindow;
1373 XGrabServer (private->xdisplay);
1376 xwindow_last = xwindow;
1377 XQueryPointer (private->xdisplay,
1384 XUngrabServer (private->xdisplay);
1386 window = gdk_window_lookup (xwindow_last);
1389 *win_x = window ? winx : -1;
1391 *win_y = window ? winy : -1;
1397 gdk_window_get_parent (GdkWindow *window)
1399 g_return_val_if_fail (window != NULL, NULL);
1401 return ((GdkWindowPrivate*) window)->parent;
1405 gdk_window_get_toplevel (GdkWindow *window)
1407 GdkWindowPrivate *private;
1409 g_return_val_if_fail (window != NULL, NULL);
1411 private = (GdkWindowPrivate*) window;
1413 while (private->window_type == GDK_WINDOW_CHILD)
1415 window = ((GdkWindowPrivate*) window)->parent;
1416 private = (GdkWindowPrivate*) window;
1423 gdk_window_get_children (GdkWindow *window)
1425 GdkWindowPrivate *private;
1431 unsigned int nchildren;
1434 g_return_val_if_fail (window != NULL, NULL);
1436 private = (GdkWindowPrivate*) window;
1437 if (private->destroyed)
1440 XQueryTree (private->xdisplay, private->xwindow,
1441 &root, &parent, &xchildren, &nchildren);
1447 for (i = 0; i < nchildren; i++)
1449 child = gdk_window_lookup (xchildren[i]);
1451 children = g_list_prepend (children, child);
1462 gdk_window_get_events (GdkWindow *window)
1464 GdkWindowPrivate *private;
1465 XWindowAttributes attrs;
1466 GdkEventMask event_mask;
1469 g_return_val_if_fail (window != NULL, 0);
1471 private = (GdkWindowPrivate*) window;
1472 if (private->destroyed)
1475 XGetWindowAttributes (gdk_display, private->xwindow,
1479 for (i = 0; i < nevent_masks; i++)
1481 if (attrs.your_event_mask & event_mask_table[i])
1482 event_mask |= 1 << (i + 1);
1489 gdk_window_set_events (GdkWindow *window,
1490 GdkEventMask event_mask)
1492 GdkWindowPrivate *private;
1496 g_return_if_fail (window != NULL);
1498 private = (GdkWindowPrivate*) window;
1499 if (private->destroyed)
1502 xevent_mask = StructureNotifyMask;
1503 for (i = 0; i < nevent_masks; i++)
1505 if (event_mask & (1 << (i + 1)))
1506 xevent_mask |= event_mask_table[i];
1509 XSelectInput (gdk_display, private->xwindow,
1514 gdk_window_add_colormap_windows (GdkWindow *window)
1516 GdkWindow *toplevel;
1517 GdkWindowPrivate *toplevel_private;
1518 GdkWindowPrivate *window_private;
1519 Window *old_windows;
1520 Window *new_windows;
1523 g_return_if_fail (window != NULL);
1525 toplevel = gdk_window_get_toplevel (window);
1526 toplevel_private = (GdkWindowPrivate*) toplevel;
1527 window_private = (GdkWindowPrivate*) window;
1528 if (window_private->destroyed)
1532 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1533 toplevel_private->xwindow,
1534 &old_windows, &count))
1539 for (i = 0; i < count; i++)
1540 if (old_windows[i] == window_private->xwindow)
1542 XFree (old_windows);
1546 new_windows = g_new (Window, count + 1);
1548 for (i = 0; i < count; i++)
1549 new_windows[i] = old_windows[i];
1550 new_windows[count] = window_private->xwindow;
1552 XSetWMColormapWindows (toplevel_private->xdisplay,
1553 toplevel_private->xwindow,
1554 new_windows, count + 1);
1556 g_free (new_windows);
1558 XFree (old_windows);
1562 * This needs the X11 shape extension.
1563 * If not available, shaped windows will look
1564 * ugly, but programs still work. Stefan Wille
1567 gdk_window_shape_combine_mask (GdkWindow *window,
1571 enum { UNKNOWN, NO, YES };
1573 static gint have_shape = UNKNOWN;
1575 GdkWindowPrivate *window_private;
1578 g_return_if_fail (window != NULL);
1580 #ifdef HAVE_SHAPE_EXT
1581 if (have_shape == UNKNOWN)
1584 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1590 if (have_shape == YES)
1592 window_private = (GdkWindowPrivate*) window;
1593 if (window_private->destroyed)
1598 GdkWindowPrivate *pixmap_private;
1600 pixmap_private = (GdkWindowPrivate*) mask;
1601 pixmap = (Pixmap) pixmap_private->xwindow;
1610 XShapeCombineMask (window_private->xdisplay,
1611 window_private->xwindow,
1617 #endif /* HAVE_SHAPE_EXT */
1621 gdk_dnd_drag_addwindow (GdkWindow *window)
1623 GdkWindowPrivate *window_private;
1625 g_return_if_fail (window != NULL);
1627 window_private = (GdkWindowPrivate *) window;
1628 if (window_private->destroyed)
1631 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1633 gdk_dnd.drag_numwindows++;
1634 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1635 gdk_dnd.drag_numwindows
1636 * sizeof(GdkWindow *));
1637 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1638 window_private->dnd_drag_accepted = 0;
1641 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1645 gdk_window_dnd_drag_set (GdkWindow *window,
1650 GdkWindowPrivate *window_private;
1653 g_return_if_fail (window != NULL);
1654 window_private = (GdkWindowPrivate *) window;
1655 if (window_private->destroyed)
1658 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1662 g_return_if_fail(typelist != NULL);
1664 if (window_private->dnd_drag_data_numtypesavail > 3)
1666 window_private->dnd_drag_data_numtypesavail = numtypes;
1668 window_private->dnd_drag_data_typesavail =
1669 g_realloc (window_private->dnd_drag_data_typesavail,
1670 (numtypes + 1) * sizeof (GdkAtom));
1672 for (i = 0; i < numtypes; i++)
1674 /* Allow blanket use of ALL to get anything... */
1675 if (strcmp (typelist[i], "ALL"))
1676 window_private->dnd_drag_data_typesavail[i] =
1677 gdk_atom_intern (typelist[i], FALSE);
1679 window_private->dnd_drag_data_typesavail[i] = None;
1683 * set our extended type list if we need to
1686 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1687 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1688 (guchar *)(window_private->dnd_drag_data_typesavail
1689 + (sizeof(GdkAtom) * 3)),
1690 (numtypes - 3) * sizeof(GdkAtom));
1692 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1696 g_free (window_private->dnd_drag_data_typesavail);
1697 window_private->dnd_drag_data_typesavail = NULL;
1698 window_private->dnd_drag_data_numtypesavail = 0;
1703 gdk_window_dnd_drop_set (GdkWindow *window,
1707 guint8 destructive_op)
1709 GdkWindowPrivate *window_private;
1712 g_return_if_fail (window != NULL);
1713 window_private = (GdkWindowPrivate *) window;
1714 if (window_private->destroyed)
1717 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1720 g_return_if_fail(typelist != NULL);
1722 window_private->dnd_drop_data_numtypesavail = numtypes;
1724 window_private->dnd_drop_data_typesavail =
1725 g_realloc (window_private->dnd_drop_data_typesavail,
1726 (numtypes + 1) * sizeof (GdkAtom));
1728 for (i = 0; i < numtypes; i++)
1729 window_private->dnd_drop_data_typesavail[i] =
1730 gdk_atom_intern (typelist[i], FALSE);
1732 window_private->dnd_drop_destructive_op = destructive_op;
1737 * This is used to reply to a GDK_DRAG_REQUEST event
1738 * (which may be generated by XdeRequest or a confirmed drop...
1741 gdk_window_dnd_data_set (GdkWindow *window,
1744 gulong data_numbytes)
1746 GdkWindowPrivate *window_private;
1748 GdkEventDropDataAvailable tmp_ev;
1751 g_return_if_fail (window != NULL);
1752 g_return_if_fail (event != NULL);
1753 g_return_if_fail (data != NULL);
1754 g_return_if_fail (data_numbytes > 0);
1755 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1757 window_private = (GdkWindowPrivate *) window;
1758 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1759 if (window_private->destroyed)
1762 /* We set the property on our window... */
1763 gdk_property_change (window, window_private->dnd_drag_data_type,
1764 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1766 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1768 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1773 * Then we send the event to tell the receiving window that the
1776 tmp_ev.u.allflags = 0;
1777 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1778 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1780 sev.xclient.type = ClientMessage;
1781 sev.xclient.format = 32;
1782 sev.xclient.window = event->dragrequest.requestor;
1783 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1784 sev.xclient.data.l[0] = window_private->xwindow;
1785 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1786 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1788 if (event->dragrequest.isdrop)
1789 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1790 (event->dragrequest.drop_coords.y << 16);
1792 sev.xclient.data.l[3] = 0;
1794 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1796 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1797 StructureNotifyMask, &sev))
1798 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1799 event->dragrequest.requestor));
1804 gdk_window_add_filter (GdkWindow *window,
1805 GdkFilterFunc function,
1808 GdkWindowPrivate *private;
1810 GdkEventFilter *filter;
1812 private = (GdkWindowPrivate*) window;
1813 if (private && private->destroyed)
1817 tmp_list = private->filters;
1819 tmp_list = gdk_default_filters;
1823 filter = (GdkEventFilter *)tmp_list->data;
1824 if ((filter->function == function) && (filter->data == data))
1826 tmp_list = tmp_list->next;
1829 filter = g_new (GdkEventFilter, 1);
1830 filter->function = function;
1831 filter->data = data;
1834 private->filters = g_list_append (private->filters, filter);
1836 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1840 gdk_window_remove_filter (GdkWindow *window,
1841 GdkFilterFunc function,
1844 GdkWindowPrivate *private;
1846 GdkEventFilter *filter;
1848 private = (GdkWindowPrivate*) window;
1851 tmp_list = private->filters;
1853 tmp_list = gdk_default_filters;
1857 filter = (GdkEventFilter *)tmp_list->data;
1858 tmp_list = tmp_list->next;
1860 if ((filter->function == function) && (filter->data == data))
1863 private->filters = g_list_remove_link (private->filters, tmp_list);
1865 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1866 g_list_free_1 (tmp_list);
1875 gdk_window_set_override_redirect(GdkWindow *window,
1876 gboolean override_redirect)
1878 GdkWindowPrivate *private;
1879 XSetWindowAttributes attr;
1881 g_return_if_fail (window != NULL);
1882 private = (GdkWindowPrivate*) window;
1883 if (private->destroyed)
1886 attr.override_redirect = (override_redirect == FALSE)?False:True;
1887 XChangeWindowAttributes(gdk_display,
1888 ((GdkWindowPrivate *)window)->xwindow,
1894 gdk_window_set_icon (GdkWindow *window,
1895 GdkWindow *icon_window,
1900 GdkWindowPrivate *window_private;
1901 GdkWindowPrivate *private;
1903 g_return_if_fail (window != NULL);
1904 window_private = (GdkWindowPrivate*) window;
1905 if (window_private->destroyed)
1910 if (icon_window != NULL)
1912 private = (GdkWindowPrivate *)icon_window;
1913 wm_hints.flags |= IconWindowHint;
1914 wm_hints.icon_window = private->xwindow;
1919 private = (GdkWindowPrivate *)pixmap;
1920 wm_hints.flags |= IconPixmapHint;
1921 wm_hints.icon_pixmap = private->xwindow;
1926 private = (GdkWindowPrivate *)mask;
1927 wm_hints.flags |= IconMaskHint;
1928 wm_hints.icon_mask = private->xwindow;
1931 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1935 gdk_window_set_icon_name (GdkWindow *window,
1938 GdkWindowPrivate *window_private;
1939 XTextProperty property;
1942 g_return_if_fail (window != NULL);
1943 window_private = (GdkWindowPrivate*) window;
1944 if (window_private->destroyed)
1946 res = XmbTextListToTextProperty (window_private->xdisplay,
1947 &name, 1, XStdICCTextStyle,
1951 g_warning("Error converting icon name to text property: %d\n", res);
1955 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1959 XFree (property.value);
1963 gdk_window_set_group (GdkWindow *window,
1967 GdkWindowPrivate *window_private;
1968 GdkWindowPrivate *private;
1970 g_return_if_fail (window != NULL);
1971 g_return_if_fail (leader != NULL);
1972 window_private = (GdkWindowPrivate*) window;
1973 if (window_private->destroyed)
1976 private = (GdkWindowPrivate *)leader;
1977 wm_hints.flags = WindowGroupHint;
1978 wm_hints.window_group = private->xwindow;
1980 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1984 gdk_window_set_mwm_hints (GdkWindow *window,
1985 MotifWmHints *new_hints)
1987 static Atom hints_atom = None;
1988 MotifWmHints *hints;
1994 GdkWindowPrivate *window_private;
1996 g_return_if_fail (window != NULL);
1997 window_private = (GdkWindowPrivate*) window;
1998 if (window_private->destroyed)
2002 hints_atom = XInternAtom (window_private->xdisplay,
2003 _XA_MOTIF_WM_HINTS, FALSE);
2005 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
2006 hints_atom, 0, sizeof(MotifWmHints)/4,
2007 False, AnyPropertyType, &type, &format, &nitems,
2008 &bytes_after, (guchar **)&hints);
2014 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2016 hints->flags |= MWM_HINTS_FUNCTIONS;
2017 hints->functions = new_hints->functions;
2019 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2021 hints->flags |= MWM_HINTS_DECORATIONS;
2022 hints->decorations = new_hints->decorations;
2026 XChangeProperty (window_private->xdisplay, window_private->xwindow,
2027 hints_atom, hints_atom, 32, PropModeReplace,
2028 (guchar *)hints, sizeof(MotifWmHints)/4);
2030 if (hints != new_hints)
2035 gdk_window_set_decorations (GdkWindow *window,
2036 GdkWMDecoration decorations)
2040 hints.flags = MWM_HINTS_DECORATIONS;
2041 hints.decorations = decorations;
2043 gdk_window_set_mwm_hints (window, &hints);
2047 gdk_window_set_functions (GdkWindow *window,
2048 GdkWMFunction functions)
2052 hints.flags = MWM_HINTS_FUNCTIONS;
2053 hints.functions = functions;
2055 gdk_window_set_mwm_hints (window, &hints);
2059 gdk_window_get_toplevels (void)
2061 GList *new_list = NULL;
2064 tmp_list = gdk_root_parent.children;
2067 new_list = g_list_prepend (new_list, tmp_list->data);
2068 tmp_list = tmp_list->next;