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, gint bx, gint by, gint x, gint y,
65 GList *excludes, gboolean excl_child)
68 GdkWindowPrivate *private;
71 Window child=0,parent_win=0,root_win=0;
74 unsigned int ww, wh, wb, wd, num;
77 window=(GdkWindow*)&gdk_root_parent;
78 private=(GdkWindowPrivate*)window;
79 disp=private->xdisplay;
80 if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
83 if (!((x>=wx)&&(y>=wy)&&(x<(int)(wx+ww))&&(y<(int)(wy+wh))))
85 if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
91 if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
93 if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
107 * The following fucntion by The Rasterman <raster@redhat.com>
108 * This function returns the X Window ID in which the x y location is in
109 * (x and y being relative to the root window), excluding any windows listed
110 * in the GList excludes (this is a list of X Window ID's - gpointer being
113 * This is primarily designed for internal gdk use - for DND for example
114 * when using a shaped icon window as the drag object - you exclude the
115 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
116 * You can get back an X Window ID as to what X Window ID is infact under
117 * those X,Y co-ordinates.
120 gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
123 GdkWindowPrivate *private;
126 Window root,child=0,parent_win=0,root_win=0;
130 window=(GdkWindow*)&gdk_root_parent;
131 private=(GdkWindowPrivate*)window;
132 disp=private->xdisplay;
133 root=private->xwindow;
135 num=g_list_length(excludes);
136 if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
143 XWindowAttributes xwa;
145 XGetWindowAttributes (disp, list [i], &xwa);
147 if (xwa.map_state != IsViewable)
150 if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
153 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
158 if (!g_list_find(excludes,(gpointer *)child))
179 gdk_window_init (void)
181 XWindowAttributes xattributes;
184 unsigned int border_width;
188 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
189 &x, &y, &width, &height, &border_width, &depth);
190 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
192 gdk_root_parent.xdisplay = gdk_display;
193 gdk_root_parent.xwindow = gdk_root_window;
194 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
195 gdk_root_parent.window.user_data = NULL;
196 gdk_root_parent.width = width;
197 gdk_root_parent.height = height;
198 gdk_root_parent.children = NULL;
199 gdk_root_parent.colormap = NULL;
203 gdk_window_new (GdkWindow *parent,
204 GdkWindowAttr *attributes,
205 gint attributes_mask)
208 GdkWindowPrivate *private;
209 GdkWindowPrivate *parent_private;
211 Display *parent_display;
214 XSetWindowAttributes xattributes;
215 long xattributes_mask;
216 XSizeHints size_hints;
218 XClassHint *class_hint;
224 g_return_val_if_fail (attributes != NULL, NULL);
227 parent = (GdkWindow*) &gdk_root_parent;
229 parent_private = (GdkWindowPrivate*) parent;
230 if (parent_private->destroyed)
233 xparent = parent_private->xwindow;
234 parent_display = parent_private->xdisplay;
236 private = g_new (GdkWindowPrivate, 1);
237 window = (GdkWindow*) private;
239 private->parent = parent;
242 parent_private->children = g_list_prepend (parent_private->children, window);
244 private->xdisplay = parent_display;
245 private->destroyed = FALSE;
246 private->resize_count = 0;
247 private->ref_count = 1;
248 xattributes_mask = 0;
250 if (attributes_mask & GDK_WA_X)
255 if (attributes_mask & GDK_WA_Y)
262 private->width = (attributes->width > 1) ? (attributes->width) : (1);
263 private->height = (attributes->height > 1) ? (attributes->height) : (1);
264 private->window_type = attributes->window_type;
265 private->extension_events = FALSE;
266 private->dnd_drag_data_type = None;
267 private->dnd_drag_data_typesavail =
268 private->dnd_drop_data_typesavail = NULL;
269 private->dnd_drop_enabled = private->dnd_drag_enabled =
270 private->dnd_drag_accepted = private->dnd_drag_datashow =
271 private->dnd_drop_data_numtypesavail =
272 private->dnd_drag_data_numtypesavail = 0;
273 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
275 private->filters = NULL;
276 private->children = NULL;
278 window->user_data = NULL;
280 if (attributes_mask & GDK_WA_VISUAL)
281 visual = attributes->visual;
283 visual = gdk_visual_get_system ();
284 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
286 xattributes.event_mask = StructureNotifyMask;
287 for (i = 0; i < nevent_masks; i++)
289 if (attributes->event_mask & (1 << (i + 1)))
290 xattributes.event_mask |= event_mask_table[i];
293 if (xattributes.event_mask)
294 xattributes_mask |= CWEventMask;
296 if(attributes_mask & GDK_WA_NOREDIR) {
297 xattributes.override_redirect =
298 (attributes->override_redirect == FALSE)?False:True;
299 xattributes_mask |= CWOverrideRedirect;
301 xattributes.override_redirect = False;
303 if (attributes->wclass == GDK_INPUT_OUTPUT)
306 depth = visual->depth;
308 if (attributes_mask & GDK_WA_COLORMAP)
309 private->colormap = attributes->colormap;
311 private->colormap = gdk_colormap_get_system ();
313 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
314 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
315 xattributes_mask |= CWBorderPixel | CWBackPixel;
317 switch (private->window_type)
319 case GDK_WINDOW_TOPLEVEL:
320 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
321 xattributes_mask |= CWColormap;
323 xparent = gdk_root_window;
326 case GDK_WINDOW_CHILD:
327 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
328 xattributes_mask |= CWColormap;
331 case GDK_WINDOW_DIALOG:
332 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
333 xattributes_mask |= CWColormap;
335 xparent = gdk_root_window;
338 case GDK_WINDOW_TEMP:
339 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
340 xattributes_mask |= CWColormap;
342 xparent = gdk_root_window;
344 xattributes.save_under = True;
345 xattributes.override_redirect = True;
346 xattributes.cursor = None;
347 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
349 case GDK_WINDOW_ROOT:
350 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
352 case GDK_WINDOW_PIXMAP:
353 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
361 private->colormap = NULL;
364 private->xwindow = XCreateWindow (private->xdisplay, xparent,
365 x, y, private->width, private->height,
366 0, depth, class, xvisual,
367 xattributes_mask, &xattributes);
368 gdk_window_ref (window);
369 gdk_xid_table_insert (&private->xwindow, window);
371 if (private->colormap)
372 gdk_colormap_ref (private->colormap);
374 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
375 (attributes->cursor) :
378 switch (private->window_type)
380 case GDK_WINDOW_DIALOG:
381 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
382 case GDK_WINDOW_TOPLEVEL:
383 case GDK_WINDOW_TEMP:
384 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
386 case GDK_WINDOW_CHILD:
387 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
388 (private->colormap != gdk_colormap_get_system ()) &&
389 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
391 GDK_NOTE (MISC, g_print ("adding colormap window\n"));
392 gdk_window_add_colormap_windows (window);
401 size_hints.flags = PSize;
402 size_hints.width = private->width;
403 size_hints.height = private->height;
405 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
406 wm_hints.window_group = gdk_leader_window;
407 wm_hints.input = True;
408 wm_hints.initial_state = NormalState;
410 /* FIXME: Is there any point in doing this? Do any WM's pay
411 * attention to PSize, and even if they do, is this the
414 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
416 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
418 if (attributes_mask & GDK_WA_TITLE)
419 title = attributes->title;
421 title = gdk_progname;
423 XmbSetWMProperties (private->xdisplay, private->xwindow,
428 if (attributes_mask & GDK_WA_WMCLASS)
430 class_hint = XAllocClassHint ();
431 class_hint->res_name = attributes->wmclass_name;
432 class_hint->res_class = attributes->wmclass_class;
433 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
442 gdk_window_foreign_new (guint32 anid)
445 GdkWindowPrivate *private;
446 GdkWindowPrivate *parent_private;
447 XWindowAttributes attrs;
452 private = g_new (GdkWindowPrivate, 1);
453 window = (GdkWindow*) private;
455 XGetWindowAttributes (gdk_display, anid, &attrs);
457 /* FIXME: This is pretty expensive. Maybe the caller should supply
459 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
461 private->parent = gdk_xid_table_lookup (parent);
463 parent_private = (GdkWindowPrivate *)private->parent;
466 parent_private->children = g_list_prepend (parent_private->children, window);
468 private->xwindow = anid;
469 private->xdisplay = gdk_display;
470 private->x = attrs.x;
471 private->y = attrs.y;
472 private->width = attrs.width;
473 private->height = attrs.height;
474 private->resize_count = 0;
475 private->ref_count = 1;
476 private->window_type = GDK_WINDOW_FOREIGN;
477 private->destroyed = FALSE;
478 private->extension_events = 0;
480 private->colormap = NULL;
482 private->dnd_drag_data_type = None;
483 private->dnd_drag_data_typesavail =
484 private->dnd_drop_data_typesavail = NULL;
485 private->dnd_drop_enabled = private->dnd_drag_enabled =
486 private->dnd_drag_accepted = private->dnd_drag_datashow =
487 private->dnd_drop_data_numtypesavail =
488 private->dnd_drag_data_numtypesavail = 0;
489 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
491 private->filters = NULL;
492 private->children = NULL;
494 window->user_data = NULL;
496 gdk_window_ref (window);
497 gdk_xid_table_insert (&private->xwindow, window);
502 /* Call this function when you want a window and all its children to
503 disappear. When xdestroy is true, a request to destroy the XWindow
504 is sent out. When it is false, it is assumed that the XWindow has
505 been or will be destroyed by destroying some ancestor of this
509 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
510 gboolean our_destroy)
512 GdkWindowPrivate *private;
513 GdkWindowPrivate *temp_private;
514 GdkWindow *temp_window;
518 g_return_if_fail (window != NULL);
520 private = (GdkWindowPrivate*) window;
522 switch (private->window_type)
524 case GDK_WINDOW_TOPLEVEL:
525 case GDK_WINDOW_CHILD:
526 case GDK_WINDOW_DIALOG:
527 case GDK_WINDOW_TEMP:
528 case GDK_WINDOW_FOREIGN:
529 if (!private->destroyed)
533 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
534 if (parent_private->children)
535 parent_private->children = g_list_remove (parent_private->children, window);
538 if (private->window_type != GDK_WINDOW_FOREIGN)
540 children = tmp = private->children;
541 private->children = NULL;
545 temp_window = tmp->data;
548 temp_private = (GdkWindowPrivate*) temp_window;
550 gdk_window_internal_destroy (temp_window, FALSE,
554 g_list_free (children);
557 if (private->extension_events != 0)
558 gdk_input_window_destroy (window);
560 if(private->dnd_drag_data_numtypesavail > 0)
562 g_free (private->dnd_drag_data_typesavail);
563 private->dnd_drag_data_typesavail = NULL;
565 if(private->dnd_drop_data_numtypesavail > 0)
567 g_free (private->dnd_drop_data_typesavail);
568 private->dnd_drop_data_typesavail = NULL;
571 if (private->filters)
573 tmp = private->filters;
581 g_list_free (private->filters);
582 private->filters = NULL;
585 if (private->window_type == GDK_WINDOW_FOREIGN)
587 if (our_destroy && (private->parent != NULL))
589 /* It's somebody elses window, but in our heirarchy,
590 * so reparent it to the root window, and then send
591 * it a delete event, as if we were a WM
593 XClientMessageEvent xevent;
595 gdk_window_hide (window);
596 gdk_window_reparent (window, NULL, 0, 0);
598 xevent.type = ClientMessage;
599 xevent.window = private->xwindow;
600 xevent.message_type = gdk_wm_protocols;
602 xevent.data.l[0] = gdk_wm_delete_window;
603 xevent.data.l[1] = CurrentTime;
605 XSendEvent (private->xdisplay, private->xwindow,
606 False, 0, (XEvent *)&xevent);
610 XDestroyWindow (private->xdisplay, private->xwindow);
612 if (private->colormap)
613 gdk_colormap_unref (private->colormap);
615 private->destroyed = TRUE;
619 case GDK_WINDOW_ROOT:
620 g_error ("attempted to destroy root window");
623 case GDK_WINDOW_PIXMAP:
624 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
629 /* Like internal_destroy, but also destroys the reference created by
633 gdk_window_destroy (GdkWindow *window)
635 gdk_window_internal_destroy (window, TRUE, TRUE);
636 gdk_window_unref (window);
639 /* This function is called when the XWindow is really gone. */
642 gdk_window_destroy_notify (GdkWindow *window)
644 GdkWindowPrivate *private;
646 g_return_if_fail (window != NULL);
648 private = (GdkWindowPrivate*) window;
650 if (!private->destroyed)
652 if (private->window_type == GDK_WINDOW_FOREIGN)
653 gdk_window_internal_destroy (window, FALSE, FALSE);
655 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
658 gdk_xid_table_remove (private->xwindow);
659 gdk_window_unref (window);
663 gdk_window_ref (GdkWindow *window)
665 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
666 g_return_val_if_fail (window != NULL, NULL);
668 private->ref_count += 1;
673 gdk_window_unref (GdkWindow *window)
675 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
676 g_return_if_fail (window != NULL);
678 private->ref_count -= 1;
679 if (private->ref_count == 0)
681 if (!private->destroyed)
682 g_warning ("losing last reference to undestroyed window\n");
688 gdk_window_show (GdkWindow *window)
690 GdkWindowPrivate *private;
692 g_return_if_fail (window != NULL);
694 private = (GdkWindowPrivate*) window;
695 if (!private->destroyed)
697 XRaiseWindow (private->xdisplay, private->xwindow);
698 XMapWindow (private->xdisplay, private->xwindow);
703 gdk_window_hide (GdkWindow *window)
705 GdkWindowPrivate *private;
707 g_return_if_fail (window != NULL);
709 private = (GdkWindowPrivate*) window;
710 if (!private->destroyed)
711 XUnmapWindow (private->xdisplay, private->xwindow);
715 gdk_window_withdraw (GdkWindow *window)
717 GdkWindowPrivate *private;
719 g_return_if_fail (window != NULL);
721 private = (GdkWindowPrivate*) window;
722 if (!private->destroyed)
723 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
727 gdk_window_move (GdkWindow *window,
731 GdkWindowPrivate *private;
733 g_return_if_fail (window != NULL);
735 private = (GdkWindowPrivate*) window;
736 if (!private->destroyed)
738 XMoveWindow (private->xdisplay, private->xwindow, x, y);
740 if (private->window_type == GDK_WINDOW_CHILD)
749 gdk_window_resize (GdkWindow *window,
753 GdkWindowPrivate *private;
755 g_return_if_fail (window != NULL);
762 private = (GdkWindowPrivate*) window;
764 if (!private->destroyed &&
765 ((private->resize_count > 0) ||
766 (private->width != (guint16) width) ||
767 (private->height != (guint16) height)))
769 XResizeWindow (private->xdisplay, private->xwindow, width, height);
770 private->resize_count += 1;
772 if (private->window_type == GDK_WINDOW_CHILD)
774 private->width = width;
775 private->height = height;
781 gdk_window_move_resize (GdkWindow *window,
787 GdkWindowPrivate *private;
789 g_return_if_fail (window != NULL);
796 private = (GdkWindowPrivate*) window;
797 if (!private->destroyed)
799 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
801 if (private->window_type == GDK_WINDOW_CHILD)
805 private->width = width;
806 private->height = height;
812 gdk_window_reparent (GdkWindow *window,
813 GdkWindow *new_parent,
817 GdkWindowPrivate *window_private;
818 GdkWindowPrivate *parent_private;
819 GdkWindowPrivate *old_parent_private;
821 g_return_if_fail (window != NULL);
824 new_parent = (GdkWindow*) &gdk_root_parent;
826 window_private = (GdkWindowPrivate*) window;
827 old_parent_private = (GdkWindowPrivate*)window_private->parent;
828 parent_private = (GdkWindowPrivate*) new_parent;
830 if (!window_private->destroyed && !parent_private->destroyed)
831 XReparentWindow (window_private->xdisplay,
832 window_private->xwindow,
833 parent_private->xwindow,
836 old_parent_private->children = g_list_remove (old_parent_private->children, window);
837 parent_private->children = g_list_prepend (parent_private->children, window);
842 gdk_window_clear (GdkWindow *window)
844 GdkWindowPrivate *private;
846 g_return_if_fail (window != NULL);
848 private = (GdkWindowPrivate*) window;
850 if (!private->destroyed)
851 XClearWindow (private->xdisplay, private->xwindow);
855 gdk_window_clear_area (GdkWindow *window,
861 GdkWindowPrivate *private;
863 g_return_if_fail (window != NULL);
865 private = (GdkWindowPrivate*) window;
867 if (!private->destroyed)
868 XClearArea (private->xdisplay, private->xwindow,
869 x, y, width, height, False);
873 gdk_window_clear_area_e (GdkWindow *window,
879 GdkWindowPrivate *private;
881 g_return_if_fail (window != NULL);
883 private = (GdkWindowPrivate*) window;
885 if (!private->destroyed)
886 XClearArea (private->xdisplay, private->xwindow,
887 x, y, width, height, True);
891 gdk_window_copy_area (GdkWindow *window,
895 GdkWindow *source_window,
901 GdkWindowPrivate *src_private;
902 GdkWindowPrivate *dest_private;
903 GdkGCPrivate *gc_private;
905 g_return_if_fail (window != NULL);
906 g_return_if_fail (gc != NULL);
908 if (source_window == NULL)
909 source_window = window;
911 src_private = (GdkWindowPrivate*) source_window;
912 dest_private = (GdkWindowPrivate*) window;
913 gc_private = (GdkGCPrivate*) gc;
915 if (!src_private->destroyed && !dest_private->destroyed)
917 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
926 gdk_window_raise (GdkWindow *window)
928 GdkWindowPrivate *private;
930 g_return_if_fail (window != NULL);
932 private = (GdkWindowPrivate*) window;
934 if (!private->destroyed)
935 XRaiseWindow (private->xdisplay, private->xwindow);
939 gdk_window_lower (GdkWindow *window)
941 GdkWindowPrivate *private;
943 g_return_if_fail (window != NULL);
945 private = (GdkWindowPrivate*) window;
947 if (!private->destroyed)
948 XLowerWindow (private->xdisplay, private->xwindow);
952 gdk_window_set_user_data (GdkWindow *window,
955 g_return_if_fail (window != NULL);
957 window->user_data = user_data;
961 gdk_window_set_hints (GdkWindow *window,
970 GdkWindowPrivate *private;
971 XSizeHints size_hints;
973 g_return_if_fail (window != NULL);
975 private = (GdkWindowPrivate*) window;
976 if (private->destroyed)
979 size_hints.flags = 0;
981 if (flags & GDK_HINT_POS)
983 size_hints.flags |= PPosition;
988 if (flags & GDK_HINT_MIN_SIZE)
990 size_hints.flags |= PMinSize;
991 size_hints.min_width = min_width;
992 size_hints.min_height = min_height;
995 if (flags & GDK_HINT_MAX_SIZE)
997 size_hints.flags |= PMaxSize;
998 size_hints.max_width = max_width;
999 size_hints.max_height = max_height;
1003 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1007 gdk_window_set_title (GdkWindow *window,
1010 GdkWindowPrivate *private;
1012 g_return_if_fail (window != NULL);
1014 private = (GdkWindowPrivate*) window;
1015 if (!private->destroyed)
1016 XmbSetWMProperties (private->xdisplay, private->xwindow,
1017 title, title, NULL, 0, NULL, NULL, NULL);
1021 gdk_window_set_background (GdkWindow *window,
1024 GdkWindowPrivate *private;
1026 g_return_if_fail (window != NULL);
1028 private = (GdkWindowPrivate*) window;
1029 if (!private->destroyed)
1030 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1034 gdk_window_set_back_pixmap (GdkWindow *window,
1036 gint parent_relative)
1038 GdkWindowPrivate *window_private;
1039 GdkPixmapPrivate *pixmap_private;
1042 g_return_if_fail (window != NULL);
1044 window_private = (GdkWindowPrivate*) window;
1045 pixmap_private = (GdkPixmapPrivate*) pixmap;
1048 xpixmap = pixmap_private->xwindow;
1052 if (parent_relative)
1053 xpixmap = ParentRelative;
1055 if (!window_private->destroyed)
1056 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1060 gdk_window_set_cursor (GdkWindow *window,
1063 GdkWindowPrivate *window_private;
1064 GdkCursorPrivate *cursor_private;
1067 g_return_if_fail (window != NULL);
1069 window_private = (GdkWindowPrivate*) window;
1070 cursor_private = (GdkCursorPrivate*) cursor;
1075 xcursor = cursor_private->xcursor;
1077 if (!window_private->destroyed)
1078 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1082 gdk_window_set_colormap (GdkWindow *window,
1083 GdkColormap *colormap)
1085 GdkWindowPrivate *window_private;
1086 GdkColormapPrivate *colormap_private;
1088 g_return_if_fail (window != NULL);
1089 g_return_if_fail (colormap != NULL);
1091 window_private = (GdkWindowPrivate*) window;
1092 colormap_private = (GdkColormapPrivate*) colormap;
1094 if (!window_private->destroyed)
1096 XSetWindowColormap (window_private->xdisplay,
1097 window_private->xwindow,
1098 colormap_private->xcolormap);
1100 if (window_private->colormap)
1101 gdk_colormap_unref (window_private->colormap);
1102 window_private->colormap = colormap;
1103 gdk_colormap_ref (window_private->colormap);
1105 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1106 gdk_window_add_colormap_windows (window);
1111 gdk_window_get_user_data (GdkWindow *window,
1114 g_return_if_fail (window != NULL);
1116 *data = window->user_data;
1120 gdk_window_get_geometry (GdkWindow *window,
1127 GdkWindowPrivate *window_private;
1133 guint tborder_width;
1137 window = (GdkWindow*) &gdk_root_parent;
1139 window_private = (GdkWindowPrivate*) window;
1141 if (!window_private->destroyed)
1143 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1144 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1160 gdk_window_get_position (GdkWindow *window,
1164 GdkWindowPrivate *window_private;
1166 g_return_if_fail (window != NULL);
1168 window_private = (GdkWindowPrivate*) window;
1171 *x = window_private->x;
1173 *y = window_private->y;
1177 gdk_window_get_size (GdkWindow *window,
1181 GdkWindowPrivate *window_private;
1183 g_return_if_fail (window != NULL);
1185 window_private = (GdkWindowPrivate*) window;
1188 *width = window_private->width;
1190 *height = window_private->height;
1194 gdk_window_get_visual (GdkWindow *window)
1196 GdkWindowPrivate *window_private;
1197 XWindowAttributes window_attributes;
1199 g_return_val_if_fail (window != NULL, NULL);
1201 window_private = (GdkWindowPrivate*) window;
1202 /* Huh? ->parent is never set for a pixmap. We should just return
1205 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1206 window_private = (GdkWindowPrivate*) window_private->parent;
1208 if (window_private && !window_private->destroyed)
1210 if (window_private->colormap == NULL)
1212 XGetWindowAttributes (window_private->xdisplay,
1213 window_private->xwindow,
1214 &window_attributes);
1215 return gdk_visual_lookup (window_attributes.visual);
1218 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1225 gdk_window_get_colormap (GdkWindow *window)
1227 GdkWindowPrivate *window_private;
1228 XWindowAttributes window_attributes;
1230 g_return_val_if_fail (window != NULL, NULL);
1231 window_private = (GdkWindowPrivate*) window;
1233 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1234 if (!window_private->destroyed)
1236 if (window_private->colormap == NULL)
1238 XGetWindowAttributes (window_private->xdisplay,
1239 window_private->xwindow,
1240 &window_attributes);
1241 return gdk_colormap_lookup (window_attributes.colormap);
1244 return window_private->colormap;
1251 gdk_window_get_type (GdkWindow *window)
1253 GdkWindowPrivate *window_private;
1255 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1257 window_private = (GdkWindowPrivate*) window;
1258 return window_private->window_type;
1262 gdk_window_get_origin (GdkWindow *window,
1266 GdkWindowPrivate *private;
1271 g_return_val_if_fail (window != NULL, 0);
1273 private = (GdkWindowPrivate*) window;
1275 if (!private->destroyed)
1277 return_val = XTranslateCoordinates (private->xdisplay,
1295 gdk_window_get_pointer (GdkWindow *window,
1298 GdkModifierType *mask)
1300 GdkWindowPrivate *private;
1301 GdkWindow *return_val;
1309 window = (GdkWindow*) &gdk_root_parent;
1311 private = (GdkWindowPrivate*) window;
1314 if (!private->destroyed &&
1315 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1316 &rootx, &rooty, &winx, &winy, &xmask))
1320 if (mask) *mask = xmask;
1323 return_val = gdk_window_lookup (child);
1330 gdk_window_get_parent (GdkWindow *window)
1332 g_return_val_if_fail (window != NULL, NULL);
1334 return ((GdkWindowPrivate*) window)->parent;
1338 gdk_window_get_toplevel (GdkWindow *window)
1340 GdkWindowPrivate *private;
1342 g_return_val_if_fail (window != NULL, NULL);
1344 private = (GdkWindowPrivate*) window;
1346 while (private->window_type == GDK_WINDOW_CHILD)
1348 window = ((GdkWindowPrivate*) window)->parent;
1349 private = (GdkWindowPrivate*) window;
1356 gdk_window_get_children (GdkWindow *window)
1358 GdkWindowPrivate *private;
1364 unsigned int nchildren;
1367 g_return_val_if_fail (window != NULL, NULL);
1369 private = (GdkWindowPrivate*) window;
1370 if (private->destroyed)
1373 XQueryTree (private->xdisplay, private->xwindow,
1374 &root, &parent, &xchildren, &nchildren);
1380 for (i = 0; i < nchildren; i++)
1382 child = gdk_window_lookup (xchildren[i]);
1384 children = g_list_prepend (children, child);
1394 gdk_window_get_events (GdkWindow *window)
1396 GdkWindowPrivate *private;
1397 XWindowAttributes attrs;
1398 GdkEventMask event_mask;
1401 g_return_val_if_fail (window != NULL, 0);
1403 private = (GdkWindowPrivate*) window;
1404 if (private->destroyed)
1407 XGetWindowAttributes (gdk_display, private->xwindow,
1411 for (i = 0; i < nevent_masks; i++)
1413 if (attrs.your_event_mask & event_mask_table[i])
1414 event_mask |= 1 << (i + 1);
1421 gdk_window_set_events (GdkWindow *window,
1422 GdkEventMask event_mask)
1424 GdkWindowPrivate *private;
1428 g_return_if_fail (window != NULL);
1430 private = (GdkWindowPrivate*) window;
1431 if (private->destroyed)
1434 xevent_mask = StructureNotifyMask;
1435 for (i = 0; i < nevent_masks; i++)
1437 if (event_mask & (1 << (i + 1)))
1438 xevent_mask |= event_mask_table[i];
1441 XSelectInput (gdk_display, private->xwindow,
1446 gdk_window_add_colormap_windows (GdkWindow *window)
1448 GdkWindow *toplevel;
1449 GdkWindowPrivate *toplevel_private;
1450 GdkWindowPrivate *window_private;
1451 Window *old_windows;
1452 Window *new_windows;
1455 g_return_if_fail (window != NULL);
1457 toplevel = gdk_window_get_toplevel (window);
1458 toplevel_private = (GdkWindowPrivate*) toplevel;
1459 window_private = (GdkWindowPrivate*) window;
1460 if (window_private->destroyed)
1463 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1464 toplevel_private->xwindow,
1465 &old_windows, &count))
1471 for (i = 0; i < count; i++)
1472 if (old_windows[i] == window_private->xwindow)
1475 new_windows = g_new (Window, count + 1);
1477 for (i = 0; i < count; i++)
1478 new_windows[i] = old_windows[i];
1479 new_windows[count] = window_private->xwindow;
1481 XSetWMColormapWindows (toplevel_private->xdisplay,
1482 toplevel_private->xwindow,
1483 new_windows, count + 1);
1485 g_free (new_windows);
1487 XFree (old_windows);
1491 * This needs the X11 shape extension.
1492 * If not available, shaped windows will look
1493 * ugly, but programs still work. Stefan Wille
1496 gdk_window_shape_combine_mask (GdkWindow *window,
1500 enum { UNKNOWN, NO, YES };
1502 static gint have_shape = UNKNOWN;
1504 GdkWindowPrivate *window_private;
1507 g_return_if_fail (window != NULL);
1509 #ifdef HAVE_SHAPE_EXT
1510 if (have_shape == UNKNOWN)
1513 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1519 if (have_shape == YES)
1521 window_private = (GdkWindowPrivate*) window;
1522 if (window_private->destroyed)
1527 GdkWindowPrivate *pixmap_private;
1529 pixmap_private = (GdkWindowPrivate*) mask;
1530 pixmap = (Pixmap) pixmap_private->xwindow;
1539 XShapeCombineMask (window_private->xdisplay,
1540 window_private->xwindow,
1546 #endif /* HAVE_SHAPE_EXT */
1550 gdk_dnd_drag_addwindow (GdkWindow *window)
1552 GdkWindowPrivate *window_private;
1554 g_return_if_fail (window != NULL);
1556 window_private = (GdkWindowPrivate *) window;
1557 if (window_private->destroyed)
1560 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1562 gdk_dnd.drag_numwindows++;
1563 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1564 gdk_dnd.drag_numwindows
1565 * sizeof(GdkWindow *));
1566 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1567 window_private->dnd_drag_accepted = 0;
1570 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1574 gdk_window_dnd_drag_set (GdkWindow *window,
1579 GdkWindowPrivate *window_private;
1582 g_return_if_fail (window != NULL);
1583 window_private = (GdkWindowPrivate *) window;
1584 if (window_private->destroyed)
1587 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1591 g_return_if_fail(typelist != NULL);
1593 if (window_private->dnd_drag_data_numtypesavail > 3)
1595 window_private->dnd_drag_data_numtypesavail = numtypes;
1597 window_private->dnd_drag_data_typesavail =
1598 g_realloc (window_private->dnd_drag_data_typesavail,
1599 (numtypes + 1) * sizeof (GdkAtom));
1601 for (i = 0; i < numtypes; i++)
1603 /* Allow blanket use of ALL to get anything... */
1604 if (strcmp (typelist[i], "ALL"))
1605 window_private->dnd_drag_data_typesavail[i] =
1606 gdk_atom_intern (typelist[i], FALSE);
1608 window_private->dnd_drag_data_typesavail[i] = None;
1612 * set our extended type list if we need to
1615 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1616 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1617 (guchar *)(window_private->dnd_drag_data_typesavail
1618 + (sizeof(GdkAtom) * 3)),
1619 (numtypes - 3) * sizeof(GdkAtom));
1621 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1625 g_free (window_private->dnd_drag_data_typesavail);
1626 window_private->dnd_drag_data_typesavail = NULL;
1627 window_private->dnd_drag_data_numtypesavail = 0;
1632 gdk_window_dnd_drop_set (GdkWindow *window,
1636 guint8 destructive_op)
1638 GdkWindowPrivate *window_private;
1641 g_return_if_fail (window != NULL);
1642 window_private = (GdkWindowPrivate *) window;
1643 if (window_private->destroyed)
1646 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1649 g_return_if_fail(typelist != NULL);
1651 window_private->dnd_drop_data_numtypesavail = numtypes;
1653 window_private->dnd_drop_data_typesavail =
1654 g_realloc (window_private->dnd_drop_data_typesavail,
1655 (numtypes + 1) * sizeof (GdkAtom));
1657 for (i = 0; i < numtypes; i++)
1658 window_private->dnd_drop_data_typesavail[i] =
1659 gdk_atom_intern (typelist[i], FALSE);
1661 window_private->dnd_drop_destructive_op = destructive_op;
1666 * This is used to reply to a GDK_DRAG_REQUEST event
1667 * (which may be generated by XdeRequest or a confirmed drop...
1670 gdk_window_dnd_data_set (GdkWindow *window,
1673 gulong data_numbytes)
1675 GdkWindowPrivate *window_private;
1677 GdkEventDropDataAvailable tmp_ev;
1680 g_return_if_fail (window != NULL);
1681 g_return_if_fail (event != NULL);
1682 g_return_if_fail (data != NULL);
1683 g_return_if_fail (data_numbytes > 0);
1684 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1686 window_private = (GdkWindowPrivate *) window;
1687 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1688 if (window_private->destroyed)
1691 /* We set the property on our window... */
1692 gdk_property_change (window, window_private->dnd_drag_data_type,
1693 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1695 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1697 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1702 * Then we send the event to tell the receiving window that the
1705 tmp_ev.u.allflags = 0;
1706 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1707 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1709 sev.xclient.type = ClientMessage;
1710 sev.xclient.format = 32;
1711 sev.xclient.window = event->dragrequest.requestor;
1712 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1713 sev.xclient.data.l[0] = window_private->xwindow;
1714 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1715 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1717 if (event->dragrequest.isdrop)
1718 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1719 (event->dragrequest.drop_coords.y << 16);
1721 sev.xclient.data.l[3] = 0;
1723 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1725 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1726 StructureNotifyMask, &sev))
1727 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1728 event->dragrequest.requestor));
1733 gdk_window_add_filter (GdkWindow *window,
1734 GdkFilterFunc function,
1737 GdkWindowPrivate *private;
1739 GdkEventFilter *filter;
1741 private = (GdkWindowPrivate*) window;
1742 if (private && private->destroyed)
1746 tmp_list = private->filters;
1748 tmp_list = gdk_default_filters;
1752 filter = (GdkEventFilter *)tmp_list->data;
1753 if ((filter->function == function) && (filter->data == data))
1755 tmp_list = tmp_list->next;
1758 filter = g_new (GdkEventFilter, 1);
1759 filter->function = function;
1760 filter->data = data;
1763 private->filters = g_list_append (private->filters, filter);
1765 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1769 gdk_window_remove_filter (GdkWindow *window,
1770 GdkFilterFunc function,
1773 GdkWindowPrivate *private;
1775 GdkEventFilter *filter;
1777 private = (GdkWindowPrivate*) window;
1780 tmp_list = private->filters;
1782 tmp_list = gdk_default_filters;
1786 filter = (GdkEventFilter *)tmp_list->data;
1787 tmp_list = tmp_list->next;
1789 if ((filter->function == function) && (filter->data == data))
1792 private->filters = g_list_remove_link (private->filters, tmp_list);
1794 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1795 g_list_free_1 (tmp_list);
1804 gdk_window_set_override_redirect(GdkWindow *window,
1805 gboolean override_redirect)
1807 GdkWindowPrivate *private;
1808 XSetWindowAttributes attr;
1810 g_return_if_fail (window != NULL);
1811 private = (GdkWindowPrivate*) window;
1812 if (private->destroyed)
1815 attr.override_redirect = (override_redirect == FALSE)?False:True;
1816 XChangeWindowAttributes(gdk_display,
1817 ((GdkWindowPrivate *)window)->xwindow,
1823 gdk_window_set_icon (GdkWindow *window,
1824 GdkWindow *icon_window,
1829 GdkWindowPrivate *window_private;
1830 GdkWindowPrivate *private;
1832 g_return_if_fail (window != NULL);
1833 window_private = (GdkWindowPrivate*) window;
1834 if (window_private->destroyed)
1839 if (icon_window != NULL)
1841 private = (GdkWindowPrivate *)icon_window;
1842 wm_hints.flags |= IconWindowHint;
1843 wm_hints.icon_window = private->xwindow;
1848 private = (GdkWindowPrivate *)pixmap;
1849 wm_hints.flags |= IconPixmapHint;
1850 wm_hints.icon_pixmap = private->xwindow;
1855 private = (GdkWindowPrivate *)mask;
1856 wm_hints.flags |= IconMaskHint;
1857 wm_hints.icon_mask = private->xwindow;
1860 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1864 gdk_window_set_icon_name (GdkWindow *window,
1867 GdkWindowPrivate *window_private;
1868 XTextProperty property;
1871 g_return_if_fail (window != NULL);
1872 window_private = (GdkWindowPrivate*) window;
1873 if (window_private->destroyed)
1875 res = XmbTextListToTextProperty (window_private->xdisplay,
1876 &name, 1, XStdICCTextStyle,
1880 g_warning("Error converting icon name to text property: %d\n", res);
1884 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1887 XFree(property.value);
1891 gdk_window_set_group (GdkWindow *window,
1895 GdkWindowPrivate *window_private;
1896 GdkWindowPrivate *private;
1898 g_return_if_fail (window != NULL);
1899 g_return_if_fail (leader != NULL);
1900 window_private = (GdkWindowPrivate*) window;
1901 if (window_private->destroyed)
1904 private = (GdkWindowPrivate *)leader;
1905 wm_hints.flags = WindowGroupHint;
1906 wm_hints.window_group = private->xwindow;
1908 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1912 gdk_window_set_mwm_hints (GdkWindow *window,
1913 MotifWmHints *new_hints)
1915 static Atom hints_atom = None;
1916 MotifWmHints *hints;
1922 GdkWindowPrivate *window_private;
1924 g_return_if_fail (window != NULL);
1925 window_private = (GdkWindowPrivate*) window;
1926 if (window_private->destroyed)
1930 hints_atom = XInternAtom (window_private->xdisplay,
1931 _XA_MOTIF_WM_HINTS, FALSE);
1933 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1934 hints_atom, 0, sizeof(MotifWmHints)/4,
1935 False, AnyPropertyType, &type, &format, &nitems,
1936 &bytes_after, (guchar **)&hints);
1942 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1944 hints->flags |= MWM_HINTS_FUNCTIONS;
1945 hints->functions = new_hints->functions;
1947 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1949 hints->flags |= MWM_HINTS_DECORATIONS;
1950 hints->decorations = new_hints->decorations;
1954 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1955 hints_atom, hints_atom, 32, PropModeReplace,
1956 (guchar *)hints, sizeof(MotifWmHints)/4);
1958 if (hints != new_hints)
1963 gdk_window_set_decorations (GdkWindow *window,
1964 GdkWMDecoration decorations)
1968 hints.flags = MWM_HINTS_DECORATIONS;
1969 hints.decorations = decorations;
1971 gdk_window_set_mwm_hints (window, &hints);
1975 gdk_window_set_functions (GdkWindow *window,
1976 GdkWMFunction functions)
1980 hints.flags = MWM_HINTS_FUNCTIONS;
1981 hints.functions = functions;
1983 gdk_window_set_mwm_hints (window, &hints);
1987 gdk_window_get_toplevels (void)
1989 GList *new_list = NULL;
1992 tmp_list = gdk_root_parent.children;
1995 new_list = g_list_prepend (new_list, tmp_list->data);
1996 tmp_list = tmp_list->next;