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