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