]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
Merges from the gtk-1-0 branch
[~andy/gtk] / gdk / gdkwindow.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include <X11/Xlib.h>
21 #include <X11/Xutil.h>
22 #include <X11/Xatom.h>
23 #include <netinet/in.h>
24 #include "gdk.h"
25 #include "../config.h"
26 #include "gdkinput.h"
27 #include "gdkprivate.h"
28 #include "MwmUtil.h"
29 #include <stdlib.h>
30 #include <stdio.h>
31
32 #ifdef HAVE_SHAPE_EXT
33 #include <X11/extensions/shape.h>
34 #endif
35
36 int nevent_masks = 17;
37 int event_mask_table[19] =
38 {
39   ExposureMask,
40   PointerMotionMask,
41   PointerMotionHintMask,
42   ButtonMotionMask,
43   Button1MotionMask,
44   Button2MotionMask,
45   Button3MotionMask,
46   ButtonPressMask | OwnerGrabButtonMask,
47   ButtonReleaseMask | OwnerGrabButtonMask,
48   KeyPressMask,
49   KeyReleaseMask,
50   EnterWindowMask,
51   LeaveWindowMask,
52   FocusChangeMask,
53   StructureNotifyMask,
54   PropertyChangeMask,
55   VisibilityChangeMask,
56   0,                            /* PROXIMITY_IN */
57   0                             /* PROXIMTY_OUT */
58 };
59
60
61 /* internal function created for and used by gdk_window_xid_at_coords */
62 Window
63 gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y, 
64                   GList *excludes, gboolean excl_child)
65 {
66    GdkWindow *window;
67    GdkWindowPrivate *private;
68    Display *disp;
69    Window *list=NULL;
70    Window child=0,parent_win=0,root_win=0;
71
72    int i;
73    unsigned int ww, wh, wb, wd, num;
74    int wx,wy;
75    
76    window=(GdkWindow*)&gdk_root_parent;
77    private=(GdkWindowPrivate*)window;
78    disp=private->xdisplay;
79    if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
80      return 0;
81    wx+=bx;wy+=by;
82    if (!((x>=wx)&&(y>=wy)&&(x<(int)(wx+ww))&&(y<(int)(wy+wh))))
83      return 0;
84    if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
85      return base;
86    if (list)
87      {
88         for (i=num-1;;i--)
89           {
90              if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
91                {
92                  if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
93                    {
94                      XFree(list);
95                      return child;
96                    }
97                }
98              if (!i) break;
99           }
100         XFree(list);
101      }
102    return base;
103 }
104
105 /* 
106  * The following fucntion by The Rasterman <raster@redhat.com>
107  * This function returns the X Window ID in which the x y location is in 
108  * (x and y being relative to the root window), excluding any windows listed
109  * in the GList excludes (this is a list of X Window ID's - gpointer being
110  * the Window ID).
111  * 
112  * This is primarily designed for internal gdk use - for DND for example
113  * when using a shaped icon window as the drag object - you exclude the
114  * X Window ID of the "icon" (perhaps more if excludes may be needed) and
115  * You can get back an X Window ID as to what X Window ID is infact under
116  * those X,Y co-ordinates.
117  */
118 Window
119 gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
120 {
121    GdkWindow *window;
122    GdkWindowPrivate *private;
123    Display *disp;
124    Window *list=NULL;
125    Window root,child=0,parent_win=0,root_win=0;
126    unsigned int num;
127    int i;
128    
129    window=(GdkWindow*)&gdk_root_parent;
130    private=(GdkWindowPrivate*)window;
131    disp=private->xdisplay;
132    root=private->xwindow;
133    XGrabServer(disp);
134    num=g_list_length(excludes);
135    if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
136         return root;
137    if (list)
138      {
139        i = num - 1;
140        do
141          {
142            XWindowAttributes xwa;
143
144            XGetWindowAttributes (disp, list [i], &xwa);
145
146            if (xwa.map_state != IsViewable)
147              continue;
148
149            if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
150              continue;
151            
152            if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
153              continue;
154
155            if (excludes)
156              {
157                if (!g_list_find(excludes,(gpointer *)child))
158                  {
159                    XFree(list);
160                    XUngrabServer(disp);
161                    return child;
162                  }
163              }
164            else
165              {
166                XFree(list);
167                XUngrabServer(disp);
168                return child;
169              }
170          } while (--i > 0);
171         XFree(list);
172      }
173    XUngrabServer(disp);
174    return root;
175 }
176
177 void
178 gdk_window_init (void)
179 {
180   XWindowAttributes xattributes;
181   unsigned int width;
182   unsigned int height;
183   unsigned int border_width;
184   unsigned int depth;
185   int x, y;
186
187   XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
188                 &x, &y, &width, &height, &border_width, &depth);
189   XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
190
191   gdk_root_parent.xdisplay = gdk_display;
192   gdk_root_parent.xwindow = gdk_root_window;
193   gdk_root_parent.window_type = GDK_WINDOW_ROOT;
194   gdk_root_parent.window.user_data = NULL;
195   gdk_root_parent.width = width;
196   gdk_root_parent.height = height;
197   gdk_root_parent.children = NULL;
198   gdk_root_parent.colormap = NULL;
199 }
200
201 GdkWindow*
202 gdk_window_new (GdkWindow     *parent,
203                 GdkWindowAttr *attributes,
204                 gint           attributes_mask)
205 {
206   GdkWindow *window;
207   GdkWindowPrivate *private;
208   GdkWindowPrivate *parent_private;
209   GdkVisual *visual;
210   Display *parent_display;
211   Window xparent;
212   Visual *xvisual;
213   XSetWindowAttributes xattributes;
214   long xattributes_mask;
215   XSizeHints size_hints;
216   XWMHints wm_hints;
217   XClassHint *class_hint;
218   int x, y, depth;
219   unsigned int class;
220   char *title;
221   int i;
222
223   g_return_val_if_fail (attributes != NULL, NULL);
224
225   if (!parent)
226     parent = (GdkWindow*) &gdk_root_parent;
227
228   parent_private = (GdkWindowPrivate*) parent;
229   if (parent_private->destroyed)
230     return NULL;
231
232   xparent = parent_private->xwindow;
233   parent_display = parent_private->xdisplay;
234
235   private = g_new (GdkWindowPrivate, 1);
236   window = (GdkWindow*) private;
237
238   private->parent = parent;
239
240   if (parent_private)
241     parent_private->children = g_list_prepend (parent_private->children, window);
242
243   private->xdisplay = parent_display;
244   private->destroyed = FALSE;
245   private->resize_count = 0;
246   private->ref_count = 1;
247   xattributes_mask = 0;
248
249   if (attributes_mask & GDK_WA_X)
250     x = attributes->x;
251   else
252     x = 0;
253
254   if (attributes_mask & GDK_WA_Y)
255     y = attributes->y;
256   else
257     y = 0;
258
259   private->x = x;
260   private->y = y;
261   private->width = (attributes->width > 1) ? (attributes->width) : (1);
262   private->height = (attributes->height > 1) ? (attributes->height) : (1);
263   private->window_type = attributes->window_type;
264   private->extension_events = FALSE;
265   private->dnd_drag_data_type = None;
266   private->dnd_drag_data_typesavail =
267     private->dnd_drop_data_typesavail = NULL;
268   private->dnd_drop_enabled = private->dnd_drag_enabled =
269     private->dnd_drag_accepted = private->dnd_drag_datashow =
270     private->dnd_drop_data_numtypesavail =
271     private->dnd_drag_data_numtypesavail = 0;
272   private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
273
274   private->filters = NULL;
275   private->children = NULL;
276
277   window->user_data = NULL;
278
279   if (attributes_mask & GDK_WA_VISUAL)
280     visual = attributes->visual;
281   else
282     visual = gdk_visual_get_system ();
283   xvisual = ((GdkVisualPrivate*) visual)->xvisual;
284
285   xattributes.event_mask = StructureNotifyMask;
286   for (i = 0; i < nevent_masks; i++)
287     {
288       if (attributes->event_mask & (1 << (i + 1)))
289         xattributes.event_mask |= event_mask_table[i];
290     }
291
292   if (xattributes.event_mask)
293     xattributes_mask |= CWEventMask;
294
295   if(attributes_mask & GDK_WA_NOREDIR) {
296         xattributes.override_redirect =
297                 (attributes->override_redirect == FALSE)?False:True;
298         xattributes_mask |= CWOverrideRedirect;
299   } else
300     xattributes.override_redirect = False;
301
302   if (attributes->wclass == GDK_INPUT_OUTPUT)
303     {
304       class = InputOutput;
305       depth = visual->depth;
306
307       if (attributes_mask & GDK_WA_COLORMAP)
308         private->colormap = attributes->colormap;
309       else
310         private->colormap = gdk_colormap_get_system ();
311
312       xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
313       xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
314       xattributes_mask |= CWBorderPixel | CWBackPixel;
315
316       switch (private->window_type)
317         {
318         case GDK_WINDOW_TOPLEVEL:
319           xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
320           xattributes_mask |= CWColormap;
321
322           xparent = gdk_root_window;
323           break;
324
325         case GDK_WINDOW_CHILD:
326           xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
327           xattributes_mask |= CWColormap;
328           break;
329
330         case GDK_WINDOW_DIALOG:
331           xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
332           xattributes_mask |= CWColormap;
333
334           xparent = gdk_root_window;
335           break;
336
337         case GDK_WINDOW_TEMP:
338           xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
339           xattributes_mask |= CWColormap;
340
341           xparent = gdk_root_window;
342
343           xattributes.save_under = True;
344           xattributes.override_redirect = True;
345           xattributes.cursor = None;
346           xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
347           break;
348         case GDK_WINDOW_ROOT:
349           g_error ("cannot make windows of type GDK_WINDOW_ROOT");
350           break;
351         case GDK_WINDOW_PIXMAP:
352           g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
353           break;
354         }
355     }
356   else
357     {
358       depth = 0;
359       class = InputOnly;
360       private->colormap = NULL;
361     }
362
363   private->xwindow = XCreateWindow (private->xdisplay, xparent,
364                                     x, y, private->width, private->height,
365                                     0, depth, class, xvisual,
366                                     xattributes_mask, &xattributes);
367   gdk_window_ref (window);
368   gdk_xid_table_insert (&private->xwindow, window);
369
370   if (private->colormap)
371     gdk_colormap_ref (private->colormap);
372
373   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
374                                   (attributes->cursor) :
375                                   NULL));
376
377   switch (private->window_type)
378     {
379     case GDK_WINDOW_DIALOG:
380       XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
381     case GDK_WINDOW_TOPLEVEL:
382     case GDK_WINDOW_TEMP:
383       XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
384       break;
385     case GDK_WINDOW_CHILD:
386       if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
387           (private->colormap != gdk_colormap_get_system ()) &&
388           (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
389         {
390           GDK_NOTE (MISC, g_print ("adding colormap window\n"));
391           gdk_window_add_colormap_windows (window);
392         }
393
394       return window;
395     default:
396
397       return window;
398     }
399
400   size_hints.flags = PSize;
401   size_hints.width = private->width;
402   size_hints.height = private->height;
403
404   wm_hints.flags = InputHint | StateHint | WindowGroupHint;
405   wm_hints.window_group = gdk_leader_window;
406   wm_hints.input = True;
407   wm_hints.initial_state = NormalState;
408
409   /* FIXME: Is there any point in doing this? Do any WM's pay
410    * attention to PSize, and even if they do, is this the
411    * correct value???
412    */
413   XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
414
415   XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
416
417   if (attributes_mask & GDK_WA_TITLE)
418     title = attributes->title;
419   else
420     title = gdk_progname;
421
422   XmbSetWMProperties (private->xdisplay, private->xwindow,
423                       title, title,
424                       NULL, 0,
425                       NULL, NULL, NULL);
426
427   if (attributes_mask & GDK_WA_WMCLASS)
428     {
429       class_hint = XAllocClassHint ();
430       class_hint->res_name = attributes->wmclass_name;
431       class_hint->res_class = attributes->wmclass_class;
432       XSetClassHint (private->xdisplay, private->xwindow, class_hint);
433       XFree (class_hint);
434     }
435
436
437   return window;
438 }
439
440 GdkWindow *
441 gdk_window_foreign_new (guint32 anid)
442 {
443   GdkWindow *window;
444   GdkWindowPrivate *private;
445   GdkWindowPrivate *parent_private;
446   XWindowAttributes attrs;
447   Window root, parent;
448   Window *children;
449   guint nchildren;
450
451   private = g_new (GdkWindowPrivate, 1);
452   window = (GdkWindow*) private;
453
454   XGetWindowAttributes (gdk_display, anid, &attrs);
455
456   /* FIXME: This is pretty expensive. Maybe the caller should supply
457    *        the parent */
458   XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
459   XFree (children);
460   private->parent = gdk_xid_table_lookup (parent);
461
462   parent_private = (GdkWindowPrivate *)private->parent;
463   
464   if (parent_private)
465     parent_private->children = g_list_prepend (parent_private->children, window);
466
467   private->xwindow = anid;
468   private->xdisplay = gdk_display;
469   private->x = attrs.x;
470   private->y = attrs.y;
471   private->width = attrs.width;
472   private->height = attrs.height;
473   private->resize_count = 0;
474   private->ref_count = 1;
475   private->window_type = GDK_WINDOW_FOREIGN;
476   private->destroyed = FALSE;
477   private->extension_events = 0;
478
479   private->colormap = NULL;
480
481   private->dnd_drag_data_type = None;
482   private->dnd_drag_data_typesavail =
483     private->dnd_drop_data_typesavail = NULL;
484   private->dnd_drop_enabled = private->dnd_drag_enabled =
485     private->dnd_drag_accepted = private->dnd_drag_datashow =
486     private->dnd_drop_data_numtypesavail =
487     private->dnd_drag_data_numtypesavail = 0;
488   private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
489
490   private->filters = NULL;
491   private->children = NULL;
492
493   window->user_data = NULL;
494
495   gdk_window_ref (window);
496   gdk_xid_table_insert (&private->xwindow, window);
497
498   return window;
499 }
500
501 /* Call this function when you want a window and all its children to
502    disappear.  When xdestroy is true, a request to destroy the XWindow
503    is sent out.  When it is false, it is assumed that the XWindow has
504    been or will be destroyed by destroying some ancestor of this
505    window.  */
506
507 static void
508 gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
509                              gboolean our_destroy)
510 {
511   GdkWindowPrivate *private;
512   GdkWindowPrivate *temp_private;
513   GdkWindow *temp_window;
514   GList *children;
515   GList *tmp;
516
517   g_return_if_fail (window != NULL);
518
519   private = (GdkWindowPrivate*) window;
520
521   switch (private->window_type)
522     {
523     case GDK_WINDOW_TOPLEVEL:
524     case GDK_WINDOW_CHILD:
525     case GDK_WINDOW_DIALOG:
526     case GDK_WINDOW_TEMP:
527     case GDK_WINDOW_FOREIGN:
528       if (!private->destroyed)
529         {
530           if (private->parent)
531             {
532               GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
533               if (parent_private->children)
534                 parent_private->children = g_list_remove (parent_private->children, window);
535             }
536
537           if (private->window_type != GDK_WINDOW_FOREIGN)
538             {
539               children = tmp = private->children;
540               private->children = NULL;
541
542               while (tmp)
543                 {
544                   temp_window = tmp->data;
545                   tmp = tmp->next;
546                   
547                   temp_private = (GdkWindowPrivate*) temp_window;
548                   if (temp_private)
549                     gdk_window_internal_destroy (temp_window, FALSE,
550                                                  our_destroy);
551                 }
552
553               g_list_free (children);
554             }
555
556           if (private->extension_events != 0)
557             gdk_input_window_destroy (window);
558
559           if(private->dnd_drag_data_numtypesavail > 0) 
560             {
561               g_free (private->dnd_drag_data_typesavail);
562               private->dnd_drag_data_typesavail = NULL;
563             }
564           if(private->dnd_drop_data_numtypesavail > 0) 
565             {
566               g_free (private->dnd_drop_data_typesavail);
567               private->dnd_drop_data_typesavail = NULL;
568             }
569
570           if (private->filters)
571             {
572               tmp = private->filters;
573
574               while (tmp)
575                 {
576                   g_free (tmp->data);
577                   tmp = tmp->next;
578                 }
579
580               g_list_free (private->filters);
581               private->filters = NULL;
582             }
583           
584           if (private->window_type == GDK_WINDOW_FOREIGN)
585             {
586               if (our_destroy && (private->parent != NULL))
587                 {
588                   /* It's somebody elses window, but in our heirarchy,
589                    * so reparent it to the root window, and then send
590                    * it a delete event, as if we were a WM
591                    */
592                   XClientMessageEvent xevent;
593                   
594                   gdk_window_hide (window);
595                   gdk_window_reparent (window, NULL, 0, 0);
596                   
597                   xevent.type = ClientMessage;
598                   xevent.window = private->xwindow;
599                   xevent.message_type = gdk_wm_protocols;
600                   xevent.format = 32;
601                   xevent.data.l[0] = gdk_wm_delete_window;
602                   xevent.data.l[1] = CurrentTime;
603                   
604                   XSendEvent (private->xdisplay, private->xwindow,
605                               False, 0, (XEvent *)&xevent);
606                 }
607             }
608           else if (xdestroy)
609             XDestroyWindow (private->xdisplay, private->xwindow);
610
611           if (private->colormap)
612             gdk_colormap_unref (private->colormap);
613
614           private->destroyed = TRUE;
615         }
616       break;
617
618     case GDK_WINDOW_ROOT:
619       g_error ("attempted to destroy root window");
620       break;
621
622     case GDK_WINDOW_PIXMAP:
623       g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
624       break;
625     }
626 }
627
628 /* Like internal_destroy, but also destroys the reference created by
629    gdk_window_new. */
630
631 void
632 gdk_window_destroy (GdkWindow *window)
633 {
634   gdk_window_internal_destroy (window, TRUE, TRUE);
635   gdk_window_unref (window);
636 }
637
638 /* This function is called when the XWindow is really gone.  */
639
640 void
641 gdk_window_destroy_notify (GdkWindow *window)
642 {
643   GdkWindowPrivate *private;
644
645   g_return_if_fail (window != NULL);
646
647   private = (GdkWindowPrivate*) window;
648
649   if (!private->destroyed)
650     {
651       if (private->window_type == GDK_WINDOW_FOREIGN)
652         gdk_window_internal_destroy (window, FALSE, FALSE);
653       else
654         g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
655     }
656   
657   gdk_xid_table_remove (private->xwindow);
658   gdk_window_unref (window);
659 }
660
661 GdkWindow*
662 gdk_window_ref (GdkWindow *window)
663 {
664   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
665   g_return_val_if_fail (window != NULL, NULL);
666
667   private->ref_count += 1;
668   return window;
669 }
670
671 void
672 gdk_window_unref (GdkWindow *window)
673 {
674   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
675   g_return_if_fail (window != NULL);
676
677   private->ref_count -= 1;
678   if (private->ref_count == 0)
679     {
680       if (!private->destroyed)
681         g_warning ("losing last reference to undestroyed window\n");
682       g_free (window);
683     }
684 }
685
686 void
687 gdk_window_show (GdkWindow *window)
688 {
689   GdkWindowPrivate *private;
690
691   g_return_if_fail (window != NULL);
692
693   private = (GdkWindowPrivate*) window;
694   if (!private->destroyed)
695     {
696       XRaiseWindow (private->xdisplay, private->xwindow);
697       XMapWindow (private->xdisplay, private->xwindow);
698     }
699 }
700
701 void
702 gdk_window_hide (GdkWindow *window)
703 {
704   GdkWindowPrivate *private;
705
706   g_return_if_fail (window != NULL);
707
708   private = (GdkWindowPrivate*) window;
709   if (!private->destroyed)
710     XUnmapWindow (private->xdisplay, private->xwindow);
711 }
712
713 void
714 gdk_window_withdraw (GdkWindow *window)
715 {
716   GdkWindowPrivate *private;
717
718   g_return_if_fail (window != NULL);
719
720   private = (GdkWindowPrivate*) window;
721   if (!private->destroyed)
722     XWithdrawWindow (private->xdisplay, private->xwindow, 0);
723 }
724
725 void
726 gdk_window_move (GdkWindow *window,
727                  gint       x,
728                  gint       y)
729 {
730   GdkWindowPrivate *private;
731
732   g_return_if_fail (window != NULL);
733
734   private = (GdkWindowPrivate*) window;
735   if (!private->destroyed)
736     {
737       XMoveWindow (private->xdisplay, private->xwindow, x, y);
738       
739       if (private->window_type == GDK_WINDOW_CHILD)
740         {
741           private->x = x;
742           private->y = y;
743         }
744     }
745 }
746
747 void
748 gdk_window_resize (GdkWindow *window,
749                    gint       width,
750                    gint       height)
751 {
752   GdkWindowPrivate *private;
753
754   g_return_if_fail (window != NULL);
755
756   if (width < 1)
757     width = 1;
758   if (height < 1)
759     height = 1;
760
761   private = (GdkWindowPrivate*) window;
762
763   if (!private->destroyed &&
764       ((private->resize_count > 0) ||
765        (private->width != (guint16) width) ||
766        (private->height != (guint16) height)))
767     {
768       XResizeWindow (private->xdisplay, private->xwindow, width, height);
769       private->resize_count += 1;
770
771       if (private->window_type == GDK_WINDOW_CHILD)
772         {
773           private->width = width;
774           private->height = height;
775         }
776     }
777 }
778
779 void
780 gdk_window_move_resize (GdkWindow *window,
781                         gint       x,
782                         gint       y,
783                         gint       width,
784                         gint       height)
785 {
786   GdkWindowPrivate *private;
787
788   g_return_if_fail (window != NULL);
789
790   if (width < 1)
791     width = 1;
792   if (height < 1)
793     height = 1;
794
795   private = (GdkWindowPrivate*) window;
796   if (!private->destroyed)
797     {
798       XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
799       
800       if (private->window_type == GDK_WINDOW_CHILD)
801         {
802           private->x = x;
803           private->y = y;
804           private->width = width;
805           private->height = height;
806         }
807     }
808 }
809
810 void
811 gdk_window_reparent (GdkWindow *window,
812                      GdkWindow *new_parent,
813                      gint       x,
814                      gint       y)
815 {
816   GdkWindowPrivate *window_private;
817   GdkWindowPrivate *parent_private;
818
819   g_return_if_fail (window != NULL);
820
821   if (!new_parent)
822     new_parent = (GdkWindow*) &gdk_root_parent;
823
824   window_private = (GdkWindowPrivate*) window;
825   parent_private = (GdkWindowPrivate*) new_parent;
826
827   if (!window_private->destroyed && !parent_private->destroyed)
828     XReparentWindow (window_private->xdisplay,
829                      window_private->xwindow,
830                      parent_private->xwindow,
831                      x, y);
832 }
833
834 void
835 gdk_window_clear (GdkWindow *window)
836 {
837   GdkWindowPrivate *private;
838
839   g_return_if_fail (window != NULL);
840
841   private = (GdkWindowPrivate*) window;
842
843   if (!private->destroyed)
844     XClearWindow (private->xdisplay, private->xwindow);
845 }
846
847 void
848 gdk_window_clear_area (GdkWindow *window,
849                        gint       x,
850                        gint       y,
851                        gint       width,
852                        gint       height)
853 {
854   GdkWindowPrivate *private;
855   
856   g_return_if_fail (window != NULL);
857   
858   private = (GdkWindowPrivate*) window;
859   
860   if (!private->destroyed)
861     XClearArea (private->xdisplay, private->xwindow,
862                 x, y, width, height, False);
863 }
864
865 void
866 gdk_window_clear_area_e (GdkWindow *window,
867                          gint       x,
868                          gint       y,
869                          gint       width,
870                          gint       height)
871 {
872   GdkWindowPrivate *private;
873   
874   g_return_if_fail (window != NULL);
875   
876   private = (GdkWindowPrivate*) window;
877   
878   if (!private->destroyed)
879     XClearArea (private->xdisplay, private->xwindow,
880                 x, y, width, height, True);
881 }
882
883 void
884 gdk_window_copy_area (GdkWindow    *window,
885                       GdkGC        *gc,
886                       gint          x,
887                       gint          y,
888                       GdkWindow    *source_window,
889                       gint          source_x,
890                       gint          source_y,
891                       gint          width,
892                       gint          height)
893 {
894   GdkWindowPrivate *src_private;
895   GdkWindowPrivate *dest_private;
896   GdkGCPrivate *gc_private;
897   
898   g_return_if_fail (window != NULL);
899   g_return_if_fail (gc != NULL);
900   
901   if (source_window == NULL)
902     source_window = window;
903   
904   src_private = (GdkWindowPrivate*) source_window;
905   dest_private = (GdkWindowPrivate*) window;
906   gc_private = (GdkGCPrivate*) gc;
907   
908   if (!src_private->destroyed && !dest_private->destroyed)
909     {
910       XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
911                  gc_private->xgc,
912                  source_x, source_y,
913                  width, height,
914                  x, y);
915     }
916 }
917
918 void
919 gdk_window_raise (GdkWindow *window)
920 {
921   GdkWindowPrivate *private;
922   
923   g_return_if_fail (window != NULL);
924   
925   private = (GdkWindowPrivate*) window;
926   
927   if (!private->destroyed)
928     XRaiseWindow (private->xdisplay, private->xwindow);
929 }
930
931 void
932 gdk_window_lower (GdkWindow *window)
933 {
934   GdkWindowPrivate *private;
935   
936   g_return_if_fail (window != NULL);
937   
938   private = (GdkWindowPrivate*) window;
939   
940   if (!private->destroyed)
941     XLowerWindow (private->xdisplay, private->xwindow);
942 }
943
944 void
945 gdk_window_set_user_data (GdkWindow *window,
946                           gpointer   user_data)
947 {
948   g_return_if_fail (window != NULL);
949   
950   window->user_data = user_data;
951 }
952
953 void
954 gdk_window_set_hints (GdkWindow *window,
955                       gint       x,
956                       gint       y,
957                       gint       min_width,
958                       gint       min_height,
959                       gint       max_width,
960                       gint       max_height,
961                       gint       flags)
962 {
963   GdkWindowPrivate *private;
964   XSizeHints size_hints;
965   
966   g_return_if_fail (window != NULL);
967   
968   private = (GdkWindowPrivate*) window;
969   if (private->destroyed)
970     return;
971   
972   size_hints.flags = 0;
973   
974   if (flags & GDK_HINT_POS)
975     {
976       size_hints.flags |= PPosition;
977       size_hints.x = x;
978       size_hints.y = y;
979     }
980   
981   if (flags & GDK_HINT_MIN_SIZE)
982     {
983       size_hints.flags |= PMinSize;
984       size_hints.min_width = min_width;
985       size_hints.min_height = min_height;
986     }
987   
988   if (flags & GDK_HINT_MAX_SIZE)
989     {
990       size_hints.flags |= PMaxSize;
991       size_hints.max_width = max_width;
992       size_hints.max_height = max_height;
993     }
994   
995   if (flags)
996     XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
997 }
998
999 void
1000 gdk_window_set_title (GdkWindow   *window,
1001                       const gchar *title)
1002 {
1003   GdkWindowPrivate *private;
1004   
1005   g_return_if_fail (window != NULL);
1006   
1007   private = (GdkWindowPrivate*) window;
1008   if (!private->destroyed)
1009     XmbSetWMProperties (private->xdisplay, private->xwindow,
1010                         title, title, NULL, 0, NULL, NULL, NULL);
1011 }
1012
1013 void
1014 gdk_window_set_background (GdkWindow *window,
1015                            GdkColor  *color)
1016 {
1017   GdkWindowPrivate *private;
1018   
1019   g_return_if_fail (window != NULL);
1020   
1021   private = (GdkWindowPrivate*) window;
1022   if (!private->destroyed)
1023     XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
1024 }
1025
1026 void
1027 gdk_window_set_back_pixmap (GdkWindow *window,
1028                             GdkPixmap *pixmap,
1029                             gint       parent_relative)
1030 {
1031   GdkWindowPrivate *window_private;
1032   GdkPixmapPrivate *pixmap_private;
1033   Pixmap xpixmap;
1034   
1035   g_return_if_fail (window != NULL);
1036   
1037   window_private = (GdkWindowPrivate*) window;
1038   pixmap_private = (GdkPixmapPrivate*) pixmap;
1039   
1040   if (pixmap)
1041     xpixmap = pixmap_private->xwindow;
1042   else
1043     xpixmap = None;
1044   
1045   if (parent_relative)
1046     xpixmap = ParentRelative;
1047   
1048   if (!window_private->destroyed)
1049     XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
1050 }
1051
1052 void
1053 gdk_window_set_cursor (GdkWindow *window,
1054                        GdkCursor *cursor)
1055 {
1056   GdkWindowPrivate *window_private;
1057   GdkCursorPrivate *cursor_private;
1058   Cursor xcursor;
1059   
1060   g_return_if_fail (window != NULL);
1061   
1062   window_private = (GdkWindowPrivate*) window;
1063   cursor_private = (GdkCursorPrivate*) cursor;
1064   
1065   if (!cursor)
1066     xcursor = None;
1067   else
1068     xcursor = cursor_private->xcursor;
1069   
1070   if (!window_private->destroyed)
1071     XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
1072 }
1073
1074 void
1075 gdk_window_set_colormap (GdkWindow   *window,
1076                          GdkColormap *colormap)
1077 {
1078   GdkWindowPrivate *window_private;
1079   GdkColormapPrivate *colormap_private;
1080   
1081   g_return_if_fail (window != NULL);
1082   g_return_if_fail (colormap != NULL);
1083   
1084   window_private = (GdkWindowPrivate*) window;
1085   colormap_private = (GdkColormapPrivate*) colormap;
1086   
1087   if (!window_private->destroyed)
1088     {
1089       XSetWindowColormap (window_private->xdisplay,
1090                           window_private->xwindow,
1091                           colormap_private->xcolormap);
1092
1093       if (window_private->colormap)
1094         gdk_colormap_unref (window_private->colormap);
1095       window_private->colormap = colormap;
1096       gdk_colormap_ref (window_private->colormap);
1097       
1098       if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1099         gdk_window_add_colormap_windows (window);
1100     }
1101 }
1102
1103 void
1104 gdk_window_get_user_data (GdkWindow *window,
1105                           gpointer  *data)
1106 {
1107   g_return_if_fail (window != NULL);
1108   
1109   *data = window->user_data;
1110 }
1111
1112 void
1113 gdk_window_get_geometry (GdkWindow *window,
1114                          gint      *x,
1115                          gint      *y,
1116                          gint      *width,
1117                          gint      *height,
1118                          gint      *depth)
1119 {
1120   GdkWindowPrivate *window_private;
1121   Window root;
1122   gint tx;
1123   gint ty;
1124   guint twidth;
1125   guint theight;
1126   guint tborder_width;
1127   guint tdepth;
1128   
1129   if (!window)
1130     window = (GdkWindow*) &gdk_root_parent;
1131   
1132   window_private = (GdkWindowPrivate*) window;
1133   
1134   if (!window_private->destroyed)
1135     {
1136       XGetGeometry (window_private->xdisplay, window_private->xwindow,
1137                     &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1138       
1139       if (x)
1140         *x = tx;
1141       if (y)
1142         *y = ty;
1143       if (width)
1144         *width = twidth;
1145       if (height)
1146         *height = theight;
1147       if (depth)
1148         *depth = tdepth;
1149     }
1150 }
1151
1152 void
1153 gdk_window_get_position (GdkWindow *window,
1154                          gint      *x,
1155                          gint      *y)
1156 {
1157   GdkWindowPrivate *window_private;
1158   
1159   g_return_if_fail (window != NULL);
1160   
1161   window_private = (GdkWindowPrivate*) window;
1162   
1163   if (x)
1164     *x = window_private->x;
1165   if (y)
1166     *y = window_private->y;
1167 }
1168
1169 void
1170 gdk_window_get_size (GdkWindow *window,
1171                      gint       *width,
1172                      gint       *height)
1173 {
1174   GdkWindowPrivate *window_private;
1175   
1176   g_return_if_fail (window != NULL);
1177   
1178   window_private = (GdkWindowPrivate*) window;
1179   
1180   if (width)
1181     *width = window_private->width;
1182   if (height)
1183     *height = window_private->height;
1184 }
1185
1186 GdkVisual*
1187 gdk_window_get_visual (GdkWindow *window)
1188 {
1189   GdkWindowPrivate *window_private;
1190   XWindowAttributes window_attributes;
1191    
1192   g_return_val_if_fail (window != NULL, NULL);
1193
1194   window_private = (GdkWindowPrivate*) window;
1195   /* Huh? ->parent is never set for a pixmap. We should just return
1196    * null immeditately
1197    */
1198   while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1199     window_private = (GdkWindowPrivate*) window_private->parent;
1200   
1201   if (window_private && !window_private->destroyed)
1202     {
1203        if (window_private->colormap == NULL)
1204          {
1205             XGetWindowAttributes (window_private->xdisplay,
1206                                   window_private->xwindow,
1207                                   &window_attributes);
1208             return gdk_visual_lookup (window_attributes.visual);
1209          }
1210        else
1211          return ((GdkColormapPrivate *)window_private->colormap)->visual;
1212     }
1213   
1214   return NULL;
1215 }
1216
1217 GdkColormap*
1218 gdk_window_get_colormap (GdkWindow *window)
1219 {
1220   GdkWindowPrivate *window_private;
1221   XWindowAttributes window_attributes;
1222   
1223   g_return_val_if_fail (window != NULL, NULL);
1224   window_private = (GdkWindowPrivate*) window;
1225
1226   g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1227   if (!window_private->destroyed)
1228     {
1229       if (window_private->colormap == NULL)
1230         {
1231           XGetWindowAttributes (window_private->xdisplay,
1232                                 window_private->xwindow,
1233                                 &window_attributes);
1234           return gdk_colormap_lookup (window_attributes.colormap);
1235          }
1236        else
1237          return window_private->colormap;
1238     }
1239   
1240   return NULL;
1241 }
1242
1243 GdkWindowType
1244 gdk_window_get_type (GdkWindow *window)
1245 {
1246   GdkWindowPrivate *window_private;
1247
1248   g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1249
1250   window_private = (GdkWindowPrivate*) window;
1251   return window_private->window_type;
1252 }
1253
1254 gint
1255 gdk_window_get_origin (GdkWindow *window,
1256                        gint      *x,
1257                        gint      *y)
1258 {
1259   GdkWindowPrivate *private;
1260   gint return_val;
1261   Window child;
1262   gint tx, ty;
1263
1264   g_return_val_if_fail (window != NULL, 0);
1265
1266   private = (GdkWindowPrivate*) window;
1267
1268   if (!private->destroyed)
1269     {
1270       return_val = XTranslateCoordinates (private->xdisplay,
1271                                           private->xwindow,
1272                                           gdk_root_window,
1273                                           0, 0, &tx, &ty,
1274                                           &child);
1275       
1276       if (x)
1277         *x = tx;
1278       if (y)
1279         *y = ty;
1280     }
1281   else
1282     return_val = 0;
1283   
1284   return return_val;
1285 }
1286
1287 GdkWindow*
1288 gdk_window_get_pointer (GdkWindow       *window,
1289                         gint            *x,
1290                         gint            *y,
1291                         GdkModifierType *mask)
1292 {
1293   GdkWindowPrivate *private;
1294   GdkWindow *return_val;
1295   Window root;
1296   Window child;
1297   int rootx, rooty;
1298   int winx, winy;
1299   unsigned int xmask;
1300
1301   if (!window)
1302     window = (GdkWindow*) &gdk_root_parent;
1303
1304   private = (GdkWindowPrivate*) window;
1305
1306   return_val = NULL;
1307   if (!private->destroyed &&
1308       XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1309                      &rootx, &rooty, &winx, &winy, &xmask))
1310     {
1311       if (x) *x = winx;
1312       if (y) *y = winy;
1313       if (mask) *mask = xmask;
1314       
1315       if (child)
1316         return_val = gdk_window_lookup (child);
1317     }
1318   
1319   return return_val;
1320 }
1321
1322 GdkWindow*
1323 gdk_window_get_parent (GdkWindow *window)
1324 {
1325   g_return_val_if_fail (window != NULL, NULL);
1326
1327   return ((GdkWindowPrivate*) window)->parent;
1328 }
1329
1330 GdkWindow*
1331 gdk_window_get_toplevel (GdkWindow *window)
1332 {
1333   GdkWindowPrivate *private;
1334
1335   g_return_val_if_fail (window != NULL, NULL);
1336
1337   private = (GdkWindowPrivate*) window;
1338
1339   while (private->window_type == GDK_WINDOW_CHILD)
1340     {
1341       window = ((GdkWindowPrivate*) window)->parent;
1342       private = (GdkWindowPrivate*) window;
1343     }
1344
1345   return window;
1346 }
1347
1348 GList*
1349 gdk_window_get_children (GdkWindow *window)
1350 {
1351   GdkWindowPrivate *private;
1352   GdkWindow *child;
1353   GList *children;
1354   Window root;
1355   Window parent;
1356   Window *xchildren;
1357   unsigned int nchildren;
1358   unsigned int i;
1359
1360   g_return_val_if_fail (window != NULL, NULL);
1361
1362   private = (GdkWindowPrivate*) window;
1363   if (private->destroyed)
1364     return NULL;
1365
1366   XQueryTree (private->xdisplay, private->xwindow,
1367               &root, &parent, &xchildren, &nchildren);
1368
1369   children = NULL;
1370
1371   if (nchildren > 0)
1372     {
1373       for (i = 0; i < nchildren; i++)
1374         {
1375           child = gdk_window_lookup (xchildren[i]);
1376           if (child)
1377             children = g_list_prepend (children, child);
1378         }
1379
1380       XFree (xchildren);
1381     }
1382
1383   return children;
1384 }
1385
1386 GdkEventMask  
1387 gdk_window_get_events      (GdkWindow       *window)
1388 {
1389   GdkWindowPrivate *private;
1390   XWindowAttributes attrs;
1391   GdkEventMask event_mask;
1392   int i;
1393
1394   g_return_val_if_fail (window != NULL, 0);
1395
1396   private = (GdkWindowPrivate*) window;
1397   if (private->destroyed)
1398     return 0;
1399
1400   XGetWindowAttributes (gdk_display, private->xwindow, 
1401                         &attrs);
1402
1403   event_mask = 0;
1404   for (i = 0; i < nevent_masks; i++)
1405     {
1406       if (attrs.your_event_mask & event_mask_table[i])
1407         event_mask |= 1 << (i + 1);
1408     }
1409
1410   return event_mask;
1411 }
1412
1413 void          
1414 gdk_window_set_events      (GdkWindow       *window,
1415                             GdkEventMask     event_mask)
1416 {
1417   GdkWindowPrivate *private;
1418   long xevent_mask;
1419   int i;
1420
1421   g_return_if_fail (window != NULL);
1422
1423   private = (GdkWindowPrivate*) window;
1424   if (private->destroyed)
1425     return;
1426
1427   xevent_mask = StructureNotifyMask;
1428   for (i = 0; i < nevent_masks; i++)
1429     {
1430       if (event_mask & (1 << (i + 1)))
1431         xevent_mask |= event_mask_table[i];
1432     }
1433   
1434   XSelectInput (gdk_display, private->xwindow, 
1435                 xevent_mask);
1436 }
1437
1438 void
1439 gdk_window_add_colormap_windows (GdkWindow *window)
1440 {
1441   GdkWindow *toplevel;
1442   GdkWindowPrivate *toplevel_private;
1443   GdkWindowPrivate *window_private;
1444   Window *old_windows;
1445   Window *new_windows;
1446   int i, count;
1447
1448   g_return_if_fail (window != NULL);
1449
1450   toplevel = gdk_window_get_toplevel (window);
1451   toplevel_private = (GdkWindowPrivate*) toplevel;
1452   window_private = (GdkWindowPrivate*) window;
1453   if (window_private->destroyed)
1454     return;
1455
1456   if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1457                               toplevel_private->xwindow,
1458                               &old_windows, &count))
1459     {
1460       old_windows = NULL;
1461       count = 0;
1462     }
1463
1464   for (i = 0; i < count; i++)
1465     if (old_windows[i] == window_private->xwindow)
1466       return;
1467
1468   new_windows = g_new (Window, count + 1);
1469
1470   for (i = 0; i < count; i++)
1471     new_windows[i] = old_windows[i];
1472   new_windows[count] = window_private->xwindow;
1473
1474   XSetWMColormapWindows (toplevel_private->xdisplay,
1475                          toplevel_private->xwindow,
1476                          new_windows, count + 1);
1477
1478   g_free (new_windows);
1479   if (old_windows)
1480     XFree (old_windows);
1481 }
1482
1483 /*
1484  * This needs the X11 shape extension.
1485  * If not available, shaped windows will look
1486  * ugly, but programs still work.    Stefan Wille
1487  */
1488 void
1489 gdk_window_shape_combine_mask (GdkWindow *window,
1490                                GdkBitmap *mask,
1491                                gint x, gint y)
1492 {
1493   enum { UNKNOWN, NO, YES };
1494
1495   static gint have_shape = UNKNOWN;
1496
1497   GdkWindowPrivate *window_private;
1498   Pixmap pixmap;
1499
1500   g_return_if_fail (window != NULL);
1501
1502 #ifdef HAVE_SHAPE_EXT
1503   if (have_shape == UNKNOWN)
1504     {
1505       int ignore;
1506       if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
1507         have_shape = YES;
1508       else
1509         have_shape = NO;
1510     }
1511   
1512   if (have_shape == YES)
1513     {
1514       window_private = (GdkWindowPrivate*) window;
1515       if (window_private->destroyed)
1516         return;
1517       
1518       if (mask)
1519         {
1520           GdkWindowPrivate *pixmap_private;
1521           
1522           pixmap_private = (GdkWindowPrivate*) mask;
1523           pixmap = (Pixmap) pixmap_private->xwindow;
1524         }
1525       else
1526         {
1527           x = 0;
1528           y = 0;
1529           pixmap = None;
1530         }
1531       
1532       XShapeCombineMask  (window_private->xdisplay,
1533                           window_private->xwindow,
1534                           ShapeBounding,
1535                           x, y,
1536                           pixmap,
1537                           ShapeSet);
1538     }
1539 #endif /* HAVE_SHAPE_EXT */
1540 }
1541
1542 void
1543 gdk_dnd_drag_addwindow (GdkWindow *window)
1544 {
1545   GdkWindowPrivate *window_private;
1546   
1547   g_return_if_fail (window != NULL);
1548   
1549   window_private = (GdkWindowPrivate *) window;
1550   if (window_private->destroyed)
1551     return;
1552   
1553   if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1554     {
1555       gdk_dnd.drag_numwindows++;
1556       gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1557                                              gdk_dnd.drag_numwindows
1558                                              * sizeof(GdkWindow *));
1559       gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1560       window_private->dnd_drag_accepted = 0;
1561     } 
1562   else
1563     g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1564 }
1565
1566 void
1567 gdk_window_dnd_drag_set (GdkWindow   *window,
1568                          guint8       drag_enable,
1569                          gchar      **typelist,
1570                          guint        numtypes)
1571 {
1572   GdkWindowPrivate *window_private;
1573   int i, wasset = 0;
1574   
1575   g_return_if_fail (window != NULL);
1576   window_private = (GdkWindowPrivate *) window;
1577   if (window_private->destroyed)
1578     return;
1579   
1580   window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1581   
1582   if (drag_enable)
1583     {
1584       g_return_if_fail(typelist != NULL);
1585       
1586       if (window_private->dnd_drag_data_numtypesavail > 3)
1587         wasset = 1;
1588       window_private->dnd_drag_data_numtypesavail = numtypes;
1589       
1590       window_private->dnd_drag_data_typesavail =
1591         g_realloc (window_private->dnd_drag_data_typesavail,
1592                    (numtypes + 1) * sizeof (GdkAtom));
1593       
1594       for (i = 0; i < numtypes; i++)
1595         {
1596           /* Allow blanket use of ALL to get anything... */
1597           if (strcmp (typelist[i], "ALL"))
1598             window_private->dnd_drag_data_typesavail[i] =
1599               gdk_atom_intern (typelist[i], FALSE);
1600           else
1601             window_private->dnd_drag_data_typesavail[i] = None;
1602         }
1603       
1604       /* 
1605        * set our extended type list if we need to 
1606        */
1607       if (numtypes > 3)
1608         gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1609                             XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1610                             (guchar *)(window_private->dnd_drag_data_typesavail
1611                              + (sizeof(GdkAtom) * 3)),
1612                             (numtypes - 3) * sizeof(GdkAtom));
1613       else if (wasset)
1614         gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1615     }
1616   else
1617     {
1618       g_free (window_private->dnd_drag_data_typesavail);
1619       window_private->dnd_drag_data_typesavail = NULL;
1620       window_private->dnd_drag_data_numtypesavail = 0;
1621     }
1622 }
1623
1624 void
1625 gdk_window_dnd_drop_set (GdkWindow   *window,
1626                          guint8       drop_enable,
1627                          gchar      **typelist,
1628                          guint        numtypes,
1629                          guint8       destructive_op)
1630 {
1631   GdkWindowPrivate *window_private;
1632   int i;
1633   
1634   g_return_if_fail (window != NULL);
1635   window_private = (GdkWindowPrivate *) window;
1636   if (window_private->destroyed)
1637     return;
1638   
1639   window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1640   if (drop_enable)
1641     {
1642       g_return_if_fail(typelist != NULL);
1643       
1644       window_private->dnd_drop_data_numtypesavail = numtypes;
1645       
1646       window_private->dnd_drop_data_typesavail =
1647         g_realloc (window_private->dnd_drop_data_typesavail,
1648                    (numtypes + 1) * sizeof (GdkAtom));
1649       
1650       for (i = 0; i < numtypes; i++)
1651         window_private->dnd_drop_data_typesavail[i] =
1652           gdk_atom_intern (typelist[i], FALSE);
1653       
1654       window_private->dnd_drop_destructive_op = destructive_op;
1655     }
1656 }
1657
1658 /* 
1659  * This is used to reply to a GDK_DRAG_REQUEST event
1660  * (which may be generated by XdeRequest or a confirmed drop... 
1661  */
1662 void
1663 gdk_window_dnd_data_set (GdkWindow       *window,
1664                          GdkEvent        *event,
1665                          gpointer         data,
1666                          gulong           data_numbytes)
1667 {
1668   GdkWindowPrivate *window_private;
1669   XEvent sev;
1670   GdkEventDropDataAvailable tmp_ev;
1671   gchar *tmp;
1672   
1673   g_return_if_fail (window != NULL);
1674   g_return_if_fail (event != NULL);
1675   g_return_if_fail (data != NULL);
1676   g_return_if_fail (data_numbytes > 0);
1677   g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1678
1679   window_private = (GdkWindowPrivate *) window;
1680   g_return_if_fail (window_private->dnd_drag_accepted != 0);    
1681   if (window_private->destroyed)
1682     return;
1683   
1684   /* We set the property on our window... */
1685   gdk_property_change (window, window_private->dnd_drag_data_type,
1686                        XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1687                        data_numbytes);
1688   tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1689 #ifdef DEBUG_DND
1690   g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1691 #endif
1692   g_free(tmp);
1693   
1694   /* 
1695    * Then we send the event to tell the receiving window that the
1696    * drop has happened 
1697    */
1698   tmp_ev.u.allflags = 0;
1699   tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1700   tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1701   
1702   sev.xclient.type = ClientMessage;
1703   sev.xclient.format = 32;
1704   sev.xclient.window = event->dragrequest.requestor;
1705   sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1706   sev.xclient.data.l[0] = window_private->xwindow;
1707   sev.xclient.data.l[1] = tmp_ev.u.allflags;
1708   sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1709
1710   if (event->dragrequest.isdrop)
1711     sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1712       (event->dragrequest.drop_coords.y << 16);
1713   else
1714     sev.xclient.data.l[3] = 0;
1715
1716   sev.xclient.data.l[4] = event->dragrequest.timestamp;
1717
1718   if (!gdk_send_xevent (event->dragrequest.requestor, False,
1719                        StructureNotifyMask, &sev))
1720     GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1721                            event->dragrequest.requestor));
1722
1723 }
1724
1725 void          
1726 gdk_window_add_filter     (GdkWindow     *window,
1727                            GdkFilterFunc  function,
1728                            gpointer       data)
1729 {
1730   GdkWindowPrivate *private;
1731   GList *tmp_list;
1732   GdkEventFilter *filter;
1733
1734   private = (GdkWindowPrivate*) window;
1735   if (private && private->destroyed)
1736     return;
1737
1738   if(private)
1739     tmp_list = private->filters;
1740   else
1741     tmp_list = gdk_default_filters;
1742
1743   while (tmp_list)
1744     {
1745       filter = (GdkEventFilter *)tmp_list->data;
1746       if ((filter->function == function) && (filter->data == data))
1747         return;
1748       tmp_list = tmp_list->next;
1749     }
1750
1751   filter = g_new (GdkEventFilter, 1);
1752   filter->function = function;
1753   filter->data = data;
1754
1755   if(private)
1756     private->filters = g_list_append (private->filters, filter);
1757   else
1758     gdk_default_filters = g_list_append (gdk_default_filters, filter);
1759 }
1760
1761 void
1762 gdk_window_remove_filter  (GdkWindow     *window,
1763                            GdkFilterFunc  function,
1764                            gpointer       data)
1765 {
1766   GdkWindowPrivate *private;
1767   GList *tmp_list;
1768   GdkEventFilter *filter;
1769
1770   private = (GdkWindowPrivate*) window;
1771
1772   if(private)
1773     tmp_list = private->filters;
1774   else
1775     tmp_list = gdk_default_filters;
1776
1777   while (tmp_list)
1778     {
1779       filter = (GdkEventFilter *)tmp_list->data;
1780       tmp_list = tmp_list->next;
1781
1782       if ((filter->function == function) && (filter->data == data))
1783         {
1784           if(private)
1785             private->filters = g_list_remove_link (private->filters, tmp_list);
1786           else
1787             gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1788           g_list_free_1 (tmp_list);
1789           g_free (filter);
1790           
1791           return;
1792         }
1793     }
1794 }
1795
1796 void
1797 gdk_window_set_override_redirect(GdkWindow *window,
1798                                  gboolean override_redirect)
1799 {
1800   GdkWindowPrivate *private;
1801   XSetWindowAttributes attr;
1802
1803   g_return_if_fail (window != NULL);
1804   private = (GdkWindowPrivate*) window;
1805   if (private->destroyed)
1806     return;
1807
1808   attr.override_redirect = (override_redirect == FALSE)?False:True;
1809   XChangeWindowAttributes(gdk_display,
1810                           ((GdkWindowPrivate *)window)->xwindow,
1811                           CWOverrideRedirect,
1812                           &attr);
1813 }
1814
1815 void          
1816 gdk_window_set_icon        (GdkWindow *window, 
1817                             GdkWindow *icon_window,
1818                             GdkPixmap *pixmap,
1819                             GdkBitmap *mask)
1820 {
1821   XWMHints wm_hints;
1822   GdkWindowPrivate *window_private;
1823   GdkWindowPrivate *private;
1824
1825   g_return_if_fail (window != NULL);
1826   window_private = (GdkWindowPrivate*) window;
1827   if (window_private->destroyed)
1828     return;
1829
1830   wm_hints.flags = 0;
1831   
1832   if (icon_window != NULL)
1833     {
1834       private = (GdkWindowPrivate *)icon_window;
1835       wm_hints.flags |= IconWindowHint;
1836       wm_hints.icon_window = private->xwindow;
1837     }
1838
1839   if (pixmap != NULL)
1840     {
1841       private = (GdkWindowPrivate *)pixmap;
1842       wm_hints.flags |= IconPixmapHint;
1843       wm_hints.icon_pixmap = private->xwindow;
1844     }
1845
1846   if (mask != NULL)
1847     {
1848       private = (GdkWindowPrivate *)mask;
1849       wm_hints.flags |= IconMaskHint;
1850       wm_hints.icon_mask = private->xwindow;
1851     }
1852
1853   XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1854 }
1855
1856 void          
1857 gdk_window_set_icon_name   (GdkWindow *window, 
1858                             gchar *    name)
1859 {
1860   GdkWindowPrivate *window_private;
1861   XTextProperty property;
1862   gint res;
1863
1864   g_return_if_fail (window != NULL);
1865   window_private = (GdkWindowPrivate*) window;
1866   if (window_private->destroyed)
1867     return;
1868   res = XmbTextListToTextProperty (window_private->xdisplay,
1869                                    &name, 1, XStdICCTextStyle,
1870                                    &property);
1871   if (res < 0)
1872     {
1873       g_warning("Error converting icon name to text property: %d\n", res);
1874       return;
1875     }
1876
1877   XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1878                   &property);
1879
1880   XFree(property.value);
1881 }
1882
1883 void          
1884 gdk_window_set_group   (GdkWindow *window, 
1885                         GdkWindow *leader)
1886 {
1887   XWMHints wm_hints;
1888   GdkWindowPrivate *window_private;
1889   GdkWindowPrivate *private;
1890
1891   g_return_if_fail (window != NULL);
1892   g_return_if_fail (leader != NULL);
1893   window_private = (GdkWindowPrivate*) window;
1894   if (window_private->destroyed)
1895     return;
1896
1897   private = (GdkWindowPrivate *)leader;
1898   wm_hints.flags = WindowGroupHint;
1899   wm_hints.window_group = private->xwindow;
1900
1901   XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1902 }
1903
1904 static void
1905 gdk_window_set_mwm_hints (GdkWindow *window,
1906                           MotifWmHints *new_hints)
1907 {
1908   static Atom hints_atom = None;
1909   MotifWmHints *hints;
1910   Atom type;
1911   gint format;
1912   gulong nitems;
1913   gulong bytes_after;
1914
1915   GdkWindowPrivate *window_private;
1916
1917   g_return_if_fail (window != NULL);
1918   window_private = (GdkWindowPrivate*) window;
1919   if (window_private->destroyed)
1920     return;
1921
1922   if (!hints_atom)
1923     hints_atom = XInternAtom (window_private->xdisplay, 
1924                               _XA_MOTIF_WM_HINTS, FALSE);
1925   
1926   XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1927                       hints_atom, 0, sizeof(MotifWmHints)/4,
1928                       False, AnyPropertyType, &type, &format, &nitems,
1929                       &bytes_after, (guchar **)&hints);
1930
1931   if (type == None)
1932     hints = new_hints;
1933   else
1934     {
1935       if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1936         {
1937           hints->flags |= MWM_HINTS_FUNCTIONS;
1938           hints->functions = new_hints->functions;
1939         }
1940       if (new_hints->flags & MWM_HINTS_DECORATIONS)
1941         {
1942           hints->flags |= MWM_HINTS_DECORATIONS;
1943           hints->decorations = new_hints->decorations;
1944         }
1945     }
1946
1947   XChangeProperty (window_private->xdisplay, window_private->xwindow,
1948                    hints_atom, hints_atom, 32, PropModeReplace,
1949                    (guchar *)hints, sizeof(MotifWmHints)/4);
1950
1951   if (hints != new_hints)
1952     XFree (hints);
1953 }
1954
1955 void
1956 gdk_window_set_decorations (GdkWindow      *window,
1957                             GdkWMDecoration decorations)
1958 {
1959   MotifWmHints hints;
1960
1961   hints.flags = MWM_HINTS_DECORATIONS;
1962   hints.decorations = decorations;
1963
1964   gdk_window_set_mwm_hints (window, &hints);
1965 }
1966
1967 void
1968 gdk_window_set_functions (GdkWindow    *window,
1969                           GdkWMFunction functions)
1970 {
1971   MotifWmHints hints;
1972
1973   hints.flags = MWM_HINTS_FUNCTIONS;
1974   hints.functions = functions;
1975
1976   gdk_window_set_mwm_hints (window, &hints);
1977 }
1978
1979 GList *
1980 gdk_window_get_toplevels (void)
1981 {
1982   GList *new_list = NULL;
1983   GList *tmp_list;
1984
1985   tmp_list = gdk_root_parent.children;
1986   while (tmp_list)
1987     {
1988       new_list = g_list_prepend (new_list, tmp_list->data);
1989       tmp_list = tmp_list->next;
1990     }
1991
1992   return new_list;
1993 }
1994