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.
19 #include <X11/Xutil.h>
20 #include <X11/Xatom.h>
21 #include <X11/extensions/shape.h>
22 #include <netinet/in.h>
25 #include "gdkprivate.h"
28 int nevent_masks = 16;
29 int event_mask_table[18] =
33 PointerMotionHintMask,
38 ButtonPressMask | OwnerGrabButtonMask,
39 ButtonReleaseMask | OwnerGrabButtonMask,
55 XWindowAttributes xattributes;
58 unsigned int border_width;
62 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
63 &x, &y, &width, &height, &border_width, &depth);
64 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
66 gdk_root_parent.xdisplay = gdk_display;
67 gdk_root_parent.xwindow = gdk_root_window;
68 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
69 gdk_root_parent.window.user_data = NULL;
73 gdk_window_new (GdkWindow *parent,
74 GdkWindowAttr *attributes,
78 GdkWindowPrivate *private;
79 GdkWindowPrivate *parent_private;
81 GdkColormap *colormap;
82 Display *parent_display;
85 XSetWindowAttributes xattributes;
86 long xattributes_mask;
87 XSizeHints size_hints;
89 XTextProperty text_property;
90 XClassHint *class_hint;
96 g_return_val_if_fail (attributes != NULL, NULL);
99 parent = (GdkWindow*) &gdk_root_parent;
101 parent_private = (GdkWindowPrivate*) parent;
102 xparent = parent_private->xwindow;
103 parent_display = parent_private->xdisplay;
105 private = g_new (GdkWindowPrivate, 1);
106 window = (GdkWindow*) private;
108 private->parent = parent;
109 private->xdisplay = parent_display;
110 private->destroyed = FALSE;
111 private->resize_count = 0;
112 private->ref_count = 1;
113 xattributes_mask = 0;
115 if (attributes_mask & GDK_WA_X)
120 if (attributes_mask & GDK_WA_Y)
127 private->width = (attributes->width > 1) ? (attributes->width) : (1);
128 private->height = (attributes->height > 1) ? (attributes->height) : (1);
129 private->window_type = attributes->window_type;
130 private->extension_events = FALSE;
131 private->dnd_drag_data_type = None;
132 private->dnd_drag_data_typesavail =
133 private->dnd_drop_data_typesavail = NULL;
134 private->dnd_drop_enabled = private->dnd_drag_enabled =
135 private->dnd_drag_accepted = private->dnd_drag_datashow =
136 private->dnd_drop_data_numtypesavail =
137 private->dnd_drag_data_numtypesavail = 0;
138 private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
140 window->user_data = NULL;
142 if (attributes_mask & GDK_WA_VISUAL)
143 visual = attributes->visual;
145 visual = gdk_visual_get_system ();
146 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
148 xattributes.event_mask = StructureNotifyMask;
149 for (i = 0; i < nevent_masks; i++)
151 if (attributes->event_mask & (1 << (i + 1)))
152 xattributes.event_mask |= event_mask_table[i];
155 if (xattributes.event_mask)
156 xattributes_mask |= CWEventMask;
158 if (attributes->wclass == GDK_INPUT_OUTPUT)
161 depth = visual->depth;
163 if (attributes_mask & GDK_WA_COLORMAP)
164 colormap = attributes->colormap;
166 colormap = gdk_colormap_get_system ();
168 xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
169 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
170 xattributes_mask |= CWBorderPixel | CWBackPixel;
172 switch (private->window_type)
174 case GDK_WINDOW_TOPLEVEL:
175 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
176 xattributes_mask |= CWColormap;
178 xparent = gdk_root_window;
181 case GDK_WINDOW_CHILD:
182 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
183 xattributes_mask |= CWColormap;
186 case GDK_WINDOW_DIALOG:
187 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
188 xattributes_mask |= CWColormap;
190 xparent = gdk_root_window;
193 case GDK_WINDOW_TEMP:
194 xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
195 xattributes_mask |= CWColormap;
197 xparent = gdk_root_window;
199 xattributes.save_under = True;
200 xattributes.override_redirect = True;
201 xattributes.cursor = None;
202 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
204 case GDK_WINDOW_ROOT:
205 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
207 case GDK_WINDOW_PIXMAP:
208 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
219 private->xwindow = XCreateWindow (private->xdisplay, xparent,
220 x, y, private->width, private->height,
221 0, depth, class, xvisual,
222 xattributes_mask, &xattributes);
223 gdk_xid_table_insert (&private->xwindow, window);
225 switch (private->window_type)
227 case GDK_WINDOW_DIALOG:
228 XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
229 case GDK_WINDOW_TOPLEVEL:
230 case GDK_WINDOW_TEMP:
231 XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
233 case GDK_WINDOW_CHILD:
234 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
235 (colormap != gdk_colormap_get_system ()) &&
236 (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
238 g_print ("adding colormap window\n");
239 gdk_window_add_colormap_windows (window);
246 size_hints.flags = PSize | PBaseSize;
247 size_hints.width = private->width;
248 size_hints.height = private->height;
249 size_hints.base_width = private->width;
250 size_hints.base_height = private->height;
252 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
253 wm_hints.window_group = gdk_leader_window;
254 wm_hints.input = True;
255 wm_hints.initial_state = NormalState;
257 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
258 XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
260 if (attributes_mask & GDK_WA_TITLE)
261 title = attributes->title;
263 title = gdk_progname;
265 if (XStringListToTextProperty (&title, 1, &text_property))
267 XSetWMName (private->xdisplay, private->xwindow, &text_property);
268 XSetWMIconName (private->xdisplay, private->xwindow, &text_property);
269 XFree (text_property.value);
272 if (attributes_mask & GDK_WA_WMCLASS)
274 class_hint = XAllocClassHint ();
275 class_hint->res_name = attributes->wmclass_name;
276 class_hint->res_class = attributes->wmclass_class;
277 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
281 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
282 (attributes->cursor) :
289 gdk_window_foreign_new (guint32 anid)
292 GdkWindowPrivate *private;
293 XWindowAttributes attrs;
295 private = g_new (GdkWindowPrivate, 1);
296 window = (GdkWindow*) private;
298 XGetWindowAttributes (gdk_display, anid, &attrs);
300 private->parent = NULL;
301 private->xwindow = anid;
302 private->xdisplay = gdk_display;
303 private->x = attrs.x;
304 private->y = attrs.y;
305 private->width = attrs.width;
306 private->height = attrs.height;
307 private->resize_count = 0;
308 private->ref_count = 1;
309 if (anid == attrs.root)
310 private->window_type = GDK_WINDOW_ROOT;
312 private->window_type = GDK_WINDOW_TOPLEVEL;
313 /* the above is probably wrong, but it may not be worth the extra
314 X call to get it right */
316 private->destroyed = FALSE;
317 private->extension_events = 0;
319 window->user_data = NULL;
321 gdk_xid_table_insert (&private->xwindow, window);
327 gdk_window_destroy (GdkWindow *window)
329 GdkWindowPrivate *private;
330 GdkWindowPrivate *temp_private;
331 GdkWindow *temp_window;
335 g_return_if_fail (window != NULL);
337 private = (GdkWindowPrivate*) window;
338 if(private->dnd_drag_data_numtypesavail > 0)
340 free(private->dnd_drag_data_typesavail);
341 private->dnd_drag_data_typesavail = NULL;
343 if(private->dnd_drop_data_numtypesavail > 0)
345 free(private->dnd_drop_data_typesavail);
346 private->dnd_drop_data_typesavail = NULL;
349 switch (private->window_type)
351 case GDK_WINDOW_TOPLEVEL:
352 case GDK_WINDOW_CHILD:
353 case GDK_WINDOW_DIALOG:
354 case GDK_WINDOW_TEMP:
355 if (private->ref_count >= 1)
356 private->ref_count -= 1;
358 if (!private->destroyed || (private->destroyed == 2))
360 children = gdk_window_get_children (window);
365 temp_window = tmp->data;
368 temp_private = (GdkWindowPrivate*) temp_window;
369 if (temp_private && !temp_private->destroyed)
370 /* Removes some nice coredumps... /David */
372 temp_private->destroyed = 2;
373 temp_private->ref_count += 1;
374 gdk_window_destroy (temp_window);
378 g_list_free (children);
380 if (!private->destroyed)
381 XDestroyWindow (private->xdisplay, private->xwindow);
382 private->destroyed = TRUE;
386 case GDK_WINDOW_ROOT:
387 g_error ("attempted to destroy root window");
390 case GDK_WINDOW_PIXMAP:
391 g_warning ("called gdk_window_destroy on a pixmap (use gdk_pixmap_destroy)");
392 gdk_pixmap_destroy (window);
398 gdk_window_real_destroy (GdkWindow *window)
400 GdkWindowPrivate *private;
402 g_return_if_fail (window != NULL);
404 private = (GdkWindowPrivate*) window;
406 if (private->extension_events != 0)
407 gdk_input_window_destroy (window);
409 if (private->ref_count == 0)
411 gdk_xid_table_remove (private->xwindow);
417 gdk_window_ref (GdkWindow *window)
419 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
420 g_return_if_fail (window != NULL);
422 private->ref_count += 1;
427 gdk_window_unref (GdkWindow *window)
429 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
430 g_return_if_fail (window != NULL);
432 private->ref_count -= 1;
433 if (private->ref_count == 0)
434 gdk_window_real_destroy (window);
438 gdk_window_show (GdkWindow *window)
440 GdkWindowPrivate *private;
442 g_return_if_fail (window != NULL);
444 private = (GdkWindowPrivate*) window;
445 if (!private->destroyed)
447 XRaiseWindow (private->xdisplay, private->xwindow);
448 XMapWindow (private->xdisplay, private->xwindow);
453 gdk_window_hide (GdkWindow *window)
455 GdkWindowPrivate *private;
457 g_return_if_fail (window != NULL);
459 private = (GdkWindowPrivate*) window;
460 if (!private->destroyed)
461 XUnmapWindow (private->xdisplay, private->xwindow);
465 gdk_window_move (GdkWindow *window,
469 GdkWindowPrivate *private;
471 g_return_if_fail (window != NULL);
473 private = (GdkWindowPrivate*) window;
474 XMoveWindow (private->xdisplay, private->xwindow, x, y);
476 if (private->window_type == GDK_WINDOW_CHILD)
484 gdk_window_resize (GdkWindow *window,
488 GdkWindowPrivate *private;
490 g_return_if_fail (window != NULL);
497 private = (GdkWindowPrivate*) window;
499 if (!private->destroyed &&
500 ((private->resize_count > 0) ||
501 (private->width != (guint16) width) ||
502 (private->height != (guint16) height)))
504 XResizeWindow (private->xdisplay, private->xwindow, width, height);
505 private->resize_count += 1;
507 if (private->window_type == GDK_WINDOW_CHILD)
509 private->width = width;
510 private->height = height;
516 gdk_window_move_resize (GdkWindow *window,
522 GdkWindowPrivate *private;
524 g_return_if_fail (window != NULL);
531 private = (GdkWindowPrivate*) window;
532 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
534 if (!private->destroyed &&
535 (private->window_type == GDK_WINDOW_CHILD))
539 private->width = width;
540 private->height = height;
545 gdk_window_reparent (GdkWindow *window,
546 GdkWindow *new_parent,
550 GdkWindowPrivate *window_private;
551 GdkWindowPrivate *parent_private;
553 g_return_if_fail (window != NULL);
556 new_parent = (GdkWindow*) &gdk_root_parent;
558 window_private = (GdkWindowPrivate*) window;
559 parent_private = (GdkWindowPrivate*) new_parent;
561 XReparentWindow (window_private->xdisplay,
562 window_private->xwindow,
563 parent_private->xwindow,
568 gdk_window_clear (GdkWindow *window)
570 GdkWindowPrivate *private;
572 g_return_if_fail (window != NULL);
574 private = (GdkWindowPrivate*) window;
576 XClearWindow (private->xdisplay, private->xwindow);
580 gdk_window_clear_area (GdkWindow *window,
586 GdkWindowPrivate *private;
588 g_return_if_fail (window != NULL);
590 private = (GdkWindowPrivate*) window;
592 if (!private->destroyed)
593 XClearArea (private->xdisplay, private->xwindow,
594 x, y, width, height, False);
598 gdk_window_clear_area_e (GdkWindow *window,
604 GdkWindowPrivate *private;
606 g_return_if_fail (window != NULL);
608 private = (GdkWindowPrivate*) window;
610 if (!private->destroyed)
611 XClearArea (private->xdisplay, private->xwindow,
612 x, y, width, height, True);
616 gdk_window_copy_area (GdkWindow *window,
620 GdkWindow *source_window,
626 GdkWindowPrivate *src_private;
627 GdkWindowPrivate *dest_private;
628 GdkGCPrivate *gc_private;
630 g_return_if_fail (window != NULL);
631 g_return_if_fail (gc != NULL);
633 if (source_window == NULL)
634 source_window = window;
636 src_private = (GdkWindowPrivate*) source_window;
637 dest_private = (GdkWindowPrivate*) window;
638 gc_private = (GdkGCPrivate*) gc;
640 if (!src_private->destroyed && !dest_private->destroyed)
642 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
651 gdk_window_raise (GdkWindow *window)
653 GdkWindowPrivate *private;
655 g_return_if_fail (window != NULL);
657 private = (GdkWindowPrivate*) window;
659 if (!private->destroyed)
660 XRaiseWindow (private->xdisplay, private->xwindow);
664 gdk_window_lower (GdkWindow *window)
666 GdkWindowPrivate *private;
668 g_return_if_fail (window != NULL);
670 private = (GdkWindowPrivate*) window;
672 if (!private->destroyed)
673 XLowerWindow (private->xdisplay, private->xwindow);
677 gdk_window_set_user_data (GdkWindow *window,
680 g_return_if_fail (window != NULL);
682 window->user_data = user_data;
686 gdk_window_set_hints (GdkWindow *window,
695 GdkWindowPrivate *private;
696 XSizeHints size_hints;
698 g_return_if_fail (window != NULL);
700 private = (GdkWindowPrivate*) window;
701 size_hints.flags = 0;
703 if (flags & GDK_HINT_POS)
705 size_hints.flags |= PPosition;
710 if (flags & GDK_HINT_MIN_SIZE)
712 size_hints.flags |= PMinSize;
713 size_hints.min_width = min_width;
714 size_hints.min_height = min_height;
717 if (flags & GDK_HINT_MAX_SIZE)
719 size_hints.flags |= PMaxSize;
720 size_hints.max_width = max_width;
721 size_hints.max_height = max_height;
725 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
729 gdk_window_set_title (GdkWindow *window,
732 GdkWindowPrivate *private;
734 g_return_if_fail (window != NULL);
736 private = (GdkWindowPrivate*) window;
737 XStoreName (private->xdisplay, private->xwindow, title);
738 XSetIconName (private->xdisplay, private->xwindow, title);
742 gdk_window_set_background (GdkWindow *window,
745 GdkWindowPrivate *private;
747 g_return_if_fail (window != NULL);
749 private = (GdkWindowPrivate*) window;
750 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
754 gdk_window_set_back_pixmap (GdkWindow *window,
756 gint parent_relative)
758 GdkWindowPrivate *window_private;
759 GdkPixmapPrivate *pixmap_private;
762 g_return_if_fail (window != NULL);
764 window_private = (GdkWindowPrivate*) window;
765 pixmap_private = (GdkPixmapPrivate*) pixmap;
768 xpixmap = pixmap_private->xwindow;
773 xpixmap = ParentRelative;
775 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
779 gdk_window_set_cursor (GdkWindow *window,
782 GdkWindowPrivate *window_private;
783 GdkCursorPrivate *cursor_private;
786 g_return_if_fail (window != NULL);
788 window_private = (GdkWindowPrivate*) window;
789 cursor_private = (GdkCursorPrivate*) cursor;
794 xcursor = cursor_private->xcursor;
796 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
800 gdk_window_set_colormap (GdkWindow *window,
801 GdkColormap *colormap)
803 GdkWindowPrivate *window_private;
804 GdkColormapPrivate *colormap_private;
806 g_return_if_fail (window != NULL);
807 g_return_if_fail (colormap != NULL);
809 window_private = (GdkWindowPrivate*) window;
810 colormap_private = (GdkColormapPrivate*) colormap;
812 XSetWindowColormap (window_private->xdisplay,
813 window_private->xwindow,
814 colormap_private->xcolormap);
816 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
817 gdk_window_add_colormap_windows (window);
821 gdk_window_get_user_data (GdkWindow *window,
824 g_return_if_fail (window != NULL);
826 *data = window->user_data;
830 gdk_window_get_geometry (GdkWindow *window,
837 GdkWindowPrivate *window_private;
847 window = (GdkWindow*) &gdk_root_parent;
849 window_private = (GdkWindowPrivate*) window;
851 XGetGeometry (window_private->xdisplay, window_private->xwindow,
852 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
867 gdk_window_get_position (GdkWindow *window,
871 GdkWindowPrivate *window_private;
873 g_return_if_fail (window != NULL);
875 window_private = (GdkWindowPrivate*) window;
878 *x = window_private->x;
880 *y = window_private->y;
884 gdk_window_get_size (GdkWindow *window,
888 GdkWindowPrivate *window_private;
890 g_return_if_fail (window != NULL);
892 window_private = (GdkWindowPrivate*) window;
895 *width = window_private->width;
897 *height = window_private->height;
902 gdk_window_get_visual (GdkWindow *window)
904 GdkWindowPrivate *window_private;
905 XWindowAttributes window_attributes;
907 g_return_val_if_fail (window != NULL, NULL);
909 window_private = (GdkWindowPrivate*) window;
910 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
911 window_private = (GdkWindowPrivate*) window_private->parent;
915 XGetWindowAttributes (window_private->xdisplay,
916 window_private->xwindow,
919 return gdk_visual_lookup (window_attributes.visual);
926 gdk_window_get_colormap (GdkWindow *window)
928 GdkWindowPrivate *window_private;
929 XWindowAttributes window_attributes;
931 g_return_val_if_fail (window != NULL, NULL);
933 window_private = (GdkWindowPrivate*) window;
935 XGetWindowAttributes (window_private->xdisplay,
936 window_private->xwindow,
939 return gdk_colormap_lookup (window_attributes.colormap);
943 gdk_window_get_type (GdkWindow *window)
945 GdkWindowPrivate *window_private;
947 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
949 window_private = (GdkWindowPrivate*) window;
950 return window_private->window_type;
954 gdk_window_get_origin (GdkWindow *window,
958 GdkWindowPrivate *private;
963 g_return_val_if_fail (window != NULL, 0);
965 private = (GdkWindowPrivate*) window;
967 return_val = XTranslateCoordinates (private->xdisplay,
982 gdk_window_get_pointer (GdkWindow *window,
985 GdkModifierType *mask)
987 GdkWindowPrivate *private;
988 GdkWindow *return_val;
996 window = (GdkWindow*) &gdk_root_parent;
998 private = (GdkWindowPrivate*) window;
1001 if (XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1002 &rootx, &rooty, &winx, &winy, &xmask))
1006 if (mask) *mask = xmask;
1009 return_val = gdk_window_lookup (child);
1016 gdk_window_get_parent (GdkWindow *window)
1018 g_return_val_if_fail (window != NULL, NULL);
1020 return ((GdkWindowPrivate*) window)->parent;
1024 gdk_window_get_toplevel (GdkWindow *window)
1026 GdkWindowPrivate *private;
1028 g_return_val_if_fail (window != NULL, NULL);
1030 private = (GdkWindowPrivate*) window;
1032 while (private->window_type == GDK_WINDOW_CHILD)
1034 window = ((GdkWindowPrivate*) window)->parent;
1035 private = (GdkWindowPrivate*) window;
1042 gdk_window_get_children (GdkWindow *window)
1044 GdkWindowPrivate *private;
1050 unsigned int nchildren;
1053 g_return_val_if_fail (window != NULL, NULL);
1055 private = (GdkWindowPrivate*) window;
1057 XQueryTree (private->xdisplay, private->xwindow,
1058 &root, &parent, &xchildren, &nchildren);
1064 for (i = 0; i < nchildren; i++)
1066 child = gdk_window_lookup (xchildren[i]);
1068 children = g_list_prepend (children, child);
1078 gdk_window_get_events (GdkWindow *window)
1080 XWindowAttributes attrs;
1081 GdkEventMask event_mask;
1084 XGetWindowAttributes (gdk_display, ((GdkWindowPrivate *)window)->xwindow,
1088 for (i = 0; i < nevent_masks; i++)
1090 if (attrs.your_event_mask & event_mask_table[i])
1091 event_mask |= 1 << (i + 1);
1098 gdk_window_set_events (GdkWindow *window,
1099 GdkEventMask event_mask)
1104 xevent_mask = StructureNotifyMask;
1105 for (i = 0; i < nevent_masks; i++)
1107 if (event_mask & (1 << (i + 1)))
1108 xevent_mask |= event_mask_table[i];
1111 XSelectInput (gdk_display, ((GdkWindowPrivate *)window)->xwindow,
1116 gdk_window_add_colormap_windows (GdkWindow *window)
1118 GdkWindow *toplevel;
1119 GdkWindowPrivate *toplevel_private;
1120 GdkWindowPrivate *window_private;
1121 Window *old_windows;
1122 Window *new_windows;
1125 g_return_if_fail (window != NULL);
1127 toplevel = gdk_window_get_toplevel (window);
1128 toplevel_private = (GdkWindowPrivate*) toplevel;
1129 window_private = (GdkWindowPrivate*) window;
1131 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1132 toplevel_private->xwindow,
1133 &old_windows, &count))
1139 for (i = 0; i < count; i++)
1140 if (old_windows[i] == window_private->xwindow)
1143 new_windows = g_new (Window, count + 1);
1145 for (i = 0; i < count; i++)
1146 new_windows[i] = old_windows[i];
1147 new_windows[count] = window_private->xwindow;
1149 XSetWMColormapWindows (toplevel_private->xdisplay,
1150 toplevel_private->xwindow,
1151 new_windows, count + 1);
1153 g_free (new_windows);
1155 XFree (old_windows);
1159 * This needs the X11 shape extension.
1160 * If not available, simply remove the call to
1161 * XShapeCombineMask. Shaped windows will look
1162 * ugly, but programs still work. Stefan Wille
1165 gdk_window_shape_combine_mask (GdkWindow *window,
1169 GdkWindowPrivate *window_private;
1170 GdkWindowPrivate *pixmap_private;
1172 g_return_if_fail (window != NULL);
1173 g_return_if_fail (mask != NULL);
1175 window_private = (GdkWindowPrivate*) window;
1176 pixmap_private = (GdkWindowPrivate*) mask;
1178 XShapeCombineMask (window_private->xdisplay,
1179 window_private->xwindow,
1182 (Pixmap)pixmap_private->xwindow,
1187 gdk_dnd_drag_addwindow (GdkWindow *window)
1189 GdkWindowPrivate *window_private;
1191 g_return_if_fail (window != NULL);
1193 window_private = (GdkWindowPrivate *) window;
1195 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1197 gdk_dnd.drag_numwindows++;
1198 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1199 gdk_dnd.drag_numwindows
1200 * sizeof(GdkWindow *));
1201 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1202 window_private->dnd_drag_accepted = 0;
1205 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1209 gdk_window_dnd_drag_set (GdkWindow *window,
1214 GdkWindowPrivate *window_private;
1217 g_return_if_fail (window != NULL);
1218 window_private = (GdkWindowPrivate *) window;
1220 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1224 g_return_if_fail(typelist != NULL);
1226 if (window_private->dnd_drag_data_numtypesavail > 3)
1228 window_private->dnd_drag_data_numtypesavail = numtypes;
1230 window_private->dnd_drag_data_typesavail =
1231 g_realloc (window_private->dnd_drag_data_typesavail,
1232 (numtypes + 1) * sizeof (GdkAtom));
1234 for (i = 0; i < numtypes; i++)
1236 /* Allow blanket use of ALL to get anything... */
1237 if (strcmp (typelist[i], "ALL"))
1238 window_private->dnd_drag_data_typesavail[i] =
1239 gdk_atom_intern (typelist[i], FALSE);
1241 window_private->dnd_drag_data_typesavail[i] = None;
1245 * set our extended type list if we need to
1248 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1249 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1250 (guchar *)(window_private->dnd_drag_data_typesavail
1251 + (sizeof(GdkAtom) * 3)),
1252 (numtypes - 3) * sizeof(GdkAtom));
1254 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1258 free (window_private->dnd_drag_data_typesavail);
1259 window_private->dnd_drag_data_typesavail = NULL;
1260 window_private->dnd_drag_data_numtypesavail = 0;
1265 gdk_window_dnd_drop_set (GdkWindow *window,
1269 guint8 destructive_op)
1271 GdkWindowPrivate *window_private;
1274 g_return_if_fail (window != NULL);
1276 window_private = (GdkWindowPrivate *) window;
1278 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1281 g_return_if_fail(typelist != NULL);
1283 window_private->dnd_drop_data_numtypesavail = numtypes;
1285 window_private->dnd_drop_data_typesavail =
1286 g_realloc (window_private->dnd_drop_data_typesavail,
1287 (numtypes + 1) * sizeof (GdkAtom));
1289 for (i = 0; i < numtypes; i++)
1290 window_private->dnd_drop_data_typesavail[i] =
1291 gdk_atom_intern (typelist[i], FALSE);
1293 window_private->dnd_drop_destructive_op = destructive_op;
1298 * This is used to reply to a GDK_DRAG_REQUEST event
1299 * (which may be generated by XdeRequest or a confirmed drop...
1302 gdk_window_dnd_data_set (GdkWindow *window,
1305 gulong data_numbytes)
1307 GdkWindowPrivate *window_private;
1309 GdkEventDropDataAvailable tmp_ev;
1312 g_return_if_fail (window != NULL);
1313 g_return_if_fail (event != NULL);
1314 g_return_if_fail (data != NULL);
1315 g_return_if_fail (data_numbytes > 0);
1316 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1318 g_free (event->dragrequest.data_type);
1319 event->dragrequest.data_type = NULL;
1321 window_private = (GdkWindowPrivate *) window;
1322 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1324 /* We set the property on our window... */
1325 gdk_property_change (window, window_private->dnd_drag_data_type,
1326 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1328 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1329 g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1333 * Then we send the event to tell the receiving window that the
1336 tmp_ev.u.allflags = 0;
1337 tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1338 tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1340 sev.xclient.type = ClientMessage;
1341 sev.xclient.format = 32;
1342 sev.xclient.window = event->dragrequest.requestor;
1343 sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1344 sev.xclient.data.l[0] = window_private->xwindow;
1345 sev.xclient.data.l[1] = tmp_ev.u.allflags;
1346 sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1348 if (event->dragrequest.isdrop)
1349 sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1350 (event->dragrequest.drop_coords.y << 16);
1352 sev.xclient.data.l[3] = 0;
1354 sev.xclient.data.l[4] = 0;
1356 XSendEvent (gdk_display, event->dragrequest.requestor, False,