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;
820 g_return_if_fail (window != NULL);
823 new_parent = (GdkWindow*) &gdk_root_parent;
825 window_private = (GdkWindowPrivate*) window;
826 parent_private = (GdkWindowPrivate*) new_parent;
828 if (!window_private->destroyed && !parent_private->destroyed)
829 XReparentWindow (window_private->xdisplay,
830 window_private->xwindow,
831 parent_private->xwindow,
836 gdk_window_clear (GdkWindow *window)
838 GdkWindowPrivate *private;
840 g_return_if_fail (window != NULL);
842 private = (GdkWindowPrivate*) window;
844 if (!private->destroyed)
845 XClearWindow (private->xdisplay, private->xwindow);
849 gdk_window_clear_area (GdkWindow *window,
855 GdkWindowPrivate *private;
857 g_return_if_fail (window != NULL);
859 private = (GdkWindowPrivate*) window;
861 if (!private->destroyed)
862 XClearArea (private->xdisplay, private->xwindow,
863 x, y, width, height, False);
867 gdk_window_clear_area_e (GdkWindow *window,
873 GdkWindowPrivate *private;
875 g_return_if_fail (window != NULL);
877 private = (GdkWindowPrivate*) window;
879 if (!private->destroyed)
880 XClearArea (private->xdisplay, private->xwindow,
881 x, y, width, height, True);
885 gdk_window_copy_area (GdkWindow *window,
889 GdkWindow *source_window,
895 GdkWindowPrivate *src_private;
896 GdkWindowPrivate *dest_private;
897 GdkGCPrivate *gc_private;
899 g_return_if_fail (window != NULL);
900 g_return_if_fail (gc != NULL);
902 if (source_window == NULL)
903 source_window = window;
905 src_private = (GdkWindowPrivate*) source_window;
906 dest_private = (GdkWindowPrivate*) window;
907 gc_private = (GdkGCPrivate*) gc;
909 if (!src_private->destroyed && !dest_private->destroyed)
911 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
920 gdk_window_raise (GdkWindow *window)
922 GdkWindowPrivate *private;
924 g_return_if_fail (window != NULL);
926 private = (GdkWindowPrivate*) window;
928 if (!private->destroyed)
929 XRaiseWindow (private->xdisplay, private->xwindow);
933 gdk_window_lower (GdkWindow *window)
935 GdkWindowPrivate *private;
937 g_return_if_fail (window != NULL);
939 private = (GdkWindowPrivate*) window;
941 if (!private->destroyed)
942 XLowerWindow (private->xdisplay, private->xwindow);
946 gdk_window_set_user_data (GdkWindow *window,
949 g_return_if_fail (window != NULL);
951 window->user_data = user_data;
955 gdk_window_set_hints (GdkWindow *window,
964 GdkWindowPrivate *private;
965 XSizeHints size_hints;
967 g_return_if_fail (window != NULL);
969 private = (GdkWindowPrivate*) window;
970 if (private->destroyed)
973 size_hints.flags = 0;
975 if (flags & GDK_HINT_POS)
977 size_hints.flags |= PPosition;
982 if (flags & GDK_HINT_MIN_SIZE)
984 size_hints.flags |= PMinSize;
985 size_hints.min_width = min_width;
986 size_hints.min_height = min_height;
989 if (flags & GDK_HINT_MAX_SIZE)
991 size_hints.flags |= PMaxSize;
992 size_hints.max_width = max_width;
993 size_hints.max_height = max_height;
997 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1001 gdk_window_set_title (GdkWindow *window,
1004 GdkWindowPrivate *private;
1006 g_return_if_fail (window != NULL);
1008 private = (GdkWindowPrivate*) window;
1009 if (!private->destroyed)
1010 XmbSetWMProperties (private->xdisplay, private->xwindow,
1011 title, title, NULL, 0, NULL, NULL, NULL);
1015 gdk_window_set_background (GdkWindow *window,
1018 GdkWindowPrivate *private;
1020 g_return_if_fail (window != NULL);
1022 private = (GdkWindowPrivate*) window;
1023 if (!private->destroyed)
1024 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1028 gdk_window_set_back_pixmap (GdkWindow *window,
1030 gint parent_relative)
1032 GdkWindowPrivate *window_private;
1033 GdkPixmapPrivate *pixmap_private;
1036 g_return_if_fail (window != NULL);
1038 window_private = (GdkWindowPrivate*) window;
1039 pixmap_private = (GdkPixmapPrivate*) pixmap;
1042 xpixmap = pixmap_private->xwindow;
1046 if (parent_relative)
1047 xpixmap = ParentRelative;
1049 if (!window_private->destroyed)
1050 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1054 gdk_window_set_cursor (GdkWindow *window,
1057 GdkWindowPrivate *window_private;
1058 GdkCursorPrivate *cursor_private;
1061 g_return_if_fail (window != NULL);
1063 window_private = (GdkWindowPrivate*) window;
1064 cursor_private = (GdkCursorPrivate*) cursor;
1069 xcursor = cursor_private->xcursor;
1071 if (!window_private->destroyed)
1072 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1076 gdk_window_set_colormap (GdkWindow *window,
1077 GdkColormap *colormap)
1079 GdkWindowPrivate *window_private;
1080 GdkColormapPrivate *colormap_private;
1082 g_return_if_fail (window != NULL);
1083 g_return_if_fail (colormap != NULL);
1085 window_private = (GdkWindowPrivate*) window;
1086 colormap_private = (GdkColormapPrivate*) colormap;
1088 if (!window_private->destroyed)
1090 XSetWindowColormap (window_private->xdisplay,
1091 window_private->xwindow,
1092 colormap_private->xcolormap);
1094 if (window_private->colormap)
1095 gdk_colormap_unref (window_private->colormap);
1096 window_private->colormap = colormap;
1097 gdk_colormap_ref (window_private->colormap);
1099 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1100 gdk_window_add_colormap_windows (window);
1105 gdk_window_get_user_data (GdkWindow *window,
1108 g_return_if_fail (window != NULL);
1110 *data = window->user_data;
1114 gdk_window_get_geometry (GdkWindow *window,
1121 GdkWindowPrivate *window_private;
1127 guint tborder_width;
1131 window = (GdkWindow*) &gdk_root_parent;
1133 window_private = (GdkWindowPrivate*) window;
1135 if (!window_private->destroyed)
1137 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1138 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1154 gdk_window_get_position (GdkWindow *window,
1158 GdkWindowPrivate *window_private;
1160 g_return_if_fail (window != NULL);
1162 window_private = (GdkWindowPrivate*) window;
1165 *x = window_private->x;
1167 *y = window_private->y;
1171 gdk_window_get_size (GdkWindow *window,
1175 GdkWindowPrivate *window_private;
1177 g_return_if_fail (window != NULL);
1179 window_private = (GdkWindowPrivate*) window;
1182 *width = window_private->width;
1184 *height = window_private->height;
1188 gdk_window_get_visual (GdkWindow *window)
1190 GdkWindowPrivate *window_private;
1191 XWindowAttributes window_attributes;
1193 g_return_val_if_fail (window != NULL, NULL);
1195 window_private = (GdkWindowPrivate*) window;
1196 /* Huh? ->parent is never set for a pixmap. We should just return
1199 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1200 window_private = (GdkWindowPrivate*) window_private->parent;
1202 if (window_private && !window_private->destroyed)
1204 if (window_private->colormap == NULL)
1206 XGetWindowAttributes (window_private->xdisplay,
1207 window_private->xwindow,
1208 &window_attributes);
1209 return gdk_visual_lookup (window_attributes.visual);
1212 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1219 gdk_window_get_colormap (GdkWindow *window)
1221 GdkWindowPrivate *window_private;
1222 XWindowAttributes window_attributes;
1224 g_return_val_if_fail (window != NULL, NULL);
1225 window_private = (GdkWindowPrivate*) window;
1227 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1228 if (!window_private->destroyed)
1230 if (window_private->colormap == NULL)
1232 XGetWindowAttributes (window_private->xdisplay,
1233 window_private->xwindow,
1234 &window_attributes);
1235 return gdk_colormap_lookup (window_attributes.colormap);
1238 return window_private->colormap;
1245 gdk_window_get_type (GdkWindow *window)
1247 GdkWindowPrivate *window_private;
1249 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1251 window_private = (GdkWindowPrivate*) window;
1252 return window_private->window_type;
1256 gdk_window_get_origin (GdkWindow *window,
1260 GdkWindowPrivate *private;
1265 g_return_val_if_fail (window != NULL, 0);
1267 private = (GdkWindowPrivate*) window;
1269 if (!private->destroyed)
1271 return_val = XTranslateCoordinates (private->xdisplay,
1289 gdk_window_get_pointer (GdkWindow *window,
1292 GdkModifierType *mask)
1294 GdkWindowPrivate *private;
1295 GdkWindow *return_val;
1303 window = (GdkWindow*) &gdk_root_parent;
1305 private = (GdkWindowPrivate*) window;
1308 if (!private->destroyed &&
1309 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1310 &rootx, &rooty, &winx, &winy, &xmask))
1314 if (mask) *mask = xmask;
1317 return_val = gdk_window_lookup (child);
1324 gdk_window_get_parent (GdkWindow *window)
1326 g_return_val_if_fail (window != NULL, NULL);
1328 return ((GdkWindowPrivate*) window)->parent;
1332 gdk_window_get_toplevel (GdkWindow *window)
1334 GdkWindowPrivate *private;
1336 g_return_val_if_fail (window != NULL, NULL);
1338 private = (GdkWindowPrivate*) window;
1340 while (private->window_type == GDK_WINDOW_CHILD)
1342 window = ((GdkWindowPrivate*) window)->parent;
1343 private = (GdkWindowPrivate*) window;
1350 gdk_window_get_children (GdkWindow *window)
1352 GdkWindowPrivate *private;
1358 unsigned int nchildren;
1361 g_return_val_if_fail (window != NULL, NULL);
1363 private = (GdkWindowPrivate*) window;
1364 if (private->destroyed)
1367 XQueryTree (private->xdisplay, private->xwindow,
1368 &root, &parent, &xchildren, &nchildren);
1374 for (i = 0; i < nchildren; i++)
1376 child = gdk_window_lookup (xchildren[i]);
1378 children = g_list_prepend (children, child);
1388 gdk_window_get_events (GdkWindow *window)
1390 GdkWindowPrivate *private;
1391 XWindowAttributes attrs;
1392 GdkEventMask event_mask;
1395 g_return_val_if_fail (window != NULL, 0);
1397 private = (GdkWindowPrivate*) window;
1398 if (private->destroyed)
1401 XGetWindowAttributes (gdk_display, private->xwindow,
1405 for (i = 0; i < nevent_masks; i++)
1407 if (attrs.your_event_mask & event_mask_table[i])
1408 event_mask |= 1 << (i + 1);
1415 gdk_window_set_events (GdkWindow *window,
1416 GdkEventMask event_mask)
1418 GdkWindowPrivate *private;
1422 g_return_if_fail (window != NULL);
1424 private = (GdkWindowPrivate*) window;
1425 if (private->destroyed)
1428 xevent_mask = StructureNotifyMask;
1429 for (i = 0; i < nevent_masks; i++)
1431 if (event_mask & (1 << (i + 1)))
1432 xevent_mask |= event_mask_table[i];
1435 XSelectInput (gdk_display, private->xwindow,
1440 gdk_window_add_colormap_windows (GdkWindow *window)
1442 GdkWindow *toplevel;
1443 GdkWindowPrivate *toplevel_private;
1444 GdkWindowPrivate *window_private;
1445 Window *old_windows;
1446 Window *new_windows;
1449 g_return_if_fail (window != NULL);
1451 toplevel = gdk_window_get_toplevel (window);
1452 toplevel_private = (GdkWindowPrivate*) toplevel;
1453 window_private = (GdkWindowPrivate*) window;
1454 if (window_private->destroyed)
1457 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1458 toplevel_private->xwindow,
1459 &old_windows, &count))
1465 for (i = 0; i < count; i++)
1466 if (old_windows[i] == window_private->xwindow)
1469 new_windows = g_new (Window, count + 1);
1471 for (i = 0; i < count; i++)
1472 new_windows[i] = old_windows[i];
1473 new_windows[count] = window_private->xwindow;
1475 XSetWMColormapWindows (toplevel_private->xdisplay,
1476 toplevel_private->xwindow,
1477 new_windows, count + 1);
1479 g_free (new_windows);
1481 XFree (old_windows);
1485 * This needs the X11 shape extension.
1486 * If not available, shaped windows will look
1487 * ugly, but programs still work. Stefan Wille
1490 gdk_window_shape_combine_mask (GdkWindow *window,
1494 enum { UNKNOWN, NO, YES };
1496 static gint have_shape = UNKNOWN;
1498 GdkWindowPrivate *window_private;
1501 g_return_if_fail (window != NULL);
1503 #ifdef HAVE_SHAPE_EXT
1504 if (have_shape == UNKNOWN)
1507 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1513 if (have_shape == YES)
1515 window_private = (GdkWindowPrivate*) window;
1516 if (window_private->destroyed)
1521 GdkWindowPrivate *pixmap_private;
1523 pixmap_private = (GdkWindowPrivate*) mask;
1524 pixmap = (Pixmap) pixmap_private->xwindow;
1533 XShapeCombineMask (window_private->xdisplay,
1534 window_private->xwindow,
1540 #endif /* HAVE_SHAPE_EXT */
1544 gdk_dnd_drag_addwindow (GdkWindow *window)
1546 GdkWindowPrivate *window_private;
1548 g_return_if_fail (window != NULL);
1550 window_private = (GdkWindowPrivate *) window;
1551 if (window_private->destroyed)
1554 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1556 gdk_dnd.drag_numwindows++;
1557 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1558 gdk_dnd.drag_numwindows
1559 * sizeof(GdkWindow *));
1560 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1561 window_private->dnd_drag_accepted = 0;
1564 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1568 gdk_window_dnd_drag_set (GdkWindow *window,
1573 GdkWindowPrivate *window_private;
1576 g_return_if_fail (window != NULL);
1577 window_private = (GdkWindowPrivate *) window;
1578 if (window_private->destroyed)
1581 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1585 g_return_if_fail(typelist != NULL);
1587 if (window_private->dnd_drag_data_numtypesavail > 3)
1589 window_private->dnd_drag_data_numtypesavail = numtypes;
1591 window_private->dnd_drag_data_typesavail =
1592 g_realloc (window_private->dnd_drag_data_typesavail,
1593 (numtypes + 1) * sizeof (GdkAtom));
1595 for (i = 0; i < numtypes; i++)
1597 /* Allow blanket use of ALL to get anything... */
1598 if (strcmp (typelist[i], "ALL"))
1599 window_private->dnd_drag_data_typesavail[i] =
1600 gdk_atom_intern (typelist[i], FALSE);
1602 window_private->dnd_drag_data_typesavail[i] = None;
1606 * set our extended type list if we need to
1609 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1610 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1611 (guchar *)(window_private->dnd_drag_data_typesavail
1612 + (sizeof(GdkAtom) * 3)),
1613 (numtypes - 3) * sizeof(GdkAtom));
1615 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1619 g_free (window_private->dnd_drag_data_typesavail);
1620 window_private->dnd_drag_data_typesavail = NULL;
1621 window_private->dnd_drag_data_numtypesavail = 0;
1626 gdk_window_dnd_drop_set (GdkWindow *window,
1630 guint8 destructive_op)
1632 GdkWindowPrivate *window_private;
1635 g_return_if_fail (window != NULL);
1636 window_private = (GdkWindowPrivate *) window;
1637 if (window_private->destroyed)
1640 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1643 g_return_if_fail(typelist != NULL);
1645 window_private->dnd_drop_data_numtypesavail = numtypes;
1647 window_private->dnd_drop_data_typesavail =
1648 g_realloc (window_private->dnd_drop_data_typesavail,
1649 (numtypes + 1) * sizeof (GdkAtom));
1651 for (i = 0; i < numtypes; i++)
1652 window_private->dnd_drop_data_typesavail[i] =
1653 gdk_atom_intern (typelist[i], FALSE);
1655 window_private->dnd_drop_destructive_op = destructive_op;
1660 * This is used to reply to a GDK_DRAG_REQUEST event
1661 * (which may be generated by XdeRequest or a confirmed drop...
1664 gdk_window_dnd_data_set (GdkWindow *window,
1667 gulong data_numbytes)
1669 GdkWindowPrivate *window_private;
1671 GdkEventDropDataAvailable tmp_ev;
1674 g_return_if_fail (window != NULL);
1675 g_return_if_fail (event != NULL);
1676 g_return_if_fail (data != NULL);
1677 g_return_if_fail (data_numbytes > 0);
1678 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1680 window_private = (GdkWindowPrivate *) window;
1681 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1682 if (window_private->destroyed)
1685 /* We set the property on our window... */
1686 gdk_property_change (window, window_private->dnd_drag_data_type,
1687 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1689 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1691 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1696 * Then we send the event to tell the receiving window that the
1699 tmp_ev.u.allflags = 0;
1700 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1701 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1703 sev.xclient.type = ClientMessage;
1704 sev.xclient.format = 32;
1705 sev.xclient.window = event->dragrequest.requestor;
1706 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1707 sev.xclient.data.l[0] = window_private->xwindow;
1708 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1709 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1711 if (event->dragrequest.isdrop)
1712 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1713 (event->dragrequest.drop_coords.y << 16);
1715 sev.xclient.data.l[3] = 0;
1717 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1719 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1720 StructureNotifyMask, &sev))
1721 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1722 event->dragrequest.requestor));
1727 gdk_window_add_filter (GdkWindow *window,
1728 GdkFilterFunc function,
1731 GdkWindowPrivate *private;
1733 GdkEventFilter *filter;
1735 private = (GdkWindowPrivate*) window;
1736 if (private && private->destroyed)
1740 tmp_list = private->filters;
1742 tmp_list = gdk_default_filters;
1746 filter = (GdkEventFilter *)tmp_list->data;
1747 if ((filter->function == function) && (filter->data == data))
1749 tmp_list = tmp_list->next;
1752 filter = g_new (GdkEventFilter, 1);
1753 filter->function = function;
1754 filter->data = data;
1757 private->filters = g_list_append (private->filters, filter);
1759 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1763 gdk_window_remove_filter (GdkWindow *window,
1764 GdkFilterFunc function,
1767 GdkWindowPrivate *private;
1769 GdkEventFilter *filter;
1771 private = (GdkWindowPrivate*) window;
1774 tmp_list = private->filters;
1776 tmp_list = gdk_default_filters;
1780 filter = (GdkEventFilter *)tmp_list->data;
1781 tmp_list = tmp_list->next;
1783 if ((filter->function == function) && (filter->data == data))
1786 private->filters = g_list_remove_link (private->filters, tmp_list);
1788 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1789 g_list_free_1 (tmp_list);
1798 gdk_window_set_override_redirect(GdkWindow *window,
1799 gboolean override_redirect)
1801 GdkWindowPrivate *private;
1802 XSetWindowAttributes attr;
1804 g_return_if_fail (window != NULL);
1805 private = (GdkWindowPrivate*) window;
1806 if (private->destroyed)
1809 attr.override_redirect = (override_redirect == FALSE)?False:True;
1810 XChangeWindowAttributes(gdk_display,
1811 ((GdkWindowPrivate *)window)->xwindow,
1817 gdk_window_set_icon (GdkWindow *window,
1818 GdkWindow *icon_window,
1823 GdkWindowPrivate *window_private;
1824 GdkWindowPrivate *private;
1826 g_return_if_fail (window != NULL);
1827 window_private = (GdkWindowPrivate*) window;
1828 if (window_private->destroyed)
1833 if (icon_window != NULL)
1835 private = (GdkWindowPrivate *)icon_window;
1836 wm_hints.flags |= IconWindowHint;
1837 wm_hints.icon_window = private->xwindow;
1842 private = (GdkWindowPrivate *)pixmap;
1843 wm_hints.flags |= IconPixmapHint;
1844 wm_hints.icon_pixmap = private->xwindow;
1849 private = (GdkWindowPrivate *)mask;
1850 wm_hints.flags |= IconMaskHint;
1851 wm_hints.icon_mask = private->xwindow;
1854 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1858 gdk_window_set_icon_name (GdkWindow *window,
1861 GdkWindowPrivate *window_private;
1862 XTextProperty property;
1865 g_return_if_fail (window != NULL);
1866 window_private = (GdkWindowPrivate*) window;
1867 if (window_private->destroyed)
1869 res = XmbTextListToTextProperty (window_private->xdisplay,
1870 &name, 1, XStdICCTextStyle,
1874 g_warning("Error converting icon name to text property: %d\n", res);
1878 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1881 XFree(property.value);
1885 gdk_window_set_group (GdkWindow *window,
1889 GdkWindowPrivate *window_private;
1890 GdkWindowPrivate *private;
1892 g_return_if_fail (window != NULL);
1893 g_return_if_fail (leader != NULL);
1894 window_private = (GdkWindowPrivate*) window;
1895 if (window_private->destroyed)
1898 private = (GdkWindowPrivate *)leader;
1899 wm_hints.flags = WindowGroupHint;
1900 wm_hints.window_group = private->xwindow;
1902 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1906 gdk_window_set_mwm_hints (GdkWindow *window,
1907 MotifWmHints *new_hints)
1909 static Atom hints_atom = None;
1910 MotifWmHints *hints;
1916 GdkWindowPrivate *window_private;
1918 g_return_if_fail (window != NULL);
1919 window_private = (GdkWindowPrivate*) window;
1920 if (window_private->destroyed)
1924 hints_atom = XInternAtom (window_private->xdisplay,
1925 _XA_MOTIF_WM_HINTS, FALSE);
1927 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1928 hints_atom, 0, sizeof(MotifWmHints)/4,
1929 False, AnyPropertyType, &type, &format, &nitems,
1930 &bytes_after, (guchar **)&hints);
1936 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1938 hints->flags |= MWM_HINTS_FUNCTIONS;
1939 hints->functions = new_hints->functions;
1941 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1943 hints->flags |= MWM_HINTS_DECORATIONS;
1944 hints->decorations = new_hints->decorations;
1948 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1949 hints_atom, hints_atom, 32, PropModeReplace,
1950 (guchar *)hints, sizeof(MotifWmHints)/4);
1952 if (hints != new_hints)
1957 gdk_window_set_decorations (GdkWindow *window,
1958 GdkWMDecoration decorations)
1962 hints.flags = MWM_HINTS_DECORATIONS;
1963 hints.decorations = decorations;
1965 gdk_window_set_mwm_hints (window, &hints);
1969 gdk_window_set_functions (GdkWindow *window,
1970 GdkWMFunction functions)
1974 hints.flags = MWM_HINTS_FUNCTIONS;
1975 hints.functions = functions;
1977 gdk_window_set_mwm_hints (window, &hints);
1981 gdk_window_get_toplevels (void)
1983 GList *new_list = NULL;
1986 tmp_list = gdk_root_parent.children;
1989 new_list = g_list_prepend (new_list, tmp_list->data);
1990 tmp_list = tmp_list->next;