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 = 17;
37 int event_mask_table[19] =
41 PointerMotionHintMask,
46 ButtonPressMask | OwnerGrabButtonMask,
47 ButtonReleaseMask | OwnerGrabButtonMask,
61 /* internal function created for and used by gdk_window_xid_at_coords */
63 gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y,
64 GList *excludes, gboolean excl_child)
67 GdkWindowPrivate *private;
70 Window child=0,parent_win=0,root_win=0;
73 unsigned int ww, wh, wb, wd, num;
76 window=(GdkWindow*)&gdk_root_parent;
77 private=(GdkWindowPrivate*)window;
78 disp=private->xdisplay;
79 if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
82 if (!((x>=wx)&&(y>=wy)&&(x<(int)(wx+ww))&&(y<(int)(wy+wh))))
84 if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
90 if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
92 if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
106 * The following fucntion by The Rasterman <raster@redhat.com>
107 * This function returns the X Window ID in which the x y location is in
108 * (x and y being relative to the root window), excluding any windows listed
109 * in the GList excludes (this is a list of X Window ID's - gpointer being
112 * This is primarily designed for internal gdk use - for DND for example
113 * when using a shaped icon window as the drag object - you exclude the
114 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
115 * You can get back an X Window ID as to what X Window ID is infact under
116 * those X,Y co-ordinates.
119 gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
122 GdkWindowPrivate *private;
125 Window root,child=0,parent_win=0,root_win=0;
129 window=(GdkWindow*)&gdk_root_parent;
130 private=(GdkWindowPrivate*)window;
131 disp=private->xdisplay;
132 root=private->xwindow;
134 num=g_list_length(excludes);
135 if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
142 XWindowAttributes xwa;
144 XGetWindowAttributes (disp, list [i], &xwa);
146 if (xwa.map_state != IsViewable)
149 if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
152 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
157 if (!g_list_find(excludes,(gpointer *)child))
178 gdk_window_init (void)
180 XWindowAttributes xattributes;
183 unsigned int border_width;
187 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
188 &x, &y, &width, &height, &border_width, &depth);
189 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
191 gdk_root_parent.xdisplay = gdk_display;
192 gdk_root_parent.xwindow = gdk_root_window;
193 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
194 gdk_root_parent.window.user_data = NULL;
195 gdk_root_parent.width = width;
196 gdk_root_parent.height = height;
197 gdk_root_parent.children = NULL;
198 gdk_root_parent.colormap = NULL;
202 gdk_window_new (GdkWindow *parent,
203 GdkWindowAttr *attributes,
204 gint attributes_mask)
207 GdkWindowPrivate *private;
208 GdkWindowPrivate *parent_private;
210 Display *parent_display;
213 XSetWindowAttributes xattributes;
214 long xattributes_mask;
215 XSizeHints size_hints;
217 XClassHint *class_hint;
223 g_return_val_if_fail (attributes != NULL, NULL);
226 parent = (GdkWindow*) &gdk_root_parent;
228 parent_private = (GdkWindowPrivate*) parent;
229 if (parent_private->destroyed)
232 xparent = parent_private->xwindow;
233 parent_display = parent_private->xdisplay;
235 private = g_new (GdkWindowPrivate, 1);
236 window = (GdkWindow*) private;
238 private->parent = parent;
241 parent_private->children = g_list_prepend (parent_private->children, window);
243 private->xdisplay = parent_display;
244 private->destroyed = FALSE;
245 private->resize_count = 0;
246 private->ref_count = 1;
247 xattributes_mask = 0;
249 if (attributes_mask & GDK_WA_X)
254 if (attributes_mask & GDK_WA_Y)
261 private->width = (attributes->width > 1) ? (attributes->width) : (1);
262 private->height = (attributes->height > 1) ? (attributes->height) : (1);
263 private->window_type = attributes->window_type;
264 private->extension_events = FALSE;
265 private->dnd_drag_data_type = None;
266 private->dnd_drag_data_typesavail =
267 private->dnd_drop_data_typesavail = NULL;
268 private->dnd_drop_enabled = private->dnd_drag_enabled =
269 private->dnd_drag_accepted = private->dnd_drag_datashow =
270 private->dnd_drop_data_numtypesavail =
271 private->dnd_drag_data_numtypesavail = 0;
272 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
274 private->filters = NULL;
275 private->children = NULL;
277 window->user_data = NULL;
279 if (attributes_mask & GDK_WA_VISUAL)
280 visual = attributes->visual;
282 visual = gdk_visual_get_system ();
283 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
285 xattributes.event_mask = StructureNotifyMask;
286 for (i = 0; i < nevent_masks; i++)
288 if (attributes->event_mask & (1 << (i + 1)))
289 xattributes.event_mask |= event_mask_table[i];
292 if (xattributes.event_mask)
293 xattributes_mask |= CWEventMask;
295 if(attributes_mask & GDK_WA_NOREDIR) {
296 xattributes.override_redirect =
297 (attributes->override_redirect == FALSE)?False:True;
298 xattributes_mask |= CWOverrideRedirect;
300 xattributes.override_redirect = False;
302 if (attributes->wclass == GDK_INPUT_OUTPUT)
305 depth = visual->depth;
307 if (attributes_mask & GDK_WA_COLORMAP)
308 private->colormap = attributes->colormap;
310 private->colormap = gdk_colormap_get_system ();
312 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
313 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
314 xattributes_mask |= CWBorderPixel | CWBackPixel;
316 switch (private->window_type)
318 case GDK_WINDOW_TOPLEVEL:
319 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
320 xattributes_mask |= CWColormap;
322 xparent = gdk_root_window;
325 case GDK_WINDOW_CHILD:
326 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
327 xattributes_mask |= CWColormap;
330 case GDK_WINDOW_DIALOG:
331 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
332 xattributes_mask |= CWColormap;
334 xparent = gdk_root_window;
337 case GDK_WINDOW_TEMP:
338 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
339 xattributes_mask |= CWColormap;
341 xparent = gdk_root_window;
343 xattributes.save_under = True;
344 xattributes.override_redirect = True;
345 xattributes.cursor = None;
346 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
348 case GDK_WINDOW_ROOT:
349 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
351 case GDK_WINDOW_PIXMAP:
352 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
360 private->colormap = NULL;
363 private->xwindow = XCreateWindow (private->xdisplay, xparent,
364 x, y, private->width, private->height,
365 0, depth, class, xvisual,
366 xattributes_mask, &xattributes);
367 gdk_window_ref (window);
368 gdk_xid_table_insert (&private->xwindow, window);
370 if (private->colormap)
371 gdk_colormap_ref (private->colormap);
373 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
374 (attributes->cursor) :
377 switch (private->window_type)
379 case GDK_WINDOW_DIALOG:
380 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
381 case GDK_WINDOW_TOPLEVEL:
382 case GDK_WINDOW_TEMP:
383 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
385 case GDK_WINDOW_CHILD:
386 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
387 (private->colormap != gdk_colormap_get_system ()) &&
388 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
390 GDK_NOTE (MISC, g_print ("adding colormap window\n"));
391 gdk_window_add_colormap_windows (window);
400 size_hints.flags = PSize;
401 size_hints.width = private->width;
402 size_hints.height = private->height;
404 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
405 wm_hints.window_group = gdk_leader_window;
406 wm_hints.input = True;
407 wm_hints.initial_state = NormalState;
409 /* FIXME: Is there any point in doing this? Do any WM's pay
410 * attention to PSize, and even if they do, is this the
413 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
415 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
417 if (attributes_mask & GDK_WA_TITLE)
418 title = attributes->title;
420 title = gdk_progname;
422 XmbSetWMProperties (private->xdisplay, private->xwindow,
427 if (attributes_mask & GDK_WA_WMCLASS)
429 class_hint = XAllocClassHint ();
430 class_hint->res_name = attributes->wmclass_name;
431 class_hint->res_class = attributes->wmclass_class;
432 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
441 gdk_window_foreign_new (guint32 anid)
444 GdkWindowPrivate *private;
445 GdkWindowPrivate *parent_private;
446 XWindowAttributes attrs;
451 private = g_new (GdkWindowPrivate, 1);
452 window = (GdkWindow*) private;
454 XGetWindowAttributes (gdk_display, anid, &attrs);
456 /* FIXME: This is pretty expensive. Maybe the caller should supply
458 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
460 private->parent = gdk_xid_table_lookup (parent);
462 parent_private = (GdkWindowPrivate *)private->parent;
465 parent_private->children = g_list_prepend (parent_private->children, window);
467 private->xwindow = anid;
468 private->xdisplay = gdk_display;
469 private->x = attrs.x;
470 private->y = attrs.y;
471 private->width = attrs.width;
472 private->height = attrs.height;
473 private->resize_count = 0;
474 private->ref_count = 1;
475 private->window_type = GDK_WINDOW_FOREIGN;
476 private->destroyed = FALSE;
477 private->extension_events = 0;
479 private->colormap = NULL;
481 private->dnd_drag_data_type = None;
482 private->dnd_drag_data_typesavail =
483 private->dnd_drop_data_typesavail = NULL;
484 private->dnd_drop_enabled = private->dnd_drag_enabled =
485 private->dnd_drag_accepted = private->dnd_drag_datashow =
486 private->dnd_drop_data_numtypesavail =
487 private->dnd_drag_data_numtypesavail = 0;
488 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
490 private->filters = NULL;
491 private->children = NULL;
493 window->user_data = NULL;
495 gdk_window_ref (window);
496 gdk_xid_table_insert (&private->xwindow, window);
501 /* Call this function when you want a window and all its children to
502 disappear. When xdestroy is true, a request to destroy the XWindow
503 is sent out. When it is false, it is assumed that the XWindow has
504 been or will be destroyed by destroying some ancestor of this
508 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
509 gboolean our_destroy)
511 GdkWindowPrivate *private;
512 GdkWindowPrivate *temp_private;
513 GdkWindow *temp_window;
517 g_return_if_fail (window != NULL);
519 private = (GdkWindowPrivate*) window;
521 switch (private->window_type)
523 case GDK_WINDOW_TOPLEVEL:
524 case GDK_WINDOW_CHILD:
525 case GDK_WINDOW_DIALOG:
526 case GDK_WINDOW_TEMP:
527 case GDK_WINDOW_FOREIGN:
528 if (!private->destroyed)
532 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
533 if (parent_private->children)
534 parent_private->children = g_list_remove (parent_private->children, window);
537 if (private->window_type != GDK_WINDOW_FOREIGN)
539 children = tmp = private->children;
540 private->children = NULL;
544 temp_window = tmp->data;
547 temp_private = (GdkWindowPrivate*) temp_window;
549 gdk_window_internal_destroy (temp_window, FALSE,
553 g_list_free (children);
556 if (private->extension_events != 0)
557 gdk_input_window_destroy (window);
559 if(private->dnd_drag_data_numtypesavail > 0)
561 g_free (private->dnd_drag_data_typesavail);
562 private->dnd_drag_data_typesavail = NULL;
564 if(private->dnd_drop_data_numtypesavail > 0)
566 g_free (private->dnd_drop_data_typesavail);
567 private->dnd_drop_data_typesavail = NULL;
570 if (private->filters)
572 tmp = private->filters;
580 g_list_free (private->filters);
581 private->filters = NULL;
584 if (private->window_type == GDK_WINDOW_FOREIGN)
586 if (our_destroy && (private->parent != NULL))
588 /* It's somebody elses window, but in our heirarchy,
589 * so reparent it to the root window, and then send
590 * it a delete event, as if we were a WM
592 XClientMessageEvent xevent;
594 gdk_window_hide (window);
595 gdk_window_reparent (window, NULL, 0, 0);
597 xevent.type = ClientMessage;
598 xevent.window = private->xwindow;
599 xevent.message_type = gdk_wm_protocols;
601 xevent.data.l[0] = gdk_wm_delete_window;
602 xevent.data.l[1] = CurrentTime;
604 XSendEvent (private->xdisplay, private->xwindow,
605 False, 0, (XEvent *)&xevent);
609 XDestroyWindow (private->xdisplay, private->xwindow);
611 if (private->colormap)
612 gdk_colormap_unref (private->colormap);
614 private->destroyed = TRUE;
618 case GDK_WINDOW_ROOT:
619 g_error ("attempted to destroy root window");
622 case GDK_WINDOW_PIXMAP:
623 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
628 /* Like internal_destroy, but also destroys the reference created by
632 gdk_window_destroy (GdkWindow *window)
634 gdk_window_internal_destroy (window, TRUE, TRUE);
635 gdk_window_unref (window);
638 /* This function is called when the XWindow is really gone. */
641 gdk_window_destroy_notify (GdkWindow *window)
643 GdkWindowPrivate *private;
645 g_return_if_fail (window != NULL);
647 private = (GdkWindowPrivate*) window;
649 if (!private->destroyed)
651 if (private->window_type == GDK_WINDOW_FOREIGN)
652 gdk_window_internal_destroy (window, FALSE, FALSE);
654 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
657 gdk_xid_table_remove (private->xwindow);
658 gdk_window_unref (window);
662 gdk_window_ref (GdkWindow *window)
664 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
665 g_return_val_if_fail (window != NULL, NULL);
667 private->ref_count += 1;
672 gdk_window_unref (GdkWindow *window)
674 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
675 g_return_if_fail (window != NULL);
677 private->ref_count -= 1;
678 if (private->ref_count == 0)
680 if (!private->destroyed)
681 g_warning ("losing last reference to undestroyed window\n");
687 gdk_window_show (GdkWindow *window)
689 GdkWindowPrivate *private;
691 g_return_if_fail (window != NULL);
693 private = (GdkWindowPrivate*) window;
694 if (!private->destroyed)
696 XRaiseWindow (private->xdisplay, private->xwindow);
697 XMapWindow (private->xdisplay, private->xwindow);
702 gdk_window_hide (GdkWindow *window)
704 GdkWindowPrivate *private;
706 g_return_if_fail (window != NULL);
708 private = (GdkWindowPrivate*) window;
709 if (!private->destroyed)
710 XUnmapWindow (private->xdisplay, private->xwindow);
714 gdk_window_withdraw (GdkWindow *window)
716 GdkWindowPrivate *private;
718 g_return_if_fail (window != NULL);
720 private = (GdkWindowPrivate*) window;
721 if (!private->destroyed)
722 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
726 gdk_window_move (GdkWindow *window,
730 GdkWindowPrivate *private;
732 g_return_if_fail (window != NULL);
734 private = (GdkWindowPrivate*) window;
735 if (!private->destroyed)
737 XMoveWindow (private->xdisplay, private->xwindow, x, y);
739 if (private->window_type == GDK_WINDOW_CHILD)
748 gdk_window_resize (GdkWindow *window,
752 GdkWindowPrivate *private;
754 g_return_if_fail (window != NULL);
761 private = (GdkWindowPrivate*) window;
763 if (!private->destroyed &&
764 ((private->resize_count > 0) ||
765 (private->width != (guint16) width) ||
766 (private->height != (guint16) height)))
768 XResizeWindow (private->xdisplay, private->xwindow, width, height);
769 private->resize_count += 1;
771 if (private->window_type == GDK_WINDOW_CHILD)
773 private->width = width;
774 private->height = height;
780 gdk_window_move_resize (GdkWindow *window,
786 GdkWindowPrivate *private;
788 g_return_if_fail (window != NULL);
795 private = (GdkWindowPrivate*) window;
796 if (!private->destroyed)
798 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
800 if (private->window_type == GDK_WINDOW_CHILD)
804 private->width = width;
805 private->height = height;
811 gdk_window_reparent (GdkWindow *window,
812 GdkWindow *new_parent,
816 GdkWindowPrivate *window_private;
817 GdkWindowPrivate *parent_private;
819 g_return_if_fail (window != NULL);
822 new_parent = (GdkWindow*) &gdk_root_parent;
824 window_private = (GdkWindowPrivate*) window;
825 parent_private = (GdkWindowPrivate*) new_parent;
827 if (!window_private->destroyed && !parent_private->destroyed)
828 XReparentWindow (window_private->xdisplay,
829 window_private->xwindow,
830 parent_private->xwindow,
835 gdk_window_clear (GdkWindow *window)
837 GdkWindowPrivate *private;
839 g_return_if_fail (window != NULL);
841 private = (GdkWindowPrivate*) window;
843 if (!private->destroyed)
844 XClearWindow (private->xdisplay, private->xwindow);
848 gdk_window_clear_area (GdkWindow *window,
854 GdkWindowPrivate *private;
856 g_return_if_fail (window != NULL);
858 private = (GdkWindowPrivate*) window;
860 if (!private->destroyed)
861 XClearArea (private->xdisplay, private->xwindow,
862 x, y, width, height, False);
866 gdk_window_clear_area_e (GdkWindow *window,
872 GdkWindowPrivate *private;
874 g_return_if_fail (window != NULL);
876 private = (GdkWindowPrivate*) window;
878 if (!private->destroyed)
879 XClearArea (private->xdisplay, private->xwindow,
880 x, y, width, height, True);
884 gdk_window_copy_area (GdkWindow *window,
888 GdkWindow *source_window,
894 GdkWindowPrivate *src_private;
895 GdkWindowPrivate *dest_private;
896 GdkGCPrivate *gc_private;
898 g_return_if_fail (window != NULL);
899 g_return_if_fail (gc != NULL);
901 if (source_window == NULL)
902 source_window = window;
904 src_private = (GdkWindowPrivate*) source_window;
905 dest_private = (GdkWindowPrivate*) window;
906 gc_private = (GdkGCPrivate*) gc;
908 if (!src_private->destroyed && !dest_private->destroyed)
910 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
919 gdk_window_raise (GdkWindow *window)
921 GdkWindowPrivate *private;
923 g_return_if_fail (window != NULL);
925 private = (GdkWindowPrivate*) window;
927 if (!private->destroyed)
928 XRaiseWindow (private->xdisplay, private->xwindow);
932 gdk_window_lower (GdkWindow *window)
934 GdkWindowPrivate *private;
936 g_return_if_fail (window != NULL);
938 private = (GdkWindowPrivate*) window;
940 if (!private->destroyed)
941 XLowerWindow (private->xdisplay, private->xwindow);
945 gdk_window_set_user_data (GdkWindow *window,
948 g_return_if_fail (window != NULL);
950 window->user_data = user_data;
954 gdk_window_set_hints (GdkWindow *window,
963 GdkWindowPrivate *private;
964 XSizeHints size_hints;
966 g_return_if_fail (window != NULL);
968 private = (GdkWindowPrivate*) window;
969 if (private->destroyed)
972 size_hints.flags = 0;
974 if (flags & GDK_HINT_POS)
976 size_hints.flags |= PPosition;
981 if (flags & GDK_HINT_MIN_SIZE)
983 size_hints.flags |= PMinSize;
984 size_hints.min_width = min_width;
985 size_hints.min_height = min_height;
988 if (flags & GDK_HINT_MAX_SIZE)
990 size_hints.flags |= PMaxSize;
991 size_hints.max_width = max_width;
992 size_hints.max_height = max_height;
996 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
1000 gdk_window_set_title (GdkWindow *window,
1003 GdkWindowPrivate *private;
1005 g_return_if_fail (window != NULL);
1007 private = (GdkWindowPrivate*) window;
1008 if (!private->destroyed)
1009 XmbSetWMProperties (private->xdisplay, private->xwindow,
1010 title, title, NULL, 0, NULL, NULL, NULL);
1014 gdk_window_set_background (GdkWindow *window,
1017 GdkWindowPrivate *private;
1019 g_return_if_fail (window != NULL);
1021 private = (GdkWindowPrivate*) window;
1022 if (!private->destroyed)
1023 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1027 gdk_window_set_back_pixmap (GdkWindow *window,
1029 gint parent_relative)
1031 GdkWindowPrivate *window_private;
1032 GdkPixmapPrivate *pixmap_private;
1035 g_return_if_fail (window != NULL);
1037 window_private = (GdkWindowPrivate*) window;
1038 pixmap_private = (GdkPixmapPrivate*) pixmap;
1041 xpixmap = pixmap_private->xwindow;
1045 if (parent_relative)
1046 xpixmap = ParentRelative;
1048 if (!window_private->destroyed)
1049 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1053 gdk_window_set_cursor (GdkWindow *window,
1056 GdkWindowPrivate *window_private;
1057 GdkCursorPrivate *cursor_private;
1060 g_return_if_fail (window != NULL);
1062 window_private = (GdkWindowPrivate*) window;
1063 cursor_private = (GdkCursorPrivate*) cursor;
1068 xcursor = cursor_private->xcursor;
1070 if (!window_private->destroyed)
1071 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1075 gdk_window_set_colormap (GdkWindow *window,
1076 GdkColormap *colormap)
1078 GdkWindowPrivate *window_private;
1079 GdkColormapPrivate *colormap_private;
1081 g_return_if_fail (window != NULL);
1082 g_return_if_fail (colormap != NULL);
1084 window_private = (GdkWindowPrivate*) window;
1085 colormap_private = (GdkColormapPrivate*) colormap;
1087 if (!window_private->destroyed)
1089 XSetWindowColormap (window_private->xdisplay,
1090 window_private->xwindow,
1091 colormap_private->xcolormap);
1093 if (window_private->colormap)
1094 gdk_colormap_unref (window_private->colormap);
1095 window_private->colormap = colormap;
1096 gdk_colormap_ref (window_private->colormap);
1098 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1099 gdk_window_add_colormap_windows (window);
1104 gdk_window_get_user_data (GdkWindow *window,
1107 g_return_if_fail (window != NULL);
1109 *data = window->user_data;
1113 gdk_window_get_geometry (GdkWindow *window,
1120 GdkWindowPrivate *window_private;
1126 guint tborder_width;
1130 window = (GdkWindow*) &gdk_root_parent;
1132 window_private = (GdkWindowPrivate*) window;
1134 if (!window_private->destroyed)
1136 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1137 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1153 gdk_window_get_position (GdkWindow *window,
1157 GdkWindowPrivate *window_private;
1159 g_return_if_fail (window != NULL);
1161 window_private = (GdkWindowPrivate*) window;
1164 *x = window_private->x;
1166 *y = window_private->y;
1170 gdk_window_get_size (GdkWindow *window,
1174 GdkWindowPrivate *window_private;
1176 g_return_if_fail (window != NULL);
1178 window_private = (GdkWindowPrivate*) window;
1181 *width = window_private->width;
1183 *height = window_private->height;
1187 gdk_window_get_visual (GdkWindow *window)
1189 GdkWindowPrivate *window_private;
1190 XWindowAttributes window_attributes;
1192 g_return_val_if_fail (window != NULL, NULL);
1194 window_private = (GdkWindowPrivate*) window;
1195 /* Huh? ->parent is never set for a pixmap. We should just return
1198 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1199 window_private = (GdkWindowPrivate*) window_private->parent;
1201 if (window_private && !window_private->destroyed)
1203 if (window_private->colormap == NULL)
1205 XGetWindowAttributes (window_private->xdisplay,
1206 window_private->xwindow,
1207 &window_attributes);
1208 return gdk_visual_lookup (window_attributes.visual);
1211 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1218 gdk_window_get_colormap (GdkWindow *window)
1220 GdkWindowPrivate *window_private;
1221 XWindowAttributes window_attributes;
1223 g_return_val_if_fail (window != NULL, NULL);
1224 window_private = (GdkWindowPrivate*) window;
1226 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1227 if (!window_private->destroyed)
1229 if (window_private->colormap == NULL)
1231 XGetWindowAttributes (window_private->xdisplay,
1232 window_private->xwindow,
1233 &window_attributes);
1234 return gdk_colormap_lookup (window_attributes.colormap);
1237 return window_private->colormap;
1244 gdk_window_get_type (GdkWindow *window)
1246 GdkWindowPrivate *window_private;
1248 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1250 window_private = (GdkWindowPrivate*) window;
1251 return window_private->window_type;
1255 gdk_window_get_origin (GdkWindow *window,
1259 GdkWindowPrivate *private;
1264 g_return_val_if_fail (window != NULL, 0);
1266 private = (GdkWindowPrivate*) window;
1268 if (!private->destroyed)
1270 return_val = XTranslateCoordinates (private->xdisplay,
1288 gdk_window_get_pointer (GdkWindow *window,
1291 GdkModifierType *mask)
1293 GdkWindowPrivate *private;
1294 GdkWindow *return_val;
1302 window = (GdkWindow*) &gdk_root_parent;
1304 private = (GdkWindowPrivate*) window;
1307 if (!private->destroyed &&
1308 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1309 &rootx, &rooty, &winx, &winy, &xmask))
1313 if (mask) *mask = xmask;
1316 return_val = gdk_window_lookup (child);
1323 gdk_window_get_parent (GdkWindow *window)
1325 g_return_val_if_fail (window != NULL, NULL);
1327 return ((GdkWindowPrivate*) window)->parent;
1331 gdk_window_get_toplevel (GdkWindow *window)
1333 GdkWindowPrivate *private;
1335 g_return_val_if_fail (window != NULL, NULL);
1337 private = (GdkWindowPrivate*) window;
1339 while (private->window_type == GDK_WINDOW_CHILD)
1341 window = ((GdkWindowPrivate*) window)->parent;
1342 private = (GdkWindowPrivate*) window;
1349 gdk_window_get_children (GdkWindow *window)
1351 GdkWindowPrivate *private;
1357 unsigned int nchildren;
1360 g_return_val_if_fail (window != NULL, NULL);
1362 private = (GdkWindowPrivate*) window;
1363 if (private->destroyed)
1366 XQueryTree (private->xdisplay, private->xwindow,
1367 &root, &parent, &xchildren, &nchildren);
1373 for (i = 0; i < nchildren; i++)
1375 child = gdk_window_lookup (xchildren[i]);
1377 children = g_list_prepend (children, child);
1387 gdk_window_get_events (GdkWindow *window)
1389 GdkWindowPrivate *private;
1390 XWindowAttributes attrs;
1391 GdkEventMask event_mask;
1394 g_return_val_if_fail (window != NULL, 0);
1396 private = (GdkWindowPrivate*) window;
1397 if (private->destroyed)
1400 XGetWindowAttributes (gdk_display, private->xwindow,
1404 for (i = 0; i < nevent_masks; i++)
1406 if (attrs.your_event_mask & event_mask_table[i])
1407 event_mask |= 1 << (i + 1);
1414 gdk_window_set_events (GdkWindow *window,
1415 GdkEventMask event_mask)
1417 GdkWindowPrivate *private;
1421 g_return_if_fail (window != NULL);
1423 private = (GdkWindowPrivate*) window;
1424 if (private->destroyed)
1427 xevent_mask = StructureNotifyMask;
1428 for (i = 0; i < nevent_masks; i++)
1430 if (event_mask & (1 << (i + 1)))
1431 xevent_mask |= event_mask_table[i];
1434 XSelectInput (gdk_display, private->xwindow,
1439 gdk_window_add_colormap_windows (GdkWindow *window)
1441 GdkWindow *toplevel;
1442 GdkWindowPrivate *toplevel_private;
1443 GdkWindowPrivate *window_private;
1444 Window *old_windows;
1445 Window *new_windows;
1448 g_return_if_fail (window != NULL);
1450 toplevel = gdk_window_get_toplevel (window);
1451 toplevel_private = (GdkWindowPrivate*) toplevel;
1452 window_private = (GdkWindowPrivate*) window;
1453 if (window_private->destroyed)
1456 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1457 toplevel_private->xwindow,
1458 &old_windows, &count))
1464 for (i = 0; i < count; i++)
1465 if (old_windows[i] == window_private->xwindow)
1468 new_windows = g_new (Window, count + 1);
1470 for (i = 0; i < count; i++)
1471 new_windows[i] = old_windows[i];
1472 new_windows[count] = window_private->xwindow;
1474 XSetWMColormapWindows (toplevel_private->xdisplay,
1475 toplevel_private->xwindow,
1476 new_windows, count + 1);
1478 g_free (new_windows);
1480 XFree (old_windows);
1484 * This needs the X11 shape extension.
1485 * If not available, shaped windows will look
1486 * ugly, but programs still work. Stefan Wille
1489 gdk_window_shape_combine_mask (GdkWindow *window,
1493 enum { UNKNOWN, NO, YES };
1495 static gint have_shape = UNKNOWN;
1497 GdkWindowPrivate *window_private;
1500 g_return_if_fail (window != NULL);
1502 #ifdef HAVE_SHAPE_EXT
1503 if (have_shape == UNKNOWN)
1506 if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1512 if (have_shape == YES)
1514 window_private = (GdkWindowPrivate*) window;
1515 if (window_private->destroyed)
1520 GdkWindowPrivate *pixmap_private;
1522 pixmap_private = (GdkWindowPrivate*) mask;
1523 pixmap = (Pixmap) pixmap_private->xwindow;
1532 XShapeCombineMask (window_private->xdisplay,
1533 window_private->xwindow,
1539 #endif /* HAVE_SHAPE_EXT */
1543 gdk_dnd_drag_addwindow (GdkWindow *window)
1545 GdkWindowPrivate *window_private;
1547 g_return_if_fail (window != NULL);
1549 window_private = (GdkWindowPrivate *) window;
1550 if (window_private->destroyed)
1553 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1555 gdk_dnd.drag_numwindows++;
1556 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1557 gdk_dnd.drag_numwindows
1558 * sizeof(GdkWindow *));
1559 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1560 window_private->dnd_drag_accepted = 0;
1563 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1567 gdk_window_dnd_drag_set (GdkWindow *window,
1572 GdkWindowPrivate *window_private;
1575 g_return_if_fail (window != NULL);
1576 window_private = (GdkWindowPrivate *) window;
1577 if (window_private->destroyed)
1580 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1584 g_return_if_fail(typelist != NULL);
1586 if (window_private->dnd_drag_data_numtypesavail > 3)
1588 window_private->dnd_drag_data_numtypesavail = numtypes;
1590 window_private->dnd_drag_data_typesavail =
1591 g_realloc (window_private->dnd_drag_data_typesavail,
1592 (numtypes + 1) * sizeof (GdkAtom));
1594 for (i = 0; i < numtypes; i++)
1596 /* Allow blanket use of ALL to get anything... */
1597 if (strcmp (typelist[i], "ALL"))
1598 window_private->dnd_drag_data_typesavail[i] =
1599 gdk_atom_intern (typelist[i], FALSE);
1601 window_private->dnd_drag_data_typesavail[i] = None;
1605 * set our extended type list if we need to
1608 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1609 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1610 (guchar *)(window_private->dnd_drag_data_typesavail
1611 + (sizeof(GdkAtom) * 3)),
1612 (numtypes - 3) * sizeof(GdkAtom));
1614 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1618 g_free (window_private->dnd_drag_data_typesavail);
1619 window_private->dnd_drag_data_typesavail = NULL;
1620 window_private->dnd_drag_data_numtypesavail = 0;
1625 gdk_window_dnd_drop_set (GdkWindow *window,
1629 guint8 destructive_op)
1631 GdkWindowPrivate *window_private;
1634 g_return_if_fail (window != NULL);
1635 window_private = (GdkWindowPrivate *) window;
1636 if (window_private->destroyed)
1639 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1642 g_return_if_fail(typelist != NULL);
1644 window_private->dnd_drop_data_numtypesavail = numtypes;
1646 window_private->dnd_drop_data_typesavail =
1647 g_realloc (window_private->dnd_drop_data_typesavail,
1648 (numtypes + 1) * sizeof (GdkAtom));
1650 for (i = 0; i < numtypes; i++)
1651 window_private->dnd_drop_data_typesavail[i] =
1652 gdk_atom_intern (typelist[i], FALSE);
1654 window_private->dnd_drop_destructive_op = destructive_op;
1659 * This is used to reply to a GDK_DRAG_REQUEST event
1660 * (which may be generated by XdeRequest or a confirmed drop...
1663 gdk_window_dnd_data_set (GdkWindow *window,
1666 gulong data_numbytes)
1668 GdkWindowPrivate *window_private;
1670 GdkEventDropDataAvailable tmp_ev;
1673 g_return_if_fail (window != NULL);
1674 g_return_if_fail (event != NULL);
1675 g_return_if_fail (data != NULL);
1676 g_return_if_fail (data_numbytes > 0);
1677 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1679 window_private = (GdkWindowPrivate *) window;
1680 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1681 if (window_private->destroyed)
1684 /* We set the property on our window... */
1685 gdk_property_change (window, window_private->dnd_drag_data_type,
1686 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1688 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1690 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1695 * Then we send the event to tell the receiving window that the
1698 tmp_ev.u.allflags = 0;
1699 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1700 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1702 sev.xclient.type = ClientMessage;
1703 sev.xclient.format = 32;
1704 sev.xclient.window = event->dragrequest.requestor;
1705 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1706 sev.xclient.data.l[0] = window_private->xwindow;
1707 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1708 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1710 if (event->dragrequest.isdrop)
1711 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1712 (event->dragrequest.drop_coords.y << 16);
1714 sev.xclient.data.l[3] = 0;
1716 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1718 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1719 StructureNotifyMask, &sev))
1720 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1721 event->dragrequest.requestor));
1726 gdk_window_add_filter (GdkWindow *window,
1727 GdkFilterFunc function,
1730 GdkWindowPrivate *private;
1732 GdkEventFilter *filter;
1734 private = (GdkWindowPrivate*) window;
1735 if (private && private->destroyed)
1739 tmp_list = private->filters;
1741 tmp_list = gdk_default_filters;
1745 filter = (GdkEventFilter *)tmp_list->data;
1746 if ((filter->function == function) && (filter->data == data))
1748 tmp_list = tmp_list->next;
1751 filter = g_new (GdkEventFilter, 1);
1752 filter->function = function;
1753 filter->data = data;
1756 private->filters = g_list_append (private->filters, filter);
1758 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1762 gdk_window_remove_filter (GdkWindow *window,
1763 GdkFilterFunc function,
1766 GdkWindowPrivate *private;
1768 GdkEventFilter *filter;
1770 private = (GdkWindowPrivate*) window;
1773 tmp_list = private->filters;
1775 tmp_list = gdk_default_filters;
1779 filter = (GdkEventFilter *)tmp_list->data;
1780 tmp_list = tmp_list->next;
1782 if ((filter->function == function) && (filter->data == data))
1785 private->filters = g_list_remove_link (private->filters, tmp_list);
1787 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1788 g_list_free_1 (tmp_list);
1797 gdk_window_set_override_redirect(GdkWindow *window,
1798 gboolean override_redirect)
1800 GdkWindowPrivate *private;
1801 XSetWindowAttributes attr;
1803 g_return_if_fail (window != NULL);
1804 private = (GdkWindowPrivate*) window;
1805 if (private->destroyed)
1808 attr.override_redirect = (override_redirect == FALSE)?False:True;
1809 XChangeWindowAttributes(gdk_display,
1810 ((GdkWindowPrivate *)window)->xwindow,
1816 gdk_window_set_icon (GdkWindow *window,
1817 GdkWindow *icon_window,
1822 GdkWindowPrivate *window_private;
1823 GdkWindowPrivate *private;
1825 g_return_if_fail (window != NULL);
1826 window_private = (GdkWindowPrivate*) window;
1827 if (window_private->destroyed)
1832 if (icon_window != NULL)
1834 private = (GdkWindowPrivate *)icon_window;
1835 wm_hints.flags |= IconWindowHint;
1836 wm_hints.icon_window = private->xwindow;
1841 private = (GdkWindowPrivate *)pixmap;
1842 wm_hints.flags |= IconPixmapHint;
1843 wm_hints.icon_pixmap = private->xwindow;
1848 private = (GdkWindowPrivate *)mask;
1849 wm_hints.flags |= IconMaskHint;
1850 wm_hints.icon_mask = private->xwindow;
1853 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1857 gdk_window_set_icon_name (GdkWindow *window,
1860 GdkWindowPrivate *window_private;
1861 XTextProperty property;
1864 g_return_if_fail (window != NULL);
1865 window_private = (GdkWindowPrivate*) window;
1866 if (window_private->destroyed)
1868 res = XmbTextListToTextProperty (window_private->xdisplay,
1869 &name, 1, XStdICCTextStyle,
1873 g_warning("Error converting icon name to text property: %d\n", res);
1877 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1880 XFree(property.value);
1884 gdk_window_set_group (GdkWindow *window,
1888 GdkWindowPrivate *window_private;
1889 GdkWindowPrivate *private;
1891 g_return_if_fail (window != NULL);
1892 g_return_if_fail (leader != NULL);
1893 window_private = (GdkWindowPrivate*) window;
1894 if (window_private->destroyed)
1897 private = (GdkWindowPrivate *)leader;
1898 wm_hints.flags = WindowGroupHint;
1899 wm_hints.window_group = private->xwindow;
1901 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1905 gdk_window_set_mwm_hints (GdkWindow *window,
1906 MotifWmHints *new_hints)
1908 static Atom hints_atom = None;
1909 MotifWmHints *hints;
1915 GdkWindowPrivate *window_private;
1917 g_return_if_fail (window != NULL);
1918 window_private = (GdkWindowPrivate*) window;
1919 if (window_private->destroyed)
1923 hints_atom = XInternAtom (window_private->xdisplay,
1924 _XA_MOTIF_WM_HINTS, FALSE);
1926 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1927 hints_atom, 0, sizeof(MotifWmHints)/4,
1928 False, AnyPropertyType, &type, &format, &nitems,
1929 &bytes_after, (guchar **)&hints);
1935 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1937 hints->flags |= MWM_HINTS_FUNCTIONS;
1938 hints->functions = new_hints->functions;
1940 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1942 hints->flags |= MWM_HINTS_DECORATIONS;
1943 hints->decorations = new_hints->decorations;
1947 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1948 hints_atom, hints_atom, 32, PropModeReplace,
1949 (guchar *)hints, sizeof(MotifWmHints)/4);
1951 if (hints != new_hints)
1956 gdk_window_set_decorations (GdkWindow *window,
1957 GdkWMDecoration decorations)
1961 hints.flags = MWM_HINTS_DECORATIONS;
1962 hints.decorations = decorations;
1964 gdk_window_set_mwm_hints (window, &hints);
1968 gdk_window_set_functions (GdkWindow *window,
1969 GdkWMFunction functions)
1973 hints.flags = MWM_HINTS_FUNCTIONS;
1974 hints.functions = functions;
1976 gdk_window_set_mwm_hints (window, &hints);
1980 gdk_window_get_toplevels (void)
1982 GList *new_list = NULL;
1985 tmp_list = gdk_root_parent.children;
1988 new_list = g_list_prepend (new_list, tmp_list->data);
1989 tmp_list = tmp_list->next;