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