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 Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <X11/Xutil.h>
21 #include <X11/Xatom.h>
22 #include <X11/extensions/shape.h>
23 #include <netinet/in.h>
25 #include "../config.h"
27 #include "gdkprivate.h"
32 int nevent_masks = 17;
33 int event_mask_table[19] =
37 PointerMotionHintMask,
42 ButtonPressMask | OwnerGrabButtonMask,
43 ButtonReleaseMask | OwnerGrabButtonMask,
57 /* internal function created for and used by gdk_window_xid_at_coords */
59 gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y,
60 GList *excludes, gboolean excl_child)
63 GdkWindowPrivate *private;
66 Window child=0,parent_win=0,root_win=0;
72 window=(GdkWindow*)&gdk_root_parent;
73 private=(GdkWindowPrivate*)window;
74 disp=private->xdisplay;
75 if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
78 if (!((x>=wx)&&(y>=wy)&&(x<(wx+ww))&&(y<(wy+wh))))
80 if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
86 if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
88 if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
102 * The following fucntion by The Rasterman <raster@redhat.com>
103 * This function returns the X Window ID in which the x y location is in
104 * (x and y being relative to the root window), excluding any windows listed
105 * in the GList excludes (this is a list of X Window ID's - gpointer being
108 * This is primarily designed for internal gdk use - for DND for example
109 * when using a shaped icon window as the drag object - you exclude the
110 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
111 * You can get back an X Window ID as to what X Window ID is infact under
112 * those X,Y co-ordinates.
115 gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
118 GdkWindowPrivate *private;
121 Window root,child=0,parent_win=0,root_win=0;
125 window=(GdkWindow*)&gdk_root_parent;
126 private=(GdkWindowPrivate*)window;
127 disp=private->xdisplay;
128 root=private->xwindow;
130 num=g_list_length(excludes);
131 if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
138 XWindowAttributes xwa;
140 XGetWindowAttributes (disp, list [i], &xwa);
142 if (xwa.map_state != IsViewable)
145 if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
148 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
153 if (!g_list_find(excludes,(gpointer *)child))
176 XWindowAttributes xattributes;
179 unsigned int border_width;
183 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
184 &x, &y, &width, &height, &border_width, &depth);
185 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
187 gdk_root_parent.xdisplay = gdk_display;
188 gdk_root_parent.xwindow = gdk_root_window;
189 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
190 gdk_root_parent.window.user_data = NULL;
191 gdk_root_parent.width = width;
192 gdk_root_parent.height = height;
196 gdk_window_new (GdkWindow *parent,
197 GdkWindowAttr *attributes,
198 gint attributes_mask)
201 GdkWindowPrivate *private;
202 GdkWindowPrivate *parent_private;
204 GdkColormap *colormap;
205 Display *parent_display;
208 XSetWindowAttributes xattributes;
209 long xattributes_mask;
210 XSizeHints size_hints;
212 XClassHint *class_hint;
218 g_return_val_if_fail (attributes != NULL, NULL);
221 parent = (GdkWindow*) &gdk_root_parent;
223 parent_private = (GdkWindowPrivate*) parent;
224 if (parent_private->destroyed)
227 xparent = parent_private->xwindow;
228 parent_display = parent_private->xdisplay;
230 private = g_new (GdkWindowPrivate, 1);
231 window = (GdkWindow*) private;
233 private->parent = parent;
234 private->xdisplay = parent_display;
235 private->destroyed = FALSE;
236 private->resize_count = 0;
237 private->ref_count = 1;
238 xattributes_mask = 0;
240 if (attributes_mask & GDK_WA_X)
245 if (attributes_mask & GDK_WA_Y)
252 private->width = (attributes->width > 1) ? (attributes->width) : (1);
253 private->height = (attributes->height > 1) ? (attributes->height) : (1);
254 private->window_type = attributes->window_type;
255 private->extension_events = FALSE;
256 private->dnd_drag_data_type = None;
257 private->dnd_drag_data_typesavail =
258 private->dnd_drop_data_typesavail = NULL;
259 private->dnd_drop_enabled = private->dnd_drag_enabled =
260 private->dnd_drag_accepted = private->dnd_drag_datashow =
261 private->dnd_drop_data_numtypesavail =
262 private->dnd_drag_data_numtypesavail = 0;
263 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
265 private->filters = NULL;
267 window->user_data = NULL;
269 if (attributes_mask & GDK_WA_VISUAL)
270 visual = attributes->visual;
272 visual = gdk_visual_get_system ();
273 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
275 xattributes.event_mask = StructureNotifyMask;
276 for (i = 0; i < nevent_masks; i++)
278 if (attributes->event_mask & (1 << (i + 1)))
279 xattributes.event_mask |= event_mask_table[i];
282 if (xattributes.event_mask)
283 xattributes_mask |= CWEventMask;
285 if(attributes_mask & GDK_WA_NOREDIR) {
286 xattributes.override_redirect =
287 (attributes->override_redirect == FALSE)?False:True;
288 xattributes_mask |= CWOverrideRedirect;
290 xattributes.override_redirect = False;
292 if (attributes->wclass == GDK_INPUT_OUTPUT)
295 depth = visual->depth;
297 if (attributes_mask & GDK_WA_COLORMAP)
298 colormap = attributes->colormap;
300 colormap = gdk_colormap_get_system ();
302 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
303 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
304 xattributes_mask |= CWBorderPixel | CWBackPixel;
306 switch (private->window_type)
308 case GDK_WINDOW_TOPLEVEL:
309 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
310 xattributes_mask |= CWColormap;
312 xparent = gdk_root_window;
315 case GDK_WINDOW_CHILD:
316 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
317 xattributes_mask |= CWColormap;
320 case GDK_WINDOW_DIALOG:
321 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
322 xattributes_mask |= CWColormap;
324 xparent = gdk_root_window;
327 case GDK_WINDOW_TEMP:
328 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
329 xattributes_mask |= CWColormap;
331 xparent = gdk_root_window;
333 xattributes.save_under = True;
334 xattributes.override_redirect = True;
335 xattributes.cursor = None;
336 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
338 case GDK_WINDOW_ROOT:
339 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
341 case GDK_WINDOW_PIXMAP:
342 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
353 private->xwindow = XCreateWindow (private->xdisplay, xparent,
354 x, y, private->width, private->height,
355 0, depth, class, xvisual,
356 xattributes_mask, &xattributes);
357 gdk_window_ref (window);
358 gdk_xid_table_insert (&private->xwindow, window);
360 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
361 (attributes->cursor) :
364 switch (private->window_type)
366 case GDK_WINDOW_DIALOG:
367 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
368 case GDK_WINDOW_TOPLEVEL:
369 case GDK_WINDOW_TEMP:
370 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
372 case GDK_WINDOW_CHILD:
373 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
374 (colormap != gdk_colormap_get_system ()) &&
375 (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
377 GDK_NOTE (MISC, g_print ("adding colormap window\n"));
378 gdk_window_add_colormap_windows (window);
387 size_hints.flags = PSize;
388 size_hints.width = private->width;
389 size_hints.height = private->height;
391 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
392 wm_hints.window_group = gdk_leader_window;
393 wm_hints.input = True;
394 wm_hints.initial_state = NormalState;
396 /* FIXME: Is there any point in doing this? Do any WM's pay
397 * attention to PSize, and even if they do, is this the
400 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
402 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
404 if (attributes_mask & GDK_WA_TITLE)
405 title = attributes->title;
407 title = gdk_progname;
409 XmbSetWMProperties (private->xdisplay, private->xwindow,
414 if (attributes_mask & GDK_WA_WMCLASS)
416 class_hint = XAllocClassHint ();
417 class_hint->res_name = attributes->wmclass_name;
418 class_hint->res_class = attributes->wmclass_class;
419 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
428 gdk_window_foreign_new (guint32 anid)
431 GdkWindowPrivate *private;
432 XWindowAttributes attrs;
437 private = g_new (GdkWindowPrivate, 1);
438 window = (GdkWindow*) private;
440 XGetWindowAttributes (gdk_display, anid, &attrs);
442 /* FIXME: This is pretty expensive. Maybe the caller should supply
444 XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
446 private->parent = gdk_xid_table_lookup (parent);
448 private->xwindow = anid;
449 private->xdisplay = gdk_display;
450 private->x = attrs.x;
451 private->y = attrs.y;
452 private->width = attrs.width;
453 private->height = attrs.height;
454 private->resize_count = 0;
455 private->ref_count = 1;
456 private->window_type = GDK_WINDOW_FOREIGN;
457 private->destroyed = FALSE;
458 private->extension_events = 0;
461 private->dnd_drag_data_type = None;
462 private->dnd_drag_data_typesavail =
463 private->dnd_drop_data_typesavail = NULL;
464 private->dnd_drop_enabled = private->dnd_drag_enabled =
465 private->dnd_drag_accepted = private->dnd_drag_datashow =
466 private->dnd_drop_data_numtypesavail =
467 private->dnd_drag_data_numtypesavail = 0;
468 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
470 private->filters = NULL;
472 window->user_data = NULL;
474 gdk_window_ref (window);
475 gdk_xid_table_insert (&private->xwindow, window);
480 /* Call this function when you want a window and all its children to
481 disappear. When xdestroy is true, a request to destroy the XWindow
482 is sent out. When it is false, it is assumed that the XWindow has
483 been or will be destroyed by destroying some ancestor of this
487 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
488 gboolean our_destroy)
490 GdkWindowPrivate *private;
491 GdkWindowPrivate *temp_private;
492 GdkWindow *temp_window;
496 g_return_if_fail (window != NULL);
498 private = (GdkWindowPrivate*) window;
500 switch (private->window_type)
502 case GDK_WINDOW_TOPLEVEL:
503 case GDK_WINDOW_CHILD:
504 case GDK_WINDOW_DIALOG:
505 case GDK_WINDOW_TEMP:
506 case GDK_WINDOW_FOREIGN:
507 if (!private->destroyed)
509 if (private->window_type != GDK_WINDOW_FOREIGN)
511 children = gdk_window_get_children (window);
516 temp_window = tmp->data;
519 temp_private = (GdkWindowPrivate*) temp_window;
521 gdk_window_internal_destroy (temp_window, FALSE,
525 g_list_free (children);
528 if (private->extension_events != 0)
529 gdk_input_window_destroy (window);
531 if(private->dnd_drag_data_numtypesavail > 0)
533 g_free (private->dnd_drag_data_typesavail);
534 private->dnd_drag_data_typesavail = NULL;
536 if(private->dnd_drop_data_numtypesavail > 0)
538 g_free (private->dnd_drop_data_typesavail);
539 private->dnd_drop_data_typesavail = NULL;
542 if (private->filters)
544 tmp = private->filters;
552 g_list_free (private->filters);
553 private->filters = NULL;
556 if (private->window_type == GDK_WINDOW_FOREIGN)
558 if (our_destroy && (private->parent != NULL))
560 /* It's somebody elses window, but in our heirarchy,
561 * so reparent it to the root window, and then send
562 * it a delete event, as if we were a WM
564 XClientMessageEvent xevent;
566 gdk_window_hide (window);
567 gdk_window_reparent (window, NULL, 0, 0);
569 xevent.type = ClientMessage;
570 xevent.window = private->xwindow;
571 xevent.message_type = gdk_wm_protocols;
573 xevent.data.l[0] = gdk_wm_delete_window;
574 xevent.data.l[1] = CurrentTime;
576 XSendEvent (private->xdisplay, private->xwindow,
577 False, 0, (XEvent *)&xevent);
581 XDestroyWindow (private->xdisplay, private->xwindow);
583 private->destroyed = TRUE;
587 case GDK_WINDOW_ROOT:
588 g_error ("attempted to destroy root window");
591 case GDK_WINDOW_PIXMAP:
592 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
597 /* Like internal_destroy, but also destroys the reference created by
601 gdk_window_destroy (GdkWindow *window)
603 gdk_window_internal_destroy (window, TRUE, TRUE);
604 gdk_window_unref (window);
607 /* This function is called when the XWindow is really gone. */
610 gdk_window_destroy_notify (GdkWindow *window)
612 GdkWindowPrivate *private;
614 g_return_if_fail (window != NULL);
616 private = (GdkWindowPrivate*) window;
618 if (!private->destroyed)
620 if (private->window_type == GDK_WINDOW_FOREIGN)
621 gdk_window_internal_destroy (window, FALSE, FALSE);
623 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
626 gdk_xid_table_remove (private->xwindow);
627 gdk_window_unref (window);
631 gdk_window_ref (GdkWindow *window)
633 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
634 g_return_val_if_fail (window != NULL, NULL);
636 private->ref_count += 1;
641 gdk_window_unref (GdkWindow *window)
643 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
644 g_return_if_fail (window != NULL);
646 private->ref_count -= 1;
647 if (private->ref_count == 0)
649 if (!private->destroyed)
650 g_warning ("losing last reference to undestroyed window\n");
656 gdk_window_show (GdkWindow *window)
658 GdkWindowPrivate *private;
660 g_return_if_fail (window != NULL);
662 private = (GdkWindowPrivate*) window;
663 if (!private->destroyed)
665 XRaiseWindow (private->xdisplay, private->xwindow);
666 XMapWindow (private->xdisplay, private->xwindow);
671 gdk_window_hide (GdkWindow *window)
673 GdkWindowPrivate *private;
675 g_return_if_fail (window != NULL);
677 private = (GdkWindowPrivate*) window;
678 if (!private->destroyed)
679 XUnmapWindow (private->xdisplay, private->xwindow);
683 gdk_window_withdraw (GdkWindow *window)
685 GdkWindowPrivate *private;
687 g_return_if_fail (window != NULL);
689 private = (GdkWindowPrivate*) window;
690 if (!private->destroyed)
691 XWithdrawWindow (private->xdisplay, private->xwindow, 0);
695 gdk_window_move (GdkWindow *window,
699 GdkWindowPrivate *private;
701 g_return_if_fail (window != NULL);
703 private = (GdkWindowPrivate*) window;
704 if (!private->destroyed)
706 XMoveWindow (private->xdisplay, private->xwindow, x, y);
708 if (private->window_type == GDK_WINDOW_CHILD)
717 gdk_window_resize (GdkWindow *window,
721 GdkWindowPrivate *private;
723 g_return_if_fail (window != NULL);
730 private = (GdkWindowPrivate*) window;
732 if (!private->destroyed &&
733 ((private->resize_count > 0) ||
734 (private->width != (guint16) width) ||
735 (private->height != (guint16) height)))
737 XResizeWindow (private->xdisplay, private->xwindow, width, height);
738 private->resize_count += 1;
740 if (private->window_type == GDK_WINDOW_CHILD)
742 private->width = width;
743 private->height = height;
749 gdk_window_move_resize (GdkWindow *window,
755 GdkWindowPrivate *private;
757 g_return_if_fail (window != NULL);
764 private = (GdkWindowPrivate*) window;
765 if (!private->destroyed)
767 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
769 if (private->window_type == GDK_WINDOW_CHILD)
773 private->width = width;
774 private->height = height;
780 gdk_window_reparent (GdkWindow *window,
781 GdkWindow *new_parent,
785 GdkWindowPrivate *window_private;
786 GdkWindowPrivate *parent_private;
788 g_return_if_fail (window != NULL);
791 new_parent = (GdkWindow*) &gdk_root_parent;
793 window_private = (GdkWindowPrivate*) window;
794 parent_private = (GdkWindowPrivate*) new_parent;
796 if (!window_private->destroyed && !parent_private->destroyed)
797 XReparentWindow (window_private->xdisplay,
798 window_private->xwindow,
799 parent_private->xwindow,
804 gdk_window_clear (GdkWindow *window)
806 GdkWindowPrivate *private;
808 g_return_if_fail (window != NULL);
810 private = (GdkWindowPrivate*) window;
812 if (!private->destroyed)
813 XClearWindow (private->xdisplay, private->xwindow);
817 gdk_window_clear_area (GdkWindow *window,
823 GdkWindowPrivate *private;
825 g_return_if_fail (window != NULL);
827 private = (GdkWindowPrivate*) window;
829 if (!private->destroyed)
830 XClearArea (private->xdisplay, private->xwindow,
831 x, y, width, height, False);
835 gdk_window_clear_area_e (GdkWindow *window,
841 GdkWindowPrivate *private;
843 g_return_if_fail (window != NULL);
845 private = (GdkWindowPrivate*) window;
847 if (!private->destroyed)
848 XClearArea (private->xdisplay, private->xwindow,
849 x, y, width, height, True);
853 gdk_window_copy_area (GdkWindow *window,
857 GdkWindow *source_window,
863 GdkWindowPrivate *src_private;
864 GdkWindowPrivate *dest_private;
865 GdkGCPrivate *gc_private;
867 g_return_if_fail (window != NULL);
868 g_return_if_fail (gc != NULL);
870 if (source_window == NULL)
871 source_window = window;
873 src_private = (GdkWindowPrivate*) source_window;
874 dest_private = (GdkWindowPrivate*) window;
875 gc_private = (GdkGCPrivate*) gc;
877 if (!src_private->destroyed && !dest_private->destroyed)
879 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
888 gdk_window_raise (GdkWindow *window)
890 GdkWindowPrivate *private;
892 g_return_if_fail (window != NULL);
894 private = (GdkWindowPrivate*) window;
896 if (!private->destroyed)
897 XRaiseWindow (private->xdisplay, private->xwindow);
901 gdk_window_lower (GdkWindow *window)
903 GdkWindowPrivate *private;
905 g_return_if_fail (window != NULL);
907 private = (GdkWindowPrivate*) window;
909 if (!private->destroyed)
910 XLowerWindow (private->xdisplay, private->xwindow);
914 gdk_window_set_user_data (GdkWindow *window,
917 g_return_if_fail (window != NULL);
919 window->user_data = user_data;
923 gdk_window_set_hints (GdkWindow *window,
932 GdkWindowPrivate *private;
933 XSizeHints size_hints;
935 g_return_if_fail (window != NULL);
937 private = (GdkWindowPrivate*) window;
938 if (private->destroyed)
941 size_hints.flags = 0;
943 if (flags & GDK_HINT_POS)
945 size_hints.flags |= PPosition;
950 if (flags & GDK_HINT_MIN_SIZE)
952 size_hints.flags |= PMinSize;
953 size_hints.min_width = min_width;
954 size_hints.min_height = min_height;
957 if (flags & GDK_HINT_MAX_SIZE)
959 size_hints.flags |= PMaxSize;
960 size_hints.max_width = max_width;
961 size_hints.max_height = max_height;
965 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
969 gdk_window_set_title (GdkWindow *window,
972 GdkWindowPrivate *private;
974 g_return_if_fail (window != NULL);
976 private = (GdkWindowPrivate*) window;
977 if (!private->destroyed)
978 XmbSetWMProperties (private->xdisplay, private->xwindow,
979 title, title, NULL, 0, NULL, NULL, NULL);
983 gdk_window_set_background (GdkWindow *window,
986 GdkWindowPrivate *private;
988 g_return_if_fail (window != NULL);
990 private = (GdkWindowPrivate*) window;
991 if (!private->destroyed)
992 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
996 gdk_window_set_back_pixmap (GdkWindow *window,
998 gint parent_relative)
1000 GdkWindowPrivate *window_private;
1001 GdkPixmapPrivate *pixmap_private;
1004 g_return_if_fail (window != NULL);
1006 window_private = (GdkWindowPrivate*) window;
1007 pixmap_private = (GdkPixmapPrivate*) pixmap;
1010 xpixmap = pixmap_private->xwindow;
1014 if (parent_relative)
1015 xpixmap = ParentRelative;
1017 if (!window_private->destroyed)
1018 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1022 gdk_window_set_cursor (GdkWindow *window,
1025 GdkWindowPrivate *window_private;
1026 GdkCursorPrivate *cursor_private;
1029 g_return_if_fail (window != NULL);
1031 window_private = (GdkWindowPrivate*) window;
1032 cursor_private = (GdkCursorPrivate*) cursor;
1037 xcursor = cursor_private->xcursor;
1039 if (!window_private->destroyed)
1040 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1044 gdk_window_set_colormap (GdkWindow *window,
1045 GdkColormap *colormap)
1047 GdkWindowPrivate *window_private;
1048 GdkColormapPrivate *colormap_private;
1050 g_return_if_fail (window != NULL);
1051 g_return_if_fail (colormap != NULL);
1053 window_private = (GdkWindowPrivate*) window;
1054 colormap_private = (GdkColormapPrivate*) colormap;
1056 if (!window_private->destroyed)
1058 XSetWindowColormap (window_private->xdisplay,
1059 window_private->xwindow,
1060 colormap_private->xcolormap);
1062 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1063 gdk_window_add_colormap_windows (window);
1068 gdk_window_get_user_data (GdkWindow *window,
1071 g_return_if_fail (window != NULL);
1073 *data = window->user_data;
1077 gdk_window_get_geometry (GdkWindow *window,
1084 GdkWindowPrivate *window_private;
1090 guint tborder_width;
1094 window = (GdkWindow*) &gdk_root_parent;
1096 window_private = (GdkWindowPrivate*) window;
1098 if (!window_private->destroyed)
1100 XGetGeometry (window_private->xdisplay, window_private->xwindow,
1101 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1117 gdk_window_get_position (GdkWindow *window,
1121 GdkWindowPrivate *window_private;
1123 g_return_if_fail (window != NULL);
1125 window_private = (GdkWindowPrivate*) window;
1128 *x = window_private->x;
1130 *y = window_private->y;
1134 gdk_window_get_size (GdkWindow *window,
1138 GdkWindowPrivate *window_private;
1140 g_return_if_fail (window != NULL);
1142 window_private = (GdkWindowPrivate*) window;
1145 *width = window_private->width;
1147 *height = window_private->height;
1151 gdk_window_get_visual (GdkWindow *window)
1153 GdkWindowPrivate *window_private;
1154 XWindowAttributes window_attributes;
1156 g_return_val_if_fail (window != NULL, NULL);
1158 window_private = (GdkWindowPrivate*) window;
1159 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1160 window_private = (GdkWindowPrivate*) window_private->parent;
1162 if (window_private && !window_private->destroyed)
1164 XGetWindowAttributes (window_private->xdisplay,
1165 window_private->xwindow,
1166 &window_attributes);
1168 return gdk_visual_lookup (window_attributes.visual);
1175 gdk_window_get_colormap (GdkWindow *window)
1177 GdkWindowPrivate *window_private;
1178 XWindowAttributes window_attributes;
1180 g_return_val_if_fail (window != NULL, NULL);
1182 window_private = (GdkWindowPrivate*) window;
1184 if (!window_private->destroyed)
1186 XGetWindowAttributes (window_private->xdisplay,
1187 window_private->xwindow,
1188 &window_attributes);
1190 return gdk_colormap_lookup (window_attributes.colormap);
1197 gdk_window_get_type (GdkWindow *window)
1199 GdkWindowPrivate *window_private;
1201 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1203 window_private = (GdkWindowPrivate*) window;
1204 return window_private->window_type;
1208 gdk_window_get_origin (GdkWindow *window,
1212 GdkWindowPrivate *private;
1217 g_return_val_if_fail (window != NULL, 0);
1219 private = (GdkWindowPrivate*) window;
1221 if (!private->destroyed)
1223 return_val = XTranslateCoordinates (private->xdisplay,
1241 gdk_window_get_pointer (GdkWindow *window,
1244 GdkModifierType *mask)
1246 GdkWindowPrivate *private;
1247 GdkWindow *return_val;
1255 window = (GdkWindow*) &gdk_root_parent;
1257 private = (GdkWindowPrivate*) window;
1260 if (!private->destroyed &&
1261 XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1262 &rootx, &rooty, &winx, &winy, &xmask))
1266 if (mask) *mask = xmask;
1269 return_val = gdk_window_lookup (child);
1276 gdk_window_get_parent (GdkWindow *window)
1278 g_return_val_if_fail (window != NULL, NULL);
1280 return ((GdkWindowPrivate*) window)->parent;
1284 gdk_window_get_toplevel (GdkWindow *window)
1286 GdkWindowPrivate *private;
1288 g_return_val_if_fail (window != NULL, NULL);
1290 private = (GdkWindowPrivate*) window;
1292 while (private->window_type == GDK_WINDOW_CHILD)
1294 window = ((GdkWindowPrivate*) window)->parent;
1295 private = (GdkWindowPrivate*) window;
1302 gdk_window_get_children (GdkWindow *window)
1304 GdkWindowPrivate *private;
1310 unsigned int nchildren;
1313 g_return_val_if_fail (window != NULL, NULL);
1315 private = (GdkWindowPrivate*) window;
1316 if (private->destroyed)
1319 XQueryTree (private->xdisplay, private->xwindow,
1320 &root, &parent, &xchildren, &nchildren);
1326 for (i = 0; i < nchildren; i++)
1328 child = gdk_window_lookup (xchildren[i]);
1330 children = g_list_prepend (children, child);
1340 gdk_window_get_events (GdkWindow *window)
1342 GdkWindowPrivate *private;
1343 XWindowAttributes attrs;
1344 GdkEventMask event_mask;
1347 g_return_val_if_fail (window != NULL, 0);
1349 private = (GdkWindowPrivate*) window;
1350 if (private->destroyed)
1353 XGetWindowAttributes (gdk_display, private->xwindow,
1357 for (i = 0; i < nevent_masks; i++)
1359 if (attrs.your_event_mask & event_mask_table[i])
1360 event_mask |= 1 << (i + 1);
1367 gdk_window_set_events (GdkWindow *window,
1368 GdkEventMask event_mask)
1370 GdkWindowPrivate *private;
1374 g_return_if_fail (window != NULL);
1376 private = (GdkWindowPrivate*) window;
1377 if (private->destroyed)
1380 xevent_mask = StructureNotifyMask;
1381 for (i = 0; i < nevent_masks; i++)
1383 if (event_mask & (1 << (i + 1)))
1384 xevent_mask |= event_mask_table[i];
1387 XSelectInput (gdk_display, private->xwindow,
1392 gdk_window_add_colormap_windows (GdkWindow *window)
1394 GdkWindow *toplevel;
1395 GdkWindowPrivate *toplevel_private;
1396 GdkWindowPrivate *window_private;
1397 Window *old_windows;
1398 Window *new_windows;
1401 g_return_if_fail (window != NULL);
1403 toplevel = gdk_window_get_toplevel (window);
1404 toplevel_private = (GdkWindowPrivate*) toplevel;
1405 window_private = (GdkWindowPrivate*) window;
1406 if (window_private->destroyed)
1409 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1410 toplevel_private->xwindow,
1411 &old_windows, &count))
1417 for (i = 0; i < count; i++)
1418 if (old_windows[i] == window_private->xwindow)
1421 new_windows = g_new (Window, count + 1);
1423 for (i = 0; i < count; i++)
1424 new_windows[i] = old_windows[i];
1425 new_windows[count] = window_private->xwindow;
1427 XSetWMColormapWindows (toplevel_private->xdisplay,
1428 toplevel_private->xwindow,
1429 new_windows, count + 1);
1431 g_free (new_windows);
1433 XFree (old_windows);
1437 * This needs the X11 shape extension.
1438 * If not available, simply remove the call to
1439 * XShapeCombineMask. Shaped windows will look
1440 * ugly, but programs still work. Stefan Wille
1443 gdk_window_shape_combine_mask (GdkWindow *window,
1447 GdkWindowPrivate *window_private;
1450 g_return_if_fail (window != NULL);
1452 /* This is needed, according to raster */
1453 gdk_window_set_override_redirect(window, TRUE);
1455 window_private = (GdkWindowPrivate*) window;
1456 if (window_private->destroyed)
1461 GdkWindowPrivate *pixmap_private;
1463 pixmap_private = (GdkWindowPrivate*) mask;
1464 pixmap = (Pixmap) pixmap_private->xwindow;
1473 XShapeCombineMask (window_private->xdisplay,
1474 window_private->xwindow,
1482 gdk_dnd_drag_addwindow (GdkWindow *window)
1484 GdkWindowPrivate *window_private;
1486 g_return_if_fail (window != NULL);
1488 window_private = (GdkWindowPrivate *) window;
1489 if (window_private->destroyed)
1492 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1494 gdk_dnd.drag_numwindows++;
1495 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1496 gdk_dnd.drag_numwindows
1497 * sizeof(GdkWindow *));
1498 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1499 window_private->dnd_drag_accepted = 0;
1502 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1506 gdk_window_dnd_drag_set (GdkWindow *window,
1511 GdkWindowPrivate *window_private;
1514 g_return_if_fail (window != NULL);
1515 window_private = (GdkWindowPrivate *) window;
1516 if (window_private->destroyed)
1519 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1523 g_return_if_fail(typelist != NULL);
1525 if (window_private->dnd_drag_data_numtypesavail > 3)
1527 window_private->dnd_drag_data_numtypesavail = numtypes;
1529 window_private->dnd_drag_data_typesavail =
1530 g_realloc (window_private->dnd_drag_data_typesavail,
1531 (numtypes + 1) * sizeof (GdkAtom));
1533 for (i = 0; i < numtypes; i++)
1535 /* Allow blanket use of ALL to get anything... */
1536 if (strcmp (typelist[i], "ALL"))
1537 window_private->dnd_drag_data_typesavail[i] =
1538 gdk_atom_intern (typelist[i], FALSE);
1540 window_private->dnd_drag_data_typesavail[i] = None;
1544 * set our extended type list if we need to
1547 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1548 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1549 (guchar *)(window_private->dnd_drag_data_typesavail
1550 + (sizeof(GdkAtom) * 3)),
1551 (numtypes - 3) * sizeof(GdkAtom));
1553 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1557 g_free (window_private->dnd_drag_data_typesavail);
1558 window_private->dnd_drag_data_typesavail = NULL;
1559 window_private->dnd_drag_data_numtypesavail = 0;
1564 gdk_window_dnd_drop_set (GdkWindow *window,
1568 guint8 destructive_op)
1570 GdkWindowPrivate *window_private;
1573 g_return_if_fail (window != NULL);
1574 window_private = (GdkWindowPrivate *) window;
1575 if (window_private->destroyed)
1578 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1581 g_return_if_fail(typelist != NULL);
1583 window_private->dnd_drop_data_numtypesavail = numtypes;
1585 window_private->dnd_drop_data_typesavail =
1586 g_realloc (window_private->dnd_drop_data_typesavail,
1587 (numtypes + 1) * sizeof (GdkAtom));
1589 for (i = 0; i < numtypes; i++)
1590 window_private->dnd_drop_data_typesavail[i] =
1591 gdk_atom_intern (typelist[i], FALSE);
1593 window_private->dnd_drop_destructive_op = destructive_op;
1598 * This is used to reply to a GDK_DRAG_REQUEST event
1599 * (which may be generated by XdeRequest or a confirmed drop...
1602 gdk_window_dnd_data_set (GdkWindow *window,
1605 gulong data_numbytes)
1607 GdkWindowPrivate *window_private;
1609 GdkEventDropDataAvailable tmp_ev;
1612 g_return_if_fail (window != NULL);
1613 g_return_if_fail (event != NULL);
1614 g_return_if_fail (data != NULL);
1615 g_return_if_fail (data_numbytes > 0);
1616 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1618 window_private = (GdkWindowPrivate *) window;
1619 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1620 if (window_private->destroyed)
1623 /* We set the property on our window... */
1624 gdk_property_change (window, window_private->dnd_drag_data_type,
1625 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1627 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1629 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1634 * Then we send the event to tell the receiving window that the
1637 tmp_ev.u.allflags = 0;
1638 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1639 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1641 sev.xclient.type = ClientMessage;
1642 sev.xclient.format = 32;
1643 sev.xclient.window = event->dragrequest.requestor;
1644 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1645 sev.xclient.data.l[0] = window_private->xwindow;
1646 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1647 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1649 if (event->dragrequest.isdrop)
1650 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1651 (event->dragrequest.drop_coords.y << 16);
1653 sev.xclient.data.l[3] = 0;
1655 sev.xclient.data.l[4] = event->dragrequest.timestamp;
1657 if (!gdk_send_xevent (event->dragrequest.requestor, False,
1658 StructureNotifyMask, &sev))
1659 GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1660 event->dragrequest.requestor));
1665 gdk_window_add_filter (GdkWindow *window,
1666 GdkFilterFunc function,
1669 GdkWindowPrivate *private;
1671 GdkEventFilter *filter;
1673 private = (GdkWindowPrivate*) window;
1674 if (private && private->destroyed)
1678 tmp_list = private->filters;
1680 tmp_list = gdk_default_filters;
1684 filter = (GdkEventFilter *)tmp_list->data;
1685 if ((filter->function == function) && (filter->data == data))
1687 tmp_list = tmp_list->next;
1690 filter = g_new (GdkEventFilter, 1);
1691 filter->function = function;
1692 filter->data = data;
1695 private->filters = g_list_append (private->filters, filter);
1697 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1701 gdk_window_remove_filter (GdkWindow *window,
1702 GdkFilterFunc function,
1705 GdkWindowPrivate *private;
1707 GdkEventFilter *filter;
1709 private = (GdkWindowPrivate*) window;
1712 tmp_list = private->filters;
1714 tmp_list = gdk_default_filters;
1718 filter = (GdkEventFilter *)tmp_list->data;
1719 tmp_list = tmp_list->next;
1721 if ((filter->function == function) && (filter->data == data))
1724 private->filters = g_list_remove_link (private->filters, tmp_list);
1726 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1727 g_list_free_1 (tmp_list);
1736 gdk_window_set_override_redirect(GdkWindow *window,
1737 gboolean override_redirect)
1739 GdkWindowPrivate *private;
1740 XSetWindowAttributes attr;
1742 g_return_if_fail (window != NULL);
1743 private = (GdkWindowPrivate*) window;
1744 if (private->destroyed)
1747 attr.override_redirect = (override_redirect == FALSE)?False:True;
1748 XChangeWindowAttributes(gdk_display,
1749 ((GdkWindowPrivate *)window)->xwindow,
1755 gdk_window_set_icon (GdkWindow *window,
1756 GdkWindow *icon_window,
1761 GdkWindowPrivate *window_private;
1762 GdkWindowPrivate *private;
1764 g_return_if_fail (window != NULL);
1765 window_private = (GdkWindowPrivate*) window;
1766 if (window_private->destroyed)
1771 if (icon_window != NULL)
1773 private = (GdkWindowPrivate *)icon_window;
1774 wm_hints.flags |= IconWindowHint;
1775 wm_hints.icon_window = private->xwindow;
1780 private = (GdkWindowPrivate *)pixmap;
1781 wm_hints.flags |= IconPixmapHint;
1782 wm_hints.icon_pixmap = private->xwindow;
1787 private = (GdkWindowPrivate *)mask;
1788 wm_hints.flags |= IconMaskHint;
1789 wm_hints.icon_mask = private->xwindow;
1792 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1796 gdk_window_set_icon_name (GdkWindow *window,
1799 GdkWindowPrivate *window_private;
1800 XTextProperty property;
1803 g_return_if_fail (window != NULL);
1804 window_private = (GdkWindowPrivate*) window;
1805 if (window_private->destroyed)
1807 res = XmbTextListToTextProperty (window_private->xdisplay,
1808 &name, 1, XStdICCTextStyle,
1812 g_warning("Error converting icon name to text property: %d\n", res);
1816 XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1819 XFree(property.value);
1823 gdk_window_set_group (GdkWindow *window,
1827 GdkWindowPrivate *window_private;
1828 GdkWindowPrivate *private;
1830 g_return_if_fail (window != NULL);
1831 g_return_if_fail (leader != NULL);
1832 window_private = (GdkWindowPrivate*) window;
1833 if (window_private->destroyed)
1836 private = (GdkWindowPrivate *)leader;
1837 wm_hints.flags = WindowGroupHint;
1838 wm_hints.window_group = private->xwindow;
1840 XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1844 gdk_window_set_mwm_hints (GdkWindow *window,
1845 MotifWmHints *new_hints)
1847 static Atom hints_atom = None;
1848 MotifWmHints *hints;
1854 GdkWindowPrivate *window_private;
1856 g_return_if_fail (window != NULL);
1857 window_private = (GdkWindowPrivate*) window;
1858 if (window_private->destroyed)
1862 hints_atom = XInternAtom (window_private->xdisplay,
1863 _XA_MOTIF_WM_HINTS, FALSE);
1865 XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1866 hints_atom, 0, sizeof(MotifWmHints)/4,
1867 False, AnyPropertyType, &type, &format, &nitems,
1868 &bytes_after, (guchar **)&hints);
1874 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1876 hints->flags |= MWM_HINTS_FUNCTIONS;
1877 hints->functions = new_hints->functions;
1879 if (new_hints->flags & MWM_HINTS_DECORATIONS)
1881 hints->flags |= MWM_HINTS_DECORATIONS;
1882 hints->decorations = new_hints->decorations;
1886 XChangeProperty (window_private->xdisplay, window_private->xwindow,
1887 hints_atom, hints_atom, 32, PropModeReplace,
1888 (guchar *)hints, sizeof(MotifWmHints)/4);
1890 if (hints != new_hints)
1895 gdk_window_set_decorations (GdkWindow *window,
1896 GdkWMDecoration decorations)
1900 hints.flags = MWM_HINTS_DECORATIONS;
1901 hints.decorations = decorations;
1903 gdk_window_set_mwm_hints (window, &hints);
1907 gdk_window_set_functions (GdkWindow *window,
1908 GdkWMFunction functions)
1912 hints.flags = MWM_HINTS_FUNCTIONS;
1913 hints.functions = functions;
1915 gdk_window_set_mwm_hints (window, &hints);