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>
24 #include "../config.h"
26 #include "gdkprivate.h"
29 int nevent_masks = 16;
30 int event_mask_table[18] =
34 PointerMotionHintMask,
39 ButtonPressMask | OwnerGrabButtonMask,
40 ButtonReleaseMask | OwnerGrabButtonMask,
56 XWindowAttributes xattributes;
59 unsigned int border_width;
63 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
64 &x, &y, &width, &height, &border_width, &depth);
65 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
67 gdk_root_parent.xdisplay = gdk_display;
68 gdk_root_parent.xwindow = gdk_root_window;
69 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
70 gdk_root_parent.window.user_data = NULL;
74 gdk_window_new (GdkWindow *parent,
75 GdkWindowAttr *attributes,
79 GdkWindowPrivate *private;
80 GdkWindowPrivate *parent_private;
82 GdkColormap *colormap;
83 Display *parent_display;
86 XSetWindowAttributes xattributes;
87 long xattributes_mask;
88 XSizeHints size_hints;
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 XmbSetWMProperties (private->xdisplay, private->xwindow,
270 if (attributes_mask & GDK_WA_WMCLASS)
272 class_hint = XAllocClassHint ();
273 class_hint->res_name = attributes->wmclass_name;
274 class_hint->res_class = attributes->wmclass_class;
275 XSetClassHint (private->xdisplay, private->xwindow, class_hint);
279 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
280 (attributes->cursor) :
287 gdk_window_foreign_new (guint32 anid)
290 GdkWindowPrivate *private;
291 XWindowAttributes attrs;
293 private = g_new (GdkWindowPrivate, 1);
294 window = (GdkWindow*) private;
296 XGetWindowAttributes (gdk_display, anid, &attrs);
298 private->parent = NULL;
299 private->xwindow = anid;
300 private->xdisplay = gdk_display;
301 private->x = attrs.x;
302 private->y = attrs.y;
303 private->width = attrs.width;
304 private->height = attrs.height;
305 private->resize_count = 0;
306 private->ref_count = 1;
307 if (anid == attrs.root)
308 private->window_type = GDK_WINDOW_ROOT;
310 private->window_type = GDK_WINDOW_TOPLEVEL;
311 /* the above is probably wrong, but it may not be worth the extra
312 X call to get it right */
314 private->destroyed = FALSE;
315 private->extension_events = 0;
317 window->user_data = NULL;
319 gdk_xid_table_insert (&private->xwindow, window);
325 gdk_window_destroy (GdkWindow *window)
327 GdkWindowPrivate *private;
328 GdkWindowPrivate *temp_private;
329 GdkWindow *temp_window;
333 g_return_if_fail (window != NULL);
335 private = (GdkWindowPrivate*) window;
336 if(private->dnd_drag_data_numtypesavail > 0)
338 free(private->dnd_drag_data_typesavail);
339 private->dnd_drag_data_typesavail = NULL;
341 if(private->dnd_drop_data_numtypesavail > 0)
343 free(private->dnd_drop_data_typesavail);
344 private->dnd_drop_data_typesavail = NULL;
347 switch (private->window_type)
349 case GDK_WINDOW_TOPLEVEL:
350 case GDK_WINDOW_CHILD:
351 case GDK_WINDOW_DIALOG:
352 case GDK_WINDOW_TEMP:
353 if (private->ref_count >= 1)
354 private->ref_count -= 1;
356 if (!private->destroyed || (private->destroyed == 2))
358 children = gdk_window_get_children (window);
363 temp_window = tmp->data;
366 temp_private = (GdkWindowPrivate*) temp_window;
367 if (temp_private && !temp_private->destroyed)
368 /* Removes some nice coredumps... /David */
370 temp_private->destroyed = 2;
371 temp_private->ref_count += 1;
372 gdk_window_destroy (temp_window);
376 g_list_free (children);
378 if (!private->destroyed)
379 XDestroyWindow (private->xdisplay, private->xwindow);
380 private->destroyed = TRUE;
384 case GDK_WINDOW_ROOT:
385 g_error ("attempted to destroy root window");
388 case GDK_WINDOW_PIXMAP:
389 g_warning ("called gdk_window_destroy on a pixmap (use gdk_pixmap_destroy)");
390 gdk_pixmap_destroy (window);
396 gdk_window_real_destroy (GdkWindow *window)
398 GdkWindowPrivate *private;
400 g_return_if_fail (window != NULL);
402 private = (GdkWindowPrivate*) window;
404 if (private->extension_events != 0)
405 gdk_input_window_destroy (window);
407 if (private->ref_count == 0)
409 gdk_xid_table_remove (private->xwindow);
415 gdk_window_ref (GdkWindow *window)
417 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
418 g_return_if_fail (window != NULL);
420 private->ref_count += 1;
425 gdk_window_unref (GdkWindow *window)
427 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
428 g_return_if_fail (window != NULL);
430 private->ref_count -= 1;
431 if (private->ref_count == 0)
432 gdk_window_real_destroy (window);
436 gdk_window_show (GdkWindow *window)
438 GdkWindowPrivate *private;
440 g_return_if_fail (window != NULL);
442 private = (GdkWindowPrivate*) window;
443 if (!private->destroyed)
445 XRaiseWindow (private->xdisplay, private->xwindow);
446 XMapWindow (private->xdisplay, private->xwindow);
451 gdk_window_hide (GdkWindow *window)
453 GdkWindowPrivate *private;
455 g_return_if_fail (window != NULL);
457 private = (GdkWindowPrivate*) window;
458 if (!private->destroyed)
459 XUnmapWindow (private->xdisplay, private->xwindow);
463 gdk_window_move (GdkWindow *window,
467 GdkWindowPrivate *private;
469 g_return_if_fail (window != NULL);
471 private = (GdkWindowPrivate*) window;
472 XMoveWindow (private->xdisplay, private->xwindow, x, y);
474 if (private->window_type == GDK_WINDOW_CHILD)
482 gdk_window_resize (GdkWindow *window,
486 GdkWindowPrivate *private;
488 g_return_if_fail (window != NULL);
495 private = (GdkWindowPrivate*) window;
497 if (!private->destroyed &&
498 ((private->resize_count > 0) ||
499 (private->width != (guint16) width) ||
500 (private->height != (guint16) height)))
502 XResizeWindow (private->xdisplay, private->xwindow, width, height);
503 private->resize_count += 1;
505 if (private->window_type == GDK_WINDOW_CHILD)
507 private->width = width;
508 private->height = height;
514 gdk_window_move_resize (GdkWindow *window,
520 GdkWindowPrivate *private;
522 g_return_if_fail (window != NULL);
529 private = (GdkWindowPrivate*) window;
530 XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
532 if (!private->destroyed &&
533 (private->window_type == GDK_WINDOW_CHILD))
537 private->width = width;
538 private->height = height;
543 gdk_window_reparent (GdkWindow *window,
544 GdkWindow *new_parent,
548 GdkWindowPrivate *window_private;
549 GdkWindowPrivate *parent_private;
551 g_return_if_fail (window != NULL);
554 new_parent = (GdkWindow*) &gdk_root_parent;
556 window_private = (GdkWindowPrivate*) window;
557 parent_private = (GdkWindowPrivate*) new_parent;
559 XReparentWindow (window_private->xdisplay,
560 window_private->xwindow,
561 parent_private->xwindow,
566 gdk_window_clear (GdkWindow *window)
568 GdkWindowPrivate *private;
570 g_return_if_fail (window != NULL);
572 private = (GdkWindowPrivate*) window;
574 XClearWindow (private->xdisplay, private->xwindow);
578 gdk_window_clear_area (GdkWindow *window,
584 GdkWindowPrivate *private;
586 g_return_if_fail (window != NULL);
588 private = (GdkWindowPrivate*) window;
590 if (!private->destroyed)
591 XClearArea (private->xdisplay, private->xwindow,
592 x, y, width, height, False);
596 gdk_window_clear_area_e (GdkWindow *window,
602 GdkWindowPrivate *private;
604 g_return_if_fail (window != NULL);
606 private = (GdkWindowPrivate*) window;
608 if (!private->destroyed)
609 XClearArea (private->xdisplay, private->xwindow,
610 x, y, width, height, True);
614 gdk_window_copy_area (GdkWindow *window,
618 GdkWindow *source_window,
624 GdkWindowPrivate *src_private;
625 GdkWindowPrivate *dest_private;
626 GdkGCPrivate *gc_private;
628 g_return_if_fail (window != NULL);
629 g_return_if_fail (gc != NULL);
631 if (source_window == NULL)
632 source_window = window;
634 src_private = (GdkWindowPrivate*) source_window;
635 dest_private = (GdkWindowPrivate*) window;
636 gc_private = (GdkGCPrivate*) gc;
638 if (!src_private->destroyed && !dest_private->destroyed)
640 XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
649 gdk_window_raise (GdkWindow *window)
651 GdkWindowPrivate *private;
653 g_return_if_fail (window != NULL);
655 private = (GdkWindowPrivate*) window;
657 if (!private->destroyed)
658 XRaiseWindow (private->xdisplay, private->xwindow);
662 gdk_window_lower (GdkWindow *window)
664 GdkWindowPrivate *private;
666 g_return_if_fail (window != NULL);
668 private = (GdkWindowPrivate*) window;
670 if (!private->destroyed)
671 XLowerWindow (private->xdisplay, private->xwindow);
675 gdk_window_set_user_data (GdkWindow *window,
678 g_return_if_fail (window != NULL);
680 window->user_data = user_data;
684 gdk_window_set_hints (GdkWindow *window,
693 GdkWindowPrivate *private;
694 XSizeHints size_hints;
696 g_return_if_fail (window != NULL);
698 private = (GdkWindowPrivate*) window;
699 size_hints.flags = 0;
701 if (flags & GDK_HINT_POS)
703 size_hints.flags |= PPosition;
708 if (flags & GDK_HINT_MIN_SIZE)
710 size_hints.flags |= PMinSize;
711 size_hints.min_width = min_width;
712 size_hints.min_height = min_height;
715 if (flags & GDK_HINT_MAX_SIZE)
717 size_hints.flags |= PMaxSize;
718 size_hints.max_width = max_width;
719 size_hints.max_height = max_height;
723 XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
727 gdk_window_set_title (GdkWindow *window,
730 GdkWindowPrivate *private;
732 g_return_if_fail (window != NULL);
734 private = (GdkWindowPrivate*) window;
735 XmbSetWMProperties (private->xdisplay, private->xwindow,
736 title, title, NULL, 0, NULL, NULL, NULL);
740 gdk_window_set_background (GdkWindow *window,
743 GdkWindowPrivate *private;
745 g_return_if_fail (window != NULL);
747 private = (GdkWindowPrivate*) window;
748 XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
752 gdk_window_set_back_pixmap (GdkWindow *window,
754 gint parent_relative)
756 GdkWindowPrivate *window_private;
757 GdkPixmapPrivate *pixmap_private;
760 g_return_if_fail (window != NULL);
762 window_private = (GdkWindowPrivate*) window;
763 pixmap_private = (GdkPixmapPrivate*) pixmap;
766 xpixmap = pixmap_private->xwindow;
771 xpixmap = ParentRelative;
773 XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
777 gdk_window_set_cursor (GdkWindow *window,
780 GdkWindowPrivate *window_private;
781 GdkCursorPrivate *cursor_private;
784 g_return_if_fail (window != NULL);
786 window_private = (GdkWindowPrivate*) window;
787 cursor_private = (GdkCursorPrivate*) cursor;
792 xcursor = cursor_private->xcursor;
794 XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
798 gdk_window_set_colormap (GdkWindow *window,
799 GdkColormap *colormap)
801 GdkWindowPrivate *window_private;
802 GdkColormapPrivate *colormap_private;
804 g_return_if_fail (window != NULL);
805 g_return_if_fail (colormap != NULL);
807 window_private = (GdkWindowPrivate*) window;
808 colormap_private = (GdkColormapPrivate*) colormap;
810 XSetWindowColormap (window_private->xdisplay,
811 window_private->xwindow,
812 colormap_private->xcolormap);
814 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
815 gdk_window_add_colormap_windows (window);
819 gdk_window_get_user_data (GdkWindow *window,
822 g_return_if_fail (window != NULL);
824 *data = window->user_data;
828 gdk_window_get_geometry (GdkWindow *window,
835 GdkWindowPrivate *window_private;
845 window = (GdkWindow*) &gdk_root_parent;
847 window_private = (GdkWindowPrivate*) window;
849 XGetGeometry (window_private->xdisplay, window_private->xwindow,
850 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
865 gdk_window_get_position (GdkWindow *window,
869 GdkWindowPrivate *window_private;
871 g_return_if_fail (window != NULL);
873 window_private = (GdkWindowPrivate*) window;
876 *x = window_private->x;
878 *y = window_private->y;
882 gdk_window_get_size (GdkWindow *window,
886 GdkWindowPrivate *window_private;
888 g_return_if_fail (window != NULL);
890 window_private = (GdkWindowPrivate*) window;
893 *width = window_private->width;
895 *height = window_private->height;
900 gdk_window_get_visual (GdkWindow *window)
902 GdkWindowPrivate *window_private;
903 XWindowAttributes window_attributes;
905 g_return_val_if_fail (window != NULL, NULL);
907 window_private = (GdkWindowPrivate*) window;
908 while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
909 window_private = (GdkWindowPrivate*) window_private->parent;
913 XGetWindowAttributes (window_private->xdisplay,
914 window_private->xwindow,
917 return gdk_visual_lookup (window_attributes.visual);
924 gdk_window_get_colormap (GdkWindow *window)
926 GdkWindowPrivate *window_private;
927 XWindowAttributes window_attributes;
929 g_return_val_if_fail (window != NULL, NULL);
931 window_private = (GdkWindowPrivate*) window;
933 XGetWindowAttributes (window_private->xdisplay,
934 window_private->xwindow,
937 return gdk_colormap_lookup (window_attributes.colormap);
941 gdk_window_get_type (GdkWindow *window)
943 GdkWindowPrivate *window_private;
945 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
947 window_private = (GdkWindowPrivate*) window;
948 return window_private->window_type;
952 gdk_window_get_origin (GdkWindow *window,
956 GdkWindowPrivate *private;
961 g_return_val_if_fail (window != NULL, 0);
963 private = (GdkWindowPrivate*) window;
965 return_val = XTranslateCoordinates (private->xdisplay,
980 gdk_window_get_pointer (GdkWindow *window,
983 GdkModifierType *mask)
985 GdkWindowPrivate *private;
986 GdkWindow *return_val;
994 window = (GdkWindow*) &gdk_root_parent;
996 private = (GdkWindowPrivate*) window;
999 if (XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1000 &rootx, &rooty, &winx, &winy, &xmask))
1004 if (mask) *mask = xmask;
1007 return_val = gdk_window_lookup (child);
1014 gdk_window_get_parent (GdkWindow *window)
1016 g_return_val_if_fail (window != NULL, NULL);
1018 return ((GdkWindowPrivate*) window)->parent;
1022 gdk_window_get_toplevel (GdkWindow *window)
1024 GdkWindowPrivate *private;
1026 g_return_val_if_fail (window != NULL, NULL);
1028 private = (GdkWindowPrivate*) window;
1030 while (private->window_type == GDK_WINDOW_CHILD)
1032 window = ((GdkWindowPrivate*) window)->parent;
1033 private = (GdkWindowPrivate*) window;
1040 gdk_window_get_children (GdkWindow *window)
1042 GdkWindowPrivate *private;
1048 unsigned int nchildren;
1051 g_return_val_if_fail (window != NULL, NULL);
1053 private = (GdkWindowPrivate*) window;
1055 XQueryTree (private->xdisplay, private->xwindow,
1056 &root, &parent, &xchildren, &nchildren);
1062 for (i = 0; i < nchildren; i++)
1064 child = gdk_window_lookup (xchildren[i]);
1066 children = g_list_prepend (children, child);
1076 gdk_window_get_events (GdkWindow *window)
1078 XWindowAttributes attrs;
1079 GdkEventMask event_mask;
1082 XGetWindowAttributes (gdk_display, ((GdkWindowPrivate *)window)->xwindow,
1086 for (i = 0; i < nevent_masks; i++)
1088 if (attrs.your_event_mask & event_mask_table[i])
1089 event_mask |= 1 << (i + 1);
1096 gdk_window_set_events (GdkWindow *window,
1097 GdkEventMask event_mask)
1102 xevent_mask = StructureNotifyMask;
1103 for (i = 0; i < nevent_masks; i++)
1105 if (event_mask & (1 << (i + 1)))
1106 xevent_mask |= event_mask_table[i];
1109 XSelectInput (gdk_display, ((GdkWindowPrivate *)window)->xwindow,
1114 gdk_window_add_colormap_windows (GdkWindow *window)
1116 GdkWindow *toplevel;
1117 GdkWindowPrivate *toplevel_private;
1118 GdkWindowPrivate *window_private;
1119 Window *old_windows;
1120 Window *new_windows;
1123 g_return_if_fail (window != NULL);
1125 toplevel = gdk_window_get_toplevel (window);
1126 toplevel_private = (GdkWindowPrivate*) toplevel;
1127 window_private = (GdkWindowPrivate*) window;
1129 if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1130 toplevel_private->xwindow,
1131 &old_windows, &count))
1137 for (i = 0; i < count; i++)
1138 if (old_windows[i] == window_private->xwindow)
1141 new_windows = g_new (Window, count + 1);
1143 for (i = 0; i < count; i++)
1144 new_windows[i] = old_windows[i];
1145 new_windows[count] = window_private->xwindow;
1147 XSetWMColormapWindows (toplevel_private->xdisplay,
1148 toplevel_private->xwindow,
1149 new_windows, count + 1);
1151 g_free (new_windows);
1153 XFree (old_windows);
1157 * This needs the X11 shape extension.
1158 * If not available, simply remove the call to
1159 * XShapeCombineMask. Shaped windows will look
1160 * ugly, but programs still work. Stefan Wille
1163 gdk_window_shape_combine_mask (GdkWindow *window,
1167 GdkWindowPrivate *window_private;
1168 GdkWindowPrivate *pixmap_private;
1170 g_return_if_fail (window != NULL);
1171 g_return_if_fail (mask != NULL);
1173 window_private = (GdkWindowPrivate*) window;
1174 pixmap_private = (GdkWindowPrivate*) mask;
1176 XShapeCombineMask (window_private->xdisplay,
1177 window_private->xwindow,
1180 (Pixmap)pixmap_private->xwindow,
1185 gdk_dnd_drag_addwindow (GdkWindow *window)
1187 GdkWindowPrivate *window_private;
1189 g_return_if_fail (window != NULL);
1191 window_private = (GdkWindowPrivate *) window;
1193 if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1195 gdk_dnd.drag_numwindows++;
1196 gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1197 gdk_dnd.drag_numwindows
1198 * sizeof(GdkWindow *));
1199 gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1200 window_private->dnd_drag_accepted = 0;
1203 g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1207 gdk_window_dnd_drag_set (GdkWindow *window,
1212 GdkWindowPrivate *window_private;
1215 g_return_if_fail (window != NULL);
1216 window_private = (GdkWindowPrivate *) window;
1218 window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1222 g_return_if_fail(typelist != NULL);
1224 if (window_private->dnd_drag_data_numtypesavail > 3)
1226 window_private->dnd_drag_data_numtypesavail = numtypes;
1228 window_private->dnd_drag_data_typesavail =
1229 g_realloc (window_private->dnd_drag_data_typesavail,
1230 (numtypes + 1) * sizeof (GdkAtom));
1232 for (i = 0; i < numtypes; i++)
1234 /* Allow blanket use of ALL to get anything... */
1235 if (strcmp (typelist[i], "ALL"))
1236 window_private->dnd_drag_data_typesavail[i] =
1237 gdk_atom_intern (typelist[i], FALSE);
1239 window_private->dnd_drag_data_typesavail[i] = None;
1243 * set our extended type list if we need to
1246 gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1247 XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1248 (guchar *)(window_private->dnd_drag_data_typesavail
1249 + (sizeof(GdkAtom) * 3)),
1250 (numtypes - 3) * sizeof(GdkAtom));
1252 gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1256 free (window_private->dnd_drag_data_typesavail);
1257 window_private->dnd_drag_data_typesavail = NULL;
1258 window_private->dnd_drag_data_numtypesavail = 0;
1263 gdk_window_dnd_drop_set (GdkWindow *window,
1267 guint8 destructive_op)
1269 GdkWindowPrivate *window_private;
1272 g_return_if_fail (window != NULL);
1274 window_private = (GdkWindowPrivate *) window;
1276 window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1279 g_return_if_fail(typelist != NULL);
1281 window_private->dnd_drop_data_numtypesavail = numtypes;
1283 window_private->dnd_drop_data_typesavail =
1284 g_realloc (window_private->dnd_drop_data_typesavail,
1285 (numtypes + 1) * sizeof (GdkAtom));
1287 for (i = 0; i < numtypes; i++)
1288 window_private->dnd_drop_data_typesavail[i] =
1289 gdk_atom_intern (typelist[i], FALSE);
1291 window_private->dnd_drop_destructive_op = destructive_op;
1296 * This is used to reply to a GDK_DRAG_REQUEST event
1297 * (which may be generated by XdeRequest or a confirmed drop...
1300 gdk_window_dnd_data_set (GdkWindow *window,
1303 gulong data_numbytes)
1305 GdkWindowPrivate *window_private;
1307 GdkEventDropDataAvailable tmp_ev;
1310 g_return_if_fail (window != NULL);
1311 g_return_if_fail (event != NULL);
1312 g_return_if_fail (data != NULL);
1313 g_return_if_fail (data_numbytes > 0);
1314 g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1316 g_free (event->dragrequest.data_type);
1317 event->dragrequest.data_type = NULL;
1319 window_private = (GdkWindowPrivate *) window;
1320 g_return_if_fail (window_private->dnd_drag_accepted != 0);
1322 /* We set the property on our window... */
1323 gdk_property_change (window, window_private->dnd_drag_data_type,
1324 XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1326 tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1328 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,