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 <X11/extensions/shape.h>
24 #include <netinet/in.h>
26 #include "../config.h"
28 #include "gdkprivate.h"
33 int nevent_masks = 17;
34 int event_mask_table[19] =
38 PointerMotionHintMask,
43 ButtonPressMask | OwnerGrabButtonMask,
44 ButtonReleaseMask | OwnerGrabButtonMask,
58 /* internal function created for and used by gdk_window_xid_at_coords */
60 gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y,
61 GList *excludes, gboolean excl_child)
64 GdkWindowPrivate *private;
67 Window child=0,parent_win=0,root_win=0;
70 unsigned int ww, wh, wb, wd, num;
73 window=(GdkWindow*)&gdk_root_parent;
74 private=(GdkWindowPrivate*)window;
75 disp=private->xdisplay;
76 if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
79 if (!((x>=wx)&&(y>=wy)&&(x<(int)(wx+ww))&&(y<(int)(wy+wh))))
81 if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
87 if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
89 if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
103 * The following fucntion by The Rasterman <raster@redhat.com>
104 * This function returns the X Window ID in which the x y location is in
105 * (x and y being relative to the root window), excluding any windows listed
106 * in the GList excludes (this is a list of X Window ID's - gpointer being
109 * This is primarily designed for internal gdk use - for DND for example
110 * when using a shaped icon window as the drag object - you exclude the
111 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
112 * You can get back an X Window ID as to what X Window ID is infact under
113 * those X,Y co-ordinates.
116 gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
119 GdkWindowPrivate *private;
122 Window root,child=0,parent_win=0,root_win=0;
126 window=(GdkWindow*)&gdk_root_parent;
127 private=(GdkWindowPrivate*)window;
128 disp=private->xdisplay;
129 root=private->xwindow;
131 num=g_list_length(excludes);
132 if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
139 XWindowAttributes xwa;
141 XGetWindowAttributes (disp, list [i], &xwa);
143 if (xwa.map_state != IsViewable)
146 if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
149 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
154 if (!g_list_find(excludes,(gpointer *)child))
177 XWindowAttributes xattributes;
180 unsigned int border_width;
184 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
185 &x, &y, &width, &height, &border_width, &depth);
186 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
188 gdk_root_parent.xdisplay = gdk_display;
189 gdk_root_parent.xwindow = gdk_root_window;
190 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
191 gdk_root_parent.window.user_data = NULL;
192 gdk_root_parent.width = width;
193 gdk_root_parent.height = height;
194 gdk_root_parent.children = NULL;
198 gdk_window_new (GdkWindow *parent,
199 GdkWindowAttr *attributes,
200 gint attributes_mask)
203 GdkWindowPrivate *private;
204 GdkWindowPrivate *parent_private;
206 Display *parent_display;
209 XSetWindowAttributes xattributes;
210 long xattributes_mask;
211 XSizeHints size_hints;
213 XClassHint *class_hint;
219 g_return_val_if_fail (attributes != NULL, NULL);
222 parent = (GdkWindow*) &gdk_root_parent;
224 parent_private = (GdkWindowPrivate*) parent;
225 if (parent_private->destroyed)
228 xparent = parent_private->xwindow;
229 parent_display = parent_private->xdisplay;
231 private = g_new (GdkWindowPrivate, 1);
232 window = (GdkWindow*) private;
234 private->parent = parent;
236 if (parent_private != &gdk_root_parent)
237 parent_private->children = g_list_prepend (parent_private->children, window);
239 private->xdisplay = parent_display;
240 private->destroyed = FALSE;
241 private->resize_count = 0;
242 private->ref_count = 1;
243 xattributes_mask = 0;
245 if (attributes_mask & GDK_WA_X)
250 if (attributes_mask & GDK_WA_Y)
257 private->width = (attributes->width > 1) ? (attributes->width) : (1);
258 private->height = (attributes->height > 1) ? (attributes->height) : (1);
259 private->window_type = attributes->window_type;
260 private->extension_events = FALSE;
261 private->dnd_drag_data_type = None;
262 private->dnd_drag_data_typesavail =
263 private->dnd_drop_data_typesavail = NULL;
264 private->dnd_drop_enabled = private->dnd_drag_enabled =
265 private->dnd_drag_accepted = private->dnd_drag_datashow =
266 private->dnd_drop_data_numtypesavail =
267 private->dnd_drag_data_numtypesavail = 0;
268 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
270 private->filters = NULL;
271 private->children = NULL;
273 window->user_data = NULL;
275 if (attributes_mask & GDK_WA_VISUAL)
276 visual = attributes->visual;
278 visual = gdk_visual_get_system ();
279 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
281 xattributes.event_mask = StructureNotifyMask;
282 for (i = 0; i < nevent_masks; i++)
284 if (attributes->event_mask & (1 << (i + 1)))
285 xattributes.event_mask |= event_mask_table[i];
288 if (xattributes.event_mask)
289 xattributes_mask |= CWEventMask;
291 if(attributes_mask & GDK_WA_NOREDIR) {
292 xattributes.override_redirect =
293 (attributes->override_redirect == FALSE)?False:True;
294 xattributes_mask |= CWOverrideRedirect;
296 xattributes.override_redirect = False;
298 if (attributes->wclass == GDK_INPUT_OUTPUT)
301 depth = visual->depth;
303 if (attributes_mask & GDK_WA_COLORMAP)
304 private->colormap = attributes->colormap;
306 private->colormap = gdk_colormap_get_system ();
308 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
309 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
310 xattributes_mask |= CWBorderPixel | CWBackPixel;
312 switch (private->window_type)
314 case GDK_WINDOW_TOPLEVEL:
315 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
316 xattributes_mask |= CWColormap;
318 xparent = gdk_root_window;
321 case GDK_WINDOW_CHILD:
322 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
323 xattributes_mask |= CWColormap;
326 case GDK_WINDOW_DIALOG:
327 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
328 xattributes_mask |= CWColormap;
330 xparent = gdk_root_window;
333 case GDK_WINDOW_TEMP:
334 xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
335 xattributes_mask |= CWColormap;
337 xparent = gdk_root_window;
339 xattributes.save_under = True;
340 xattributes.override_redirect = True;
341 xattributes.cursor = None;
342 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
344 case GDK_WINDOW_ROOT:
345 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
347 case GDK_WINDOW_PIXMAP:
348 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
356 private->colormap = NULL;
359 private->xwindow = XCreateWindow (private->xdisplay, xparent,
360 x, y, private->width, private->height,
361 0, depth, class, xvisual,
362 xattributes_mask, &xattributes);
363 gdk_window_ref (window);
364 gdk_xid_table_insert (&private->xwindow, window);
366 if (private->colormap)
367 gdk_colormap_ref (private->colormap);
369 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
370 (attributes->cursor) :
373 switch (private->window_type)
375 case GDK_WINDOW_DIALOG:
376 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
377 case GDK_WINDOW_TOPLEVEL:
378 case GDK_WINDOW_TEMP:
379 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
381 case GDK_WINDOW_CHILD:
382 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
383 (private->colormap != gdk_colormap_get_system ()) &&
384 (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
386 GDK_NOTE (MISC, g_print ("adding colormap window\n"));
387 gdk_window_add_colormap_windows (window);
396 size_hints.flags = PSize;
397 size_hints.width = private->width;
398 size_hints.height = private->height;
400 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
401 wm_hints.window_group = gdk_leader_window;
402 wm_hints.input = True;
403 wm_hints.initial_state = NormalState;
405 /* FIXME: Is there any point in doing this? Do any WM's pay
406 * attention to PSize, and even if they do, is this the
409 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
411 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
413 if (attributes_mask & GDK_WA_TITLE)
414 title = attributes->title;
416 title = gdk_progname;
418 XmbSetWMProperties (private->xdisplay, private->xwindow,
423 if (attributes_mask & GDK_WA_WMCLASS)
425 class_hint = XAllocClassHint ();
426 class_hint->res_name = attributes->wmclass_name;
427 class_hint->res_class = attributes->wmclass_class;
428 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
437 gdk_window_foreign_new (guint32 anid)
440 GdkWindowPrivate *private;
441 GdkWindowPrivate *parent_private;
442 XWindowAttributes attrs;
447 private = g_new (GdkWindowPrivate, 1);
448 window = (GdkWindow*) private;
450 XGetWindowAttributes (gdk_display, anid, &attrs);
452 /* FIXME: This is pretty expensive. Maybe the caller should supply
454 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
456 private->parent = gdk_xid_table_lookup (parent);
458 parent_private = (GdkWindowPrivate *)private->parent;
461 parent_private->children = g_list_prepend (parent_private->children, window);
463 private->xwindow = anid;
464 private->xdisplay = gdk_display;
465 private->x = attrs.x;
466 private->y = attrs.y;
467 private->width = attrs.width;
468 private->height = attrs.height;
469 private->resize_count = 0;
470 private->ref_count = 1;
471 private->window_type = GDK_WINDOW_FOREIGN;
472 private->destroyed = FALSE;
473 private->extension_events = 0;
476 private->dnd_drag_data_type = None;
477 private->dnd_drag_data_typesavail =
478 private->dnd_drop_data_typesavail = NULL;
479 private->dnd_drop_enabled = private->dnd_drag_enabled =
480 private->dnd_drag_accepted = private->dnd_drag_datashow =
481 private->dnd_drop_data_numtypesavail =
482 private->dnd_drag_data_numtypesavail = 0;
483 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
485 private->filters = NULL;
486 private->children = NULL;
488 window->user_data = NULL;
490 gdk_window_ref (window);
491 gdk_xid_table_insert (&private->xwindow, window);
496 /* Call this function when you want a window and all its children to
497 disappear. When xdestroy is true, a request to destroy the XWindow
498 is sent out. When it is false, it is assumed that the XWindow has
499 been or will be destroyed by destroying some ancestor of this
503 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
504 gboolean our_destroy)
506 GdkWindowPrivate *private;
507 GdkWindowPrivate *temp_private;
508 GdkWindow *temp_window;
512 g_return_if_fail (window != NULL);
514 private = (GdkWindowPrivate*) window;
516 switch (private->window_type)
518 case GDK_WINDOW_TOPLEVEL:
519 case GDK_WINDOW_CHILD:
520 case GDK_WINDOW_DIALOG:
521 case GDK_WINDOW_TEMP:
522 case GDK_WINDOW_FOREIGN:
523 if (!private->destroyed)
527 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
528 if (parent_private->children)
529 parent_private->children = g_list_remove (parent_private->children, window);
532 if (private->window_type != GDK_WINDOW_FOREIGN)
534 children = tmp = private->children;
535 private->children = NULL;
539 temp_window = tmp->data;
542 temp_private = (GdkWindowPrivate*) temp_window;
544 gdk_window_internal_destroy (temp_window, FALSE,
548 g_list_free (children);
551 if (private->extension_events != 0)
552 gdk_input_window_destroy (window);
554 if(private->dnd_drag_data_numtypesavail > 0)
556 g_free (private->dnd_drag_data_typesavail);
557 private->dnd_drag_data_typesavail = NULL;
559 if(private->dnd_drop_data_numtypesavail > 0)
561 g_free (private->dnd_drop_data_typesavail);
562 private->dnd_drop_data_typesavail = NULL;
565 if (private->filters)
567 tmp = private->filters;
575 g_list_free (private->filters);
576 private->filters = NULL;
579 if (private->window_type == GDK_WINDOW_FOREIGN)
581 if (our_destroy && (private->parent != NULL))
583 /* It's somebody elses window, but in our heirarchy,
584 * so reparent it to the root window, and then send
585 * it a delete event, as if we were a WM
587 XClientMessageEvent xevent;
589 gdk_window_hide (window);
590 gdk_window_reparent (window, NULL, 0, 0);
592 xevent.type = ClientMessage;
593 xevent.window = private->xwindow;
594 xevent.message_type = gdk_wm_protocols;
596 xevent.data.l[0] = gdk_wm_delete_window;
597 xevent.data.l[1] = CurrentTime;
599 XSendEvent (private->xdisplay, private->xwindow,
600 False, 0, (XEvent *)&xevent);
604 XDestroyWindow (private->xdisplay, private->xwindow);
606 if (private->colormap)
607 gdk_colormap_unref (private->colormap);
609 private->destroyed = TRUE;
613 case GDK_WINDOW_ROOT:
614 g_error ("attempted to destroy root window");
617 case GDK_WINDOW_PIXMAP:
618 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
623 /* Like internal_destroy, but also destroys the reference created by
627 gdk_window_destroy (GdkWindow *window)
629 gdk_window_internal_destroy (window, TRUE, TRUE);
630 gdk_window_unref (window);
633 /* This function is called when the XWindow is really gone. */
636 gdk_window_destroy_notify (GdkWindow *window)
638 GdkWindowPrivate *private;
640 g_return_if_fail (window != NULL);
642 private = (GdkWindowPrivate*) window;
644 if (!private->destroyed)
646 if (private->window_type == GDK_WINDOW_FOREIGN)
647 gdk_window_internal_destroy (window, FALSE, FALSE);
649 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
652 gdk_xid_table_remove (private->xwindow);
653 gdk_window_unref (window);
657 gdk_window_ref (GdkWindow *window)
659 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
660 g_return_val_if_fail (window != NULL, NULL);
662 private->ref_count += 1;
667 gdk_window_unref (GdkWindow *window)
669 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
670 g_return_if_fail (window != NULL);
672 private->ref_count -= 1;
673 if (private->ref_count == 0)
675 if (!private->destroyed)
676 g_warning ("losing last reference to undestroyed window\n");
682 gdk_window_show (GdkWindow *window)
684 GdkWindowPrivate *private;
686 g_return_if_fail (window != NULL);
688 private = (GdkWindowPrivate*) window;
689 if (!private->destroyed)
691 XRaiseWindow (private->xdisplay, private->xwindow);
692 XMapWindow (private->xdisplay, private->xwindow);
697 gdk_window_hide (GdkWindow *window)
699 GdkWindowPrivate *private;
701 g_return_if_fail (window != NULL);
703 private = (GdkWindowPrivate*) window;
704 if (!private->destroyed)
705 XUnmapWindow (private->xdisplay, private->xwindow);
709 gdk_window_withdraw (GdkWindow *window)
711 GdkWindowPrivate *private;
713 g_return_if_fail (window != NULL);
715 private = (GdkWindowPrivate*) window;
716 if (!private->destroyed)
717 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
721 gdk_window_move (GdkWindow *window,
725 GdkWindowPrivate *private;
727 g_return_if_fail (window != NULL);
729 private = (GdkWindowPrivate*) window;
730 if (!private->destroyed)
732 XMoveWindow (private->xdisplay, private->xwindow, x, y);
734 if (private->window_type == GDK_WINDOW_CHILD)
743 gdk_window_resize (GdkWindow *window,
747 GdkWindowPrivate *private;
749 g_return_if_fail (window != NULL);
756 private = (GdkWindowPrivate*) window;
758 if (!private->destroyed &&
759 ((private->resize_count > 0) ||
760 (private->width != (guint16) width) ||
761 (private->height != (guint16) height)))
763 XResizeWindow (private->xdisplay, private->xwindow, width, height);
764 private->resize_count += 1;
766 if (private->window_type == GDK_WINDOW_CHILD)
768 private->width = width;
769 private->height = height;
775 gdk_window_move_resize (GdkWindow *window,
781 GdkWindowPrivate *private;
783 g_return_if_fail (window != NULL);
790 private = (GdkWindowPrivate*) window;
791 if (!private->destroyed)
793 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
795 if (private->window_type == GDK_WINDOW_CHILD)
799 private->width = width;
800 private->height = height;
806 gdk_window_reparent (GdkWindow *window,
807 GdkWindow *new_parent,
811 GdkWindowPrivate *window_private;
812 GdkWindowPrivate *parent_private;
814 g_return_if_fail (window != NULL);
817 new_parent = (GdkWindow*) &gdk_root_parent;
819 window_private = (GdkWindowPrivate*) window;
820 parent_private = (GdkWindowPrivate*) new_parent;
822 if (!window_private->destroyed && !parent_private->destroyed)
823 XReparentWindow (window_private->xdisplay,
824 window_private->xwindow,
825 parent_private->xwindow,
830 gdk_window_clear (GdkWindow *window)
832 GdkWindowPrivate *private;
834 g_return_if_fail (window != NULL);
836 private = (GdkWindowPrivate*) window;
838 if (!private->destroyed)
839 XClearWindow (private->xdisplay, private->xwindow);
843 gdk_window_clear_area (GdkWindow *window,
849 GdkWindowPrivate *private;
851 g_return_if_fail (window != NULL);
853 private = (GdkWindowPrivate*) window;
855 if (!private->destroyed)
856 XClearArea (private->xdisplay, private->xwindow,
857 x, y, width, height, False);
861 gdk_window_clear_area_e (GdkWindow *window,
867 GdkWindowPrivate *private;
869 g_return_if_fail (window != NULL);
871 private = (GdkWindowPrivate*) window;
873 if (!private->destroyed)
874 XClearArea (private->xdisplay, private->xwindow,
875 x, y, width, height, True);
879 gdk_window_copy_area (GdkWindow *window,
883 GdkWindow *source_window,
889 GdkWindowPrivate *src_private;
890 GdkWindowPrivate *dest_private;
891 GdkGCPrivate *gc_private;
893 g_return_if_fail (window != NULL);
894 g_return_if_fail (gc != NULL);
896 if (source_window == NULL)
897 source_window = window;
899 src_private = (GdkWindowPrivate*) source_window;
900 dest_private = (GdkWindowPrivate*) window;
901 gc_private = (GdkGCPrivate*) gc;
903 if (!src_private->destroyed && !dest_private->destroyed)
905 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
914 gdk_window_raise (GdkWindow *window)
916 GdkWindowPrivate *private;
918 g_return_if_fail (window != NULL);
920 private = (GdkWindowPrivate*) window;
922 if (!private->destroyed)
923 XRaiseWindow (private->xdisplay, private->xwindow);
927 gdk_window_lower (GdkWindow *window)
929 GdkWindowPrivate *private;
931 g_return_if_fail (window != NULL);
933 private = (GdkWindowPrivate*) window;
935 if (!private->destroyed)
936 XLowerWindow (private->xdisplay, private->xwindow);
940 gdk_window_set_user_data (GdkWindow *window,
943 g_return_if_fail (window != NULL);
945 window->user_data = user_data;
949 gdk_window_set_hints (GdkWindow *window,
958 GdkWindowPrivate *private;
959 XSizeHints size_hints;
961 g_return_if_fail (window != NULL);
963 private = (GdkWindowPrivate*) window;
964 if (private->destroyed)
967 size_hints.flags = 0;
969 if (flags & GDK_HINT_POS)
971 size_hints.flags |= PPosition;
976 if (flags & GDK_HINT_MIN_SIZE)
978 size_hints.flags |= PMinSize;
979 size_hints.min_width = min_width;
980 size_hints.min_height = min_height;
983 if (flags & GDK_HINT_MAX_SIZE)
985 size_hints.flags |= PMaxSize;
986 size_hints.max_width = max_width;
987 size_hints.max_height = max_height;
991 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
995 gdk_window_set_title (GdkWindow *window,
998 GdkWindowPrivate *private;
1000 g_return_if_fail (window != NULL);
1002 private = (GdkWindowPrivate*) window;
1003 if (!private->destroyed)
1004 XmbSetWMProperties (private->xdisplay, private->xwindow,
1005 title, title, NULL, 0, NULL, NULL, NULL);
1009 gdk_window_set_background (GdkWindow *window,
1012 GdkWindowPrivate *private;
1014 g_return_if_fail (window != NULL);
1016 private = (GdkWindowPrivate*) window;
1017 if (!private->destroyed)
1018 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1022 gdk_window_set_back_pixmap (GdkWindow *window,
1024 gint parent_relative)
1026 GdkWindowPrivate *window_private;
1027 GdkPixmapPrivate *pixmap_private;
1030 g_return_if_fail (window != NULL);
1032 window_private = (GdkWindowPrivate*) window;
1033 pixmap_private = (GdkPixmapPrivate*) pixmap;
1036 xpixmap = pixmap_private->xwindow;
1040 if (parent_relative)
1041 xpixmap = ParentRelative;
1043 if (!window_private->destroyed)
1044 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1048 gdk_window_set_cursor (GdkWindow *window,
1051 GdkWindowPrivate *window_private;
1052 GdkCursorPrivate *cursor_private;
1055 g_return_if_fail (window != NULL);
1057 window_private = (GdkWindowPrivate*) window;
1058 cursor_private = (GdkCursorPrivate*) cursor;
1063 xcursor = cursor_private->xcursor;
1065 if (!window_private->destroyed)
1066 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1070 gdk_window_set_colormap (GdkWindow *window,
1071 GdkColormap *colormap)
1073 GdkWindowPrivate *window_private;
1074 GdkColormapPrivate *colormap_private;
1076 g_return_if_fail (window != NULL);
1077 g_return_if_fail (colormap != NULL);
1079 window_private = (GdkWindowPrivate*) window;
1080 colormap_private = (GdkColormapPrivate*) colormap;
1082 if (!window_private->destroyed)
1084 XSetWindowColormap (window_private->xdisplay,
1085 window_private->xwindow,
1086 colormap_private->xcolormap);
1088 if (window_private->colormap)
1089 gdk_colormap_unref (window_private->colormap);
1090 window_private->colormap = colormap;
1091 gdk_colormap_ref (window_private->colormap);
1093 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1094 gdk_window_add_colormap_windows (window);
1099 gdk_window_get_user_data (GdkWindow *window,
1102 g_return_if_fail (window != NULL);
1104 *data = window->user_data;
1108 gdk_window_get_geometry (GdkWindow *window,
1115 GdkWindowPrivate *window_private;
1121 guint tborder_width;
1125 window = (GdkWindow*) &gdk_root_parent;
1127 window_private = (GdkWindowPrivate*) window;
1129 if (!window_private->destroyed)
1131 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1132 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1148 gdk_window_get_position (GdkWindow *window,
1152 GdkWindowPrivate *window_private;
1154 g_return_if_fail (window != NULL);
1156 window_private = (GdkWindowPrivate*) window;
1159 *x = window_private->x;
1161 *y = window_private->y;
1165 gdk_window_get_size (GdkWindow *window,
1169 GdkWindowPrivate *window_private;
1171 g_return_if_fail (window != NULL);
1173 window_private = (GdkWindowPrivate*) window;
1176 *width = window_private->width;
1178 *height = window_private->height;
1182 gdk_window_get_visual (GdkWindow *window)
1184 GdkWindowPrivate *window_private;
1185 XWindowAttributes window_attributes;
1187 g_return_val_if_fail (window != NULL, NULL);
1189 window_private = (GdkWindowPrivate*) window;
1190 /* Huh? ->parent is never set for a pixmap. We should just return
1193 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1194 window_private = (GdkWindowPrivate*) window_private->parent;
1196 if (window_private && !window_private->destroyed)
1198 if (window_private->window_type == GDK_WINDOW_FOREIGN)
1200 XGetWindowAttributes (window_private->xdisplay,
1201 window_private->xwindow,
1202 &window_attributes);
1203 return gdk_visual_lookup (window_attributes.visual);
1206 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1213 gdk_window_get_colormap (GdkWindow *window)
1215 GdkWindowPrivate *window_private;
1216 XWindowAttributes window_attributes;
1218 g_return_val_if_fail (window != NULL, NULL);
1219 window_private = (GdkWindowPrivate*) window;
1221 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1222 if (!window_private->destroyed)
1224 if (window_private->window_type == GDK_WINDOW_FOREIGN)
1226 XGetWindowAttributes (window_private->xdisplay,
1227 window_private->xwindow,
1228 &window_attributes);
1229 return gdk_colormap_lookup (window_attributes.colormap);
1232 return window_private->colormap;
1239 gdk_window_get_type (GdkWindow *window)
1241 GdkWindowPrivate *window_private;
1243 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1245 window_private = (GdkWindowPrivate*) window;
1246 return window_private->window_type;
1250 gdk_window_get_origin (GdkWindow *window,
1254 GdkWindowPrivate *private;
1259 g_return_val_if_fail (window != NULL, 0);
1261 private = (GdkWindowPrivate*) window;
1263 if (!private->destroyed)
1265 return_val = XTranslateCoordinates (private->xdisplay,
1283 gdk_window_get_pointer (GdkWindow *window,
1286 GdkModifierType *mask)
1288 GdkWindowPrivate *private;
1289 GdkWindow *return_val;
1297 window = (GdkWindow*) &gdk_root_parent;
1299 private = (GdkWindowPrivate*) window;
1302 if (!private->destroyed &&
1303 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1304 &rootx, &rooty, &winx, &winy, &xmask))
1308 if (mask) *mask = xmask;
1311 return_val = gdk_window_lookup (child);
1318 gdk_window_get_parent (GdkWindow *window)
1320 g_return_val_if_fail (window != NULL, NULL);
1322 return ((GdkWindowPrivate*) window)->parent;
1326 gdk_window_get_toplevel (GdkWindow *window)
1328 GdkWindowPrivate *private;
1330 g_return_val_if_fail (window != NULL, NULL);
1332 private = (GdkWindowPrivate*) window;
1334 while (private->window_type == GDK_WINDOW_CHILD)
1336 window = ((GdkWindowPrivate*) window)->parent;
1337 private = (GdkWindowPrivate*) window;
1344 gdk_window_get_children (GdkWindow *window)
1346 GdkWindowPrivate *private;
1352 unsigned int nchildren;
1355 g_return_val_if_fail (window != NULL, NULL);
1357 private = (GdkWindowPrivate*) window;
1358 if (private->destroyed)
1361 XQueryTree (private->xdisplay, private->xwindow,
1362 &root, &parent, &xchildren, &nchildren);
1368 for (i = 0; i < nchildren; i++)
1370 child = gdk_window_lookup (xchildren[i]);
1372 children = g_list_prepend (children, child);
1382 gdk_window_get_events (GdkWindow *window)
1384 GdkWindowPrivate *private;
1385 XWindowAttributes attrs;
1386 GdkEventMask event_mask;
1389 g_return_val_if_fail (window != NULL, 0);
1391 private = (GdkWindowPrivate*) window;
1392 if (private->destroyed)
1395 XGetWindowAttributes (gdk_display, private->xwindow,
1399 for (i = 0; i < nevent_masks; i++)
1401 if (attrs.your_event_mask & event_mask_table[i])
1402 event_mask |= 1 << (i + 1);
1409 gdk_window_set_events (GdkWindow *window,
1410 GdkEventMask event_mask)
1412 GdkWindowPrivate *private;
1416 g_return_if_fail (window != NULL);
1418 private = (GdkWindowPrivate*) window;
1419 if (private->destroyed)
1422 xevent_mask = StructureNotifyMask;
1423 for (i = 0; i < nevent_masks; i++)
1425 if (event_mask & (1 << (i + 1)))
1426 xevent_mask |= event_mask_table[i];
1429 XSelectInput (gdk_display, private->xwindow,
1434 gdk_window_add_colormap_windows (GdkWindow *window)
1436 GdkWindow *toplevel;
1437 GdkWindowPrivate *toplevel_private;
1438 GdkWindowPrivate *window_private;
1439 Window *old_windows;
1440 Window *new_windows;
1443 g_return_if_fail (window != NULL);
1445 toplevel = gdk_window_get_toplevel (window);
1446 toplevel_private = (GdkWindowPrivate*) toplevel;
1447 window_private = (GdkWindowPrivate*) window;
1448 if (window_private->destroyed)
1451 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1452 toplevel_private->xwindow,
1453 &old_windows, &count))
1459 for (i = 0; i < count; i++)
1460 if (old_windows[i] == window_private->xwindow)
1463 new_windows = g_new (Window, count + 1);
1465 for (i = 0; i < count; i++)
1466 new_windows[i] = old_windows[i];
1467 new_windows[count] = window_private->xwindow;
1469 XSetWMColormapWindows (toplevel_private->xdisplay,
1470 toplevel_private->xwindow,
1471 new_windows, count + 1);
1473 g_free (new_windows);
1475 XFree (old_windows);
1479 * This needs the X11 shape extension.
1480 * If not available, simply remove the call to
1481 * XShapeCombineMask. Shaped windows will look
1482 * ugly, but programs still work. Stefan Wille
1485 gdk_window_shape_combine_mask (GdkWindow *window,
1489 GdkWindowPrivate *window_private;
1492 g_return_if_fail (window != NULL);
1494 /* This is needed, according to raster */
1495 gdk_window_set_override_redirect(window, TRUE);
1497 window_private = (GdkWindowPrivate*) window;
1498 if (window_private->destroyed)
1503 GdkWindowPrivate *pixmap_private;
1505 pixmap_private = (GdkWindowPrivate*) mask;
1506 pixmap = (Pixmap) pixmap_private->xwindow;
1515 XShapeCombineMask (window_private->xdisplay,
1516 window_private->xwindow,
1524 gdk_dnd_drag_addwindow (GdkWindow *window)
1526 GdkWindowPrivate *window_private;
1528 g_return_if_fail (window != NULL);
1530 window_private = (GdkWindowPrivate *) window;
1531 if (window_private->destroyed)
1534 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1536 gdk_dnd.drag_numwindows++;
1537 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1538 gdk_dnd.drag_numwindows
1539 * sizeof(GdkWindow *));
1540 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1541 window_private->dnd_drag_accepted = 0;
1544 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1548 gdk_window_dnd_drag_set (GdkWindow *window,
1553 GdkWindowPrivate *window_private;
1556 g_return_if_fail (window != NULL);
1557 window_private = (GdkWindowPrivate *) window;
1558 if (window_private->destroyed)
1561 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1565 g_return_if_fail(typelist != NULL);
1567 if (window_private->dnd_drag_data_numtypesavail > 3)
1569 window_private->dnd_drag_data_numtypesavail = numtypes;
1571 window_private->dnd_drag_data_typesavail =
1572 g_realloc (window_private->dnd_drag_data_typesavail,
1573 (numtypes + 1) * sizeof (GdkAtom));
1575 for (i = 0; i < numtypes; i++)
1577 /* Allow blanket use of ALL to get anything... */
1578 if (strcmp (typelist[i], "ALL"))
1579 window_private->dnd_drag_data_typesavail[i] =
1580 gdk_atom_intern (typelist[i], FALSE);
1582 window_private->dnd_drag_data_typesavail[i] = None;
1586 * set our extended type list if we need to
1589 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1590 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1591 (guchar *)(window_private->dnd_drag_data_typesavail
1592 + (sizeof(GdkAtom) * 3)),
1593 (numtypes - 3) * sizeof(GdkAtom));
1595 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1599 g_free (window_private->dnd_drag_data_typesavail);
1600 window_private->dnd_drag_data_typesavail = NULL;
1601 window_private->dnd_drag_data_numtypesavail = 0;
1606 gdk_window_dnd_drop_set (GdkWindow *window,
1610 guint8 destructive_op)
1612 GdkWindowPrivate *window_private;
1615 g_return_if_fail (window != NULL);
1616 window_private = (GdkWindowPrivate *) window;
1617 if (window_private->destroyed)
1620 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1623 g_return_if_fail(typelist != NULL);
1625 window_private->dnd_drop_data_numtypesavail = numtypes;
1627 window_private->dnd_drop_data_typesavail =
1628 g_realloc (window_private->dnd_drop_data_typesavail,
1629 (numtypes + 1) * sizeof (GdkAtom));
1631 for (i = 0; i < numtypes; i++)
1632 window_private->dnd_drop_data_typesavail[i] =
1633 gdk_atom_intern (typelist[i], FALSE);
1635 window_private->dnd_drop_destructive_op = destructive_op;
1640 * This is used to reply to a GDK_DRAG_REQUEST event
1641 * (which may be generated by XdeRequest or a confirmed drop...
1644 gdk_window_dnd_data_set (GdkWindow *window,
1647 gulong data_numbytes)
1649 GdkWindowPrivate *window_private;
1651 GdkEventDropDataAvailable tmp_ev;
1654 g_return_if_fail (window != NULL);
1655 g_return_if_fail (event != NULL);
1656 g_return_if_fail (data != NULL);
1657 g_return_if_fail (data_numbytes > 0);
1658 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1660 window_private = (GdkWindowPrivate *) window;
1661 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1662 if (window_private->destroyed)
1665 /* We set the property on our window... */
1666 gdk_property_change (window, window_private->dnd_drag_data_type,
1667 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1669 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1671 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1676 * Then we send the event to tell the receiving window that the
1679 tmp_ev.u.allflags = 0;
1680 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1681 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1683 sev.xclient.type = ClientMessage;
1684 sev.xclient.format = 32;
1685 sev.xclient.window = event->dragrequest.requestor;
1686 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1687 sev.xclient.data.l[0] = window_private->xwindow;
1688 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1689 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1691 if (event->dragrequest.isdrop)
1692 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1693 (event->dragrequest.drop_coords.y << 16);
1695 sev.xclient.data.l[3] = 0;
1697 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1699 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1700 StructureNotifyMask, &sev))
1701 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1702 event->dragrequest.requestor));
1707 gdk_window_add_filter (GdkWindow *window,
1708 GdkFilterFunc function,
1711 GdkWindowPrivate *private;
1713 GdkEventFilter *filter;
1715 private = (GdkWindowPrivate*) window;
1716 if (private && private->destroyed)
1720 tmp_list = private->filters;
1722 tmp_list = gdk_default_filters;
1726 filter = (GdkEventFilter *)tmp_list->data;
1727 if ((filter->function == function) && (filter->data == data))
1729 tmp_list = tmp_list->next;
1732 filter = g_new (GdkEventFilter, 1);
1733 filter->function = function;
1734 filter->data = data;
1737 private->filters = g_list_append (private->filters, filter);
1739 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1743 gdk_window_remove_filter (GdkWindow *window,
1744 GdkFilterFunc function,
1747 GdkWindowPrivate *private;
1749 GdkEventFilter *filter;
1751 private = (GdkWindowPrivate*) window;
1754 tmp_list = private->filters;
1756 tmp_list = gdk_default_filters;
1760 filter = (GdkEventFilter *)tmp_list->data;
1761 tmp_list = tmp_list->next;
1763 if ((filter->function == function) && (filter->data == data))
1766 private->filters = g_list_remove_link (private->filters, tmp_list);
1768 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1769 g_list_free_1 (tmp_list);
1778 gdk_window_set_override_redirect(GdkWindow *window,
1779 gboolean override_redirect)
1781 GdkWindowPrivate *private;
1782 XSetWindowAttributes attr;
1784 g_return_if_fail (window != NULL);
1785 private = (GdkWindowPrivate*) window;
1786 if (private->destroyed)
1789 attr.override_redirect = (override_redirect == FALSE)?False:True;
1790 XChangeWindowAttributes(gdk_display,
1791 ((GdkWindowPrivate *)window)->xwindow,
1797 gdk_window_set_icon (GdkWindow *window,
1798 GdkWindow *icon_window,
1803 GdkWindowPrivate *window_private;
1804 GdkWindowPrivate *private;
1806 g_return_if_fail (window != NULL);
1807 window_private = (GdkWindowPrivate*) window;
1808 if (window_private->destroyed)
1813 if (icon_window != NULL)
1815 private = (GdkWindowPrivate *)icon_window;
1816 wm_hints.flags |= IconWindowHint;
1817 wm_hints.icon_window = private->xwindow;
1822 private = (GdkWindowPrivate *)pixmap;
1823 wm_hints.flags |= IconPixmapHint;
1824 wm_hints.icon_pixmap = private->xwindow;
1829 private = (GdkWindowPrivate *)mask;
1830 wm_hints.flags |= IconMaskHint;
1831 wm_hints.icon_mask = private->xwindow;
1834 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1838 gdk_window_set_icon_name (GdkWindow *window,
1841 GdkWindowPrivate *window_private;
1842 XTextProperty property;
1845 g_return_if_fail (window != NULL);
1846 window_private = (GdkWindowPrivate*) window;
1847 if (window_private->destroyed)
1849 res = XmbTextListToTextProperty (window_private->xdisplay,
1850 &name, 1, XStdICCTextStyle,
1854 g_warning("Error converting icon name to text property: %d\n", res);
1858 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1861 XFree(property.value);
1865 gdk_window_set_group (GdkWindow *window,
1869 GdkWindowPrivate *window_private;
1870 GdkWindowPrivate *private;
1872 g_return_if_fail (window != NULL);
1873 g_return_if_fail (leader != NULL);
1874 window_private = (GdkWindowPrivate*) window;
1875 if (window_private->destroyed)
1878 private = (GdkWindowPrivate *)leader;
1879 wm_hints.flags = WindowGroupHint;
1880 wm_hints.window_group = private->xwindow;
1882 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1886 gdk_window_set_mwm_hints (GdkWindow *window,
1887 MotifWmHints *new_hints)
1889 static Atom hints_atom = None;
1890 MotifWmHints *hints;
1896 GdkWindowPrivate *window_private;
1898 g_return_if_fail (window != NULL);
1899 window_private = (GdkWindowPrivate*) window;
1900 if (window_private->destroyed)
1904 hints_atom = XInternAtom (window_private->xdisplay,
1905 _XA_MOTIF_WM_HINTS, FALSE);
1907 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1908 hints_atom, 0, sizeof(MotifWmHints)/4,
1909 False, AnyPropertyType, &type, &format, &nitems,
1910 &bytes_after, (guchar **)&hints);
1916 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1918 hints->flags |= MWM_HINTS_FUNCTIONS;
1919 hints->functions = new_hints->functions;
1921 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1923 hints->flags |= MWM_HINTS_DECORATIONS;
1924 hints->decorations = new_hints->decorations;
1928 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1929 hints_atom, hints_atom, 32, PropModeReplace,
1930 (guchar *)hints, sizeof(MotifWmHints)/4);
1932 if (hints != new_hints)
1937 gdk_window_set_decorations (GdkWindow *window,
1938 GdkWMDecoration decorations)
1942 hints.flags = MWM_HINTS_DECORATIONS;
1943 hints.decorations = decorations;
1945 gdk_window_set_mwm_hints (window, &hints);
1949 gdk_window_set_functions (GdkWindow *window,
1950 GdkWMFunction functions)
1954 hints.flags = MWM_HINTS_FUNCTIONS;
1955 hints.functions = functions;
1957 gdk_window_set_mwm_hints (window, &hints);