]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
- Show selection correctly when starting selection with arrows
[~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   g_return_if_fail (window != NULL);
769   g_return_if_fail (gc != NULL);
770   
771   if (source_window == NULL)
772     source_window = window;
773   
774   src_private = (GdkWindowPrivate*) source_window;
775   dest_private = (GdkWindowPrivate*) window;
776   gc_private = (GdkGCPrivate*) gc;
777   
778   if (!src_private->destroyed && !dest_private->destroyed)
779     {
780       XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
781                  gc_private->xgc,
782                  source_x, source_y,
783                  width, height,
784                  x, y);
785     }
786 }
787
788 void
789 gdk_window_raise (GdkWindow *window)
790 {
791   GdkWindowPrivate *private;
792   
793   g_return_if_fail (window != NULL);
794   
795   private = (GdkWindowPrivate*) window;
796   
797   if (!private->destroyed)
798     XRaiseWindow (private->xdisplay, private->xwindow);
799 }
800
801 void
802 gdk_window_lower (GdkWindow *window)
803 {
804   GdkWindowPrivate *private;
805   
806   g_return_if_fail (window != NULL);
807   
808   private = (GdkWindowPrivate*) window;
809   
810   if (!private->destroyed)
811     XLowerWindow (private->xdisplay, private->xwindow);
812 }
813
814 void
815 gdk_window_set_user_data (GdkWindow *window,
816                           gpointer   user_data)
817 {
818   g_return_if_fail (window != NULL);
819   
820   window->user_data = user_data;
821 }
822
823 void
824 gdk_window_set_hints (GdkWindow *window,
825                       gint       x,
826                       gint       y,
827                       gint       min_width,
828                       gint       min_height,
829                       gint       max_width,
830                       gint       max_height,
831                       gint       flags)
832 {
833   GdkWindowPrivate *private;
834   XSizeHints size_hints;
835   
836   g_return_if_fail (window != NULL);
837   
838   private = (GdkWindowPrivate*) window;
839   if (private->destroyed)
840     return;
841   
842   size_hints.flags = 0;
843   
844   if (flags & GDK_HINT_POS)
845     {
846       size_hints.flags |= PPosition;
847       size_hints.x = x;
848       size_hints.y = y;
849     }
850   
851   if (flags & GDK_HINT_MIN_SIZE)
852     {
853       size_hints.flags |= PMinSize;
854       size_hints.min_width = min_width;
855       size_hints.min_height = min_height;
856     }
857   
858   if (flags & GDK_HINT_MAX_SIZE)
859     {
860       size_hints.flags |= PMaxSize;
861       size_hints.max_width = max_width;
862       size_hints.max_height = max_height;
863     }
864   
865   if (flags)
866     XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
867 }
868
869 void
870 gdk_window_set_title (GdkWindow   *window,
871                       const gchar *title)
872 {
873   GdkWindowPrivate *private;
874   
875   g_return_if_fail (window != NULL);
876   
877   private = (GdkWindowPrivate*) window;
878   if (!private->destroyed)
879     XmbSetWMProperties (private->xdisplay, private->xwindow,
880                         title, title, NULL, 0, NULL, NULL, NULL);
881 }
882
883 void
884 gdk_window_set_background (GdkWindow *window,
885                            GdkColor  *color)
886 {
887   GdkWindowPrivate *private;
888   
889   g_return_if_fail (window != NULL);
890   
891   private = (GdkWindowPrivate*) window;
892   if (!private->destroyed)
893     XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
894 }
895
896 void
897 gdk_window_set_back_pixmap (GdkWindow *window,
898                             GdkPixmap *pixmap,
899                             gint       parent_relative)
900 {
901   GdkWindowPrivate *window_private;
902   GdkPixmapPrivate *pixmap_private;
903   Pixmap xpixmap;
904   
905   g_return_if_fail (window != NULL);
906   
907   window_private = (GdkWindowPrivate*) window;
908   pixmap_private = (GdkPixmapPrivate*) pixmap;
909   
910   if (pixmap)
911     xpixmap = pixmap_private->xwindow;
912   else
913     xpixmap = None;
914   
915   if (parent_relative)
916     xpixmap = ParentRelative;
917   
918   if (!window_private->destroyed)
919     XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
920 }
921
922 void
923 gdk_window_set_cursor (GdkWindow *window,
924                        GdkCursor *cursor)
925 {
926   GdkWindowPrivate *window_private;
927   GdkCursorPrivate *cursor_private;
928   Cursor xcursor;
929   
930   g_return_if_fail (window != NULL);
931   
932   window_private = (GdkWindowPrivate*) window;
933   cursor_private = (GdkCursorPrivate*) cursor;
934   
935   if (!cursor)
936     xcursor = None;
937   else
938     xcursor = cursor_private->xcursor;
939   
940   if (!window_private->destroyed)
941     XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
942 }
943
944 void
945 gdk_window_set_colormap (GdkWindow   *window,
946                          GdkColormap *colormap)
947 {
948   GdkWindowPrivate *window_private;
949   GdkColormapPrivate *colormap_private;
950   
951   g_return_if_fail (window != NULL);
952   g_return_if_fail (colormap != NULL);
953   
954   window_private = (GdkWindowPrivate*) window;
955   colormap_private = (GdkColormapPrivate*) colormap;
956   
957   if (!window_private->destroyed)
958     {
959       XSetWindowColormap (window_private->xdisplay,
960                           window_private->xwindow,
961                           colormap_private->xcolormap);
962       
963       if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
964         gdk_window_add_colormap_windows (window);
965     }
966 }
967
968 void
969 gdk_window_get_user_data (GdkWindow *window,
970                           gpointer  *data)
971 {
972   g_return_if_fail (window != NULL);
973   
974   *data = window->user_data;
975 }
976
977 void
978 gdk_window_get_geometry (GdkWindow *window,
979                          gint      *x,
980                          gint      *y,
981                          gint      *width,
982                          gint      *height,
983                          gint      *depth)
984 {
985   GdkWindowPrivate *window_private;
986   Window root;
987   gint tx;
988   gint ty;
989   guint twidth;
990   guint theight;
991   guint tborder_width;
992   guint tdepth;
993   
994   if (!window)
995     window = (GdkWindow*) &gdk_root_parent;
996   
997   window_private = (GdkWindowPrivate*) window;
998   
999   if (!window_private->destroyed)
1000     {
1001       XGetGeometry (window_private->xdisplay, window_private->xwindow,
1002                     &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1003       
1004       if (x)
1005         *x = tx;
1006       if (y)
1007         *y = ty;
1008       if (width)
1009         *width = twidth;
1010       if (height)
1011         *height = theight;
1012       if (depth)
1013         *depth = tdepth;
1014     }
1015 }
1016
1017 void
1018 gdk_window_get_position (GdkWindow *window,
1019                          gint      *x,
1020                          gint      *y)
1021 {
1022   GdkWindowPrivate *window_private;
1023   
1024   g_return_if_fail (window != NULL);
1025   
1026   window_private = (GdkWindowPrivate*) window;
1027   
1028   if (x)
1029     *x = window_private->x;
1030   if (y)
1031     *y = window_private->y;
1032 }
1033
1034 void
1035 gdk_window_get_size (GdkWindow *window,
1036                      gint       *width,
1037                      gint       *height)
1038 {
1039   GdkWindowPrivate *window_private;
1040   
1041   g_return_if_fail (window != NULL);
1042   
1043   window_private = (GdkWindowPrivate*) window;
1044   
1045   if (width)
1046     *width = window_private->width;
1047   if (height)
1048     *height = window_private->height;
1049 }
1050
1051 GdkVisual*
1052 gdk_window_get_visual (GdkWindow *window)
1053 {
1054   GdkWindowPrivate *window_private;
1055   XWindowAttributes window_attributes;
1056   
1057   g_return_val_if_fail (window != NULL, NULL);
1058   
1059   window_private = (GdkWindowPrivate*) window;
1060   while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
1061     window_private = (GdkWindowPrivate*) window_private->parent;
1062   
1063   if (window_private && !window_private->destroyed)
1064     {
1065       XGetWindowAttributes (window_private->xdisplay,
1066                             window_private->xwindow,
1067                             &window_attributes);
1068       
1069       return gdk_visual_lookup (window_attributes.visual);
1070     }
1071   
1072   return NULL;
1073 }
1074
1075 GdkColormap*
1076 gdk_window_get_colormap (GdkWindow *window)
1077 {
1078   GdkWindowPrivate *window_private;
1079   XWindowAttributes window_attributes;
1080   
1081   g_return_val_if_fail (window != NULL, NULL);
1082   
1083   window_private = (GdkWindowPrivate*) window;
1084   
1085   if (!window_private->destroyed)
1086     {
1087       XGetWindowAttributes (window_private->xdisplay,
1088                             window_private->xwindow,
1089                             &window_attributes);
1090       
1091       return gdk_colormap_lookup (window_attributes.colormap);
1092     }
1093   
1094   return NULL;
1095 }
1096
1097 GdkWindowType
1098 gdk_window_get_type (GdkWindow *window)
1099 {
1100   GdkWindowPrivate *window_private;
1101
1102   g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1103
1104   window_private = (GdkWindowPrivate*) window;
1105   return window_private->window_type;
1106 }
1107
1108 gint
1109 gdk_window_get_origin (GdkWindow *window,
1110                        gint      *x,
1111                        gint      *y)
1112 {
1113   GdkWindowPrivate *private;
1114   gint return_val;
1115   Window child;
1116   gint tx, ty;
1117
1118   g_return_val_if_fail (window != NULL, 0);
1119
1120   private = (GdkWindowPrivate*) window;
1121
1122   if (!private->destroyed)
1123     {
1124       return_val = XTranslateCoordinates (private->xdisplay,
1125                                           private->xwindow,
1126                                           gdk_root_window,
1127                                           0, 0, &tx, &ty,
1128                                           &child);
1129       
1130       if (x)
1131         *x = tx;
1132       if (y)
1133         *y = ty;
1134     }
1135   else
1136     return_val = 0;
1137   
1138   return return_val;
1139 }
1140
1141 GdkWindow*
1142 gdk_window_get_pointer (GdkWindow       *window,
1143                         gint            *x,
1144                         gint            *y,
1145                         GdkModifierType *mask)
1146 {
1147   GdkWindowPrivate *private;
1148   GdkWindow *return_val;
1149   Window root;
1150   Window child;
1151   int rootx, rooty;
1152   int winx, winy;
1153   unsigned int xmask;
1154
1155   if (!window)
1156     window = (GdkWindow*) &gdk_root_parent;
1157
1158   private = (GdkWindowPrivate*) window;
1159
1160   return_val = NULL;
1161   if (!private->destroyed &&
1162       XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
1163                      &rootx, &rooty, &winx, &winy, &xmask))
1164     {
1165       if (x) *x = winx;
1166       if (y) *y = winy;
1167       if (mask) *mask = xmask;
1168       
1169       if (child)
1170         return_val = gdk_window_lookup (child);
1171     }
1172   
1173   return return_val;
1174 }
1175
1176 GdkWindow*
1177 gdk_window_get_parent (GdkWindow *window)
1178 {
1179   g_return_val_if_fail (window != NULL, NULL);
1180
1181   return ((GdkWindowPrivate*) window)->parent;
1182 }
1183
1184 GdkWindow*
1185 gdk_window_get_toplevel (GdkWindow *window)
1186 {
1187   GdkWindowPrivate *private;
1188
1189   g_return_val_if_fail (window != NULL, NULL);
1190
1191   private = (GdkWindowPrivate*) window;
1192
1193   while (private->window_type == GDK_WINDOW_CHILD)
1194     {
1195       window = ((GdkWindowPrivate*) window)->parent;
1196       private = (GdkWindowPrivate*) window;
1197     }
1198
1199   return window;
1200 }
1201
1202 GList*
1203 gdk_window_get_children (GdkWindow *window)
1204 {
1205   GdkWindowPrivate *private;
1206   GdkWindow *child;
1207   GList *children;
1208   Window root;
1209   Window parent;
1210   Window *xchildren;
1211   unsigned int nchildren;
1212   unsigned int i;
1213
1214   g_return_val_if_fail (window != NULL, NULL);
1215
1216   private = (GdkWindowPrivate*) window;
1217   if (private->destroyed)
1218     return NULL;
1219
1220   XQueryTree (private->xdisplay, private->xwindow,
1221               &root, &parent, &xchildren, &nchildren);
1222
1223   children = NULL;
1224
1225   if (nchildren > 0)
1226     {
1227       for (i = 0; i < nchildren; i++)
1228         {
1229           child = gdk_window_lookup (xchildren[i]);
1230           if (child)
1231             children = g_list_prepend (children, child);
1232         }
1233
1234       XFree (xchildren);
1235     }
1236
1237   return children;
1238 }
1239
1240 GdkEventMask  
1241 gdk_window_get_events      (GdkWindow       *window)
1242 {
1243   GdkWindowPrivate *private;
1244   XWindowAttributes attrs;
1245   GdkEventMask event_mask;
1246   int i;
1247
1248   g_return_val_if_fail (window != NULL, 0);
1249
1250   private = (GdkWindowPrivate*) window;
1251   if (private->destroyed)
1252     return 0;
1253
1254   XGetWindowAttributes (gdk_display, private->xwindow, 
1255                         &attrs);
1256
1257   event_mask = 0;
1258   for (i = 0; i < nevent_masks; i++)
1259     {
1260       if (attrs.your_event_mask & event_mask_table[i])
1261         event_mask |= 1 << (i + 1);
1262     }
1263
1264   return event_mask;
1265 }
1266
1267 void          
1268 gdk_window_set_events      (GdkWindow       *window,
1269                             GdkEventMask     event_mask)
1270 {
1271   GdkWindowPrivate *private;
1272   long xevent_mask;
1273   int i;
1274
1275   g_return_if_fail (window != NULL);
1276
1277   private = (GdkWindowPrivate*) window;
1278   if (private->destroyed)
1279     return;
1280
1281   xevent_mask = StructureNotifyMask;
1282   for (i = 0; i < nevent_masks; i++)
1283     {
1284       if (event_mask & (1 << (i + 1)))
1285         xevent_mask |= event_mask_table[i];
1286     }
1287   
1288   XSelectInput (gdk_display, private->xwindow, 
1289                 xevent_mask);
1290 }
1291
1292 void
1293 gdk_window_add_colormap_windows (GdkWindow *window)
1294 {
1295   GdkWindow *toplevel;
1296   GdkWindowPrivate *toplevel_private;
1297   GdkWindowPrivate *window_private;
1298   Window *old_windows;
1299   Window *new_windows;
1300   int i, count;
1301
1302   g_return_if_fail (window != NULL);
1303
1304   toplevel = gdk_window_get_toplevel (window);
1305   toplevel_private = (GdkWindowPrivate*) toplevel;
1306   window_private = (GdkWindowPrivate*) window;
1307   if (window_private->destroyed)
1308     return;
1309
1310   if (!XGetWMColormapWindows (toplevel_private->xdisplay,
1311                               toplevel_private->xwindow,
1312                               &old_windows, &count))
1313     {
1314       old_windows = NULL;
1315       count = 0;
1316     }
1317
1318   for (i = 0; i < count; i++)
1319     if (old_windows[i] == window_private->xwindow)
1320       return;
1321
1322   new_windows = g_new (Window, count + 1);
1323
1324   for (i = 0; i < count; i++)
1325     new_windows[i] = old_windows[i];
1326   new_windows[count] = window_private->xwindow;
1327
1328   XSetWMColormapWindows (toplevel_private->xdisplay,
1329                          toplevel_private->xwindow,
1330                          new_windows, count + 1);
1331
1332   g_free (new_windows);
1333   if (old_windows)
1334     XFree (old_windows);
1335 }
1336
1337 /*
1338  * This needs the X11 shape extension.
1339  * If not available, simply remove the call to
1340  * XShapeCombineMask. Shaped windows will look
1341  * ugly, but programs still work.    Stefan Wille
1342  */
1343 void
1344 gdk_window_shape_combine_mask (GdkWindow *window,
1345                                GdkBitmap *mask,
1346                                gint x, gint y)
1347 {
1348   GdkWindowPrivate *window_private;
1349   Pixmap pixmap;
1350
1351   g_return_if_fail (window != NULL);
1352
1353   window_private = (GdkWindowPrivate*) window;
1354   if (window_private->destroyed)
1355     return;
1356
1357   if (mask)
1358     {
1359       GdkWindowPrivate *pixmap_private;
1360
1361       pixmap_private = (GdkWindowPrivate*) mask;
1362       pixmap = (Pixmap) pixmap_private->xwindow;
1363     }
1364   else
1365     {
1366       x = 0;
1367       y = 0;
1368       pixmap = None;
1369     }
1370
1371   XShapeCombineMask  (window_private->xdisplay,
1372                       window_private->xwindow,
1373                       ShapeBounding,
1374                       x, y,
1375                       pixmap,
1376                       ShapeSet);
1377 }
1378
1379 void
1380 gdk_dnd_drag_addwindow (GdkWindow *window)
1381 {
1382   GdkWindowPrivate *window_private;
1383   
1384   g_return_if_fail (window != NULL);
1385   
1386   window_private = (GdkWindowPrivate *) window;
1387   if (window_private->destroyed)
1388     return;
1389   
1390   if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
1391     {
1392       gdk_dnd.drag_numwindows++;
1393       gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
1394                                              gdk_dnd.drag_numwindows
1395                                              * sizeof(GdkWindow *));
1396       gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
1397       window_private->dnd_drag_accepted = 0;
1398     } 
1399   else
1400     g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
1401 }
1402
1403 void
1404 gdk_window_dnd_drag_set (GdkWindow   *window,
1405                          guint8       drag_enable,
1406                          gchar      **typelist,
1407                          guint        numtypes)
1408 {
1409   GdkWindowPrivate *window_private;
1410   int i, wasset = 0;
1411   
1412   g_return_if_fail (window != NULL);
1413   window_private = (GdkWindowPrivate *) window;
1414   if (window_private->destroyed)
1415     return;
1416   
1417   window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
1418   
1419   if (drag_enable)
1420     {
1421       g_return_if_fail(typelist != NULL);
1422       
1423       if (window_private->dnd_drag_data_numtypesavail > 3)
1424         wasset = 1;
1425       window_private->dnd_drag_data_numtypesavail = numtypes;
1426       
1427       window_private->dnd_drag_data_typesavail =
1428         g_realloc (window_private->dnd_drag_data_typesavail,
1429                    (numtypes + 1) * sizeof (GdkAtom));
1430       
1431       for (i = 0; i < numtypes; i++)
1432         {
1433           /* Allow blanket use of ALL to get anything... */
1434           if (strcmp (typelist[i], "ALL"))
1435             window_private->dnd_drag_data_typesavail[i] =
1436               gdk_atom_intern (typelist[i], FALSE);
1437           else
1438             window_private->dnd_drag_data_typesavail[i] = None;
1439         }
1440       
1441       /* 
1442        * set our extended type list if we need to 
1443        */
1444       if (numtypes > 3)
1445         gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
1446                             XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
1447                             (guchar *)(window_private->dnd_drag_data_typesavail
1448                              + (sizeof(GdkAtom) * 3)),
1449                             (numtypes - 3) * sizeof(GdkAtom));
1450       else if (wasset)
1451         gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
1452     }
1453   else
1454     {
1455       g_free (window_private->dnd_drag_data_typesavail);
1456       window_private->dnd_drag_data_typesavail = NULL;
1457       window_private->dnd_drag_data_numtypesavail = 0;
1458     }
1459 }
1460
1461 void
1462 gdk_window_dnd_drop_set (GdkWindow   *window,
1463                          guint8       drop_enable,
1464                          gchar      **typelist,
1465                          guint        numtypes,
1466                          guint8       destructive_op)
1467 {
1468   GdkWindowPrivate *window_private;
1469   int i;
1470   
1471   g_return_if_fail (window != NULL);
1472   window_private = (GdkWindowPrivate *) window;
1473   if (window_private->destroyed)
1474     return;
1475   
1476   window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
1477   if (drop_enable)
1478     {
1479       g_return_if_fail(typelist != NULL);
1480       
1481       window_private->dnd_drop_data_numtypesavail = numtypes;
1482       
1483       window_private->dnd_drop_data_typesavail =
1484         g_realloc (window_private->dnd_drop_data_typesavail,
1485                    (numtypes + 1) * sizeof (GdkAtom));
1486       
1487       for (i = 0; i < numtypes; i++)
1488         window_private->dnd_drop_data_typesavail[i] =
1489           gdk_atom_intern (typelist[i], FALSE);
1490       
1491       window_private->dnd_drop_destructive_op = destructive_op;
1492     }
1493 }
1494
1495 /* 
1496  * This is used to reply to a GDK_DRAG_REQUEST event
1497  * (which may be generated by XdeRequest or a confirmed drop... 
1498  */
1499 void
1500 gdk_window_dnd_data_set (GdkWindow       *window,
1501                          GdkEvent        *event,
1502                          gpointer         data,
1503                          gulong           data_numbytes)
1504 {
1505   GdkWindowPrivate *window_private;
1506   XEvent sev;
1507   GdkEventDropDataAvailable tmp_ev;
1508   gchar *tmp;
1509   
1510   g_return_if_fail (window != NULL);
1511   g_return_if_fail (event != NULL);
1512   g_return_if_fail (data != NULL);
1513   g_return_if_fail (data_numbytes > 0);
1514   g_return_if_fail (event->type == GDK_DRAG_REQUEST);
1515
1516   window_private = (GdkWindowPrivate *) window;
1517   g_return_if_fail (window_private->dnd_drag_accepted != 0);    
1518   if (window_private->destroyed)
1519     return;
1520   
1521   /* We set the property on our window... */
1522   gdk_property_change (window, window_private->dnd_drag_data_type,
1523                        XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
1524                        data_numbytes);
1525   tmp = gdk_atom_name(window_private->dnd_drag_data_type);
1526 #ifdef DEBUG_DND
1527   g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
1528 #endif
1529   g_free(tmp);
1530   
1531   /* 
1532    * Then we send the event to tell the receiving window that the
1533    * drop has happened 
1534    */
1535   tmp_ev.u.allflags = 0;
1536   tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
1537   tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
1538   
1539   sev.xclient.type = ClientMessage;
1540   sev.xclient.format = 32;
1541   sev.xclient.window = event->dragrequest.requestor;
1542   sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
1543   sev.xclient.data.l[0] = window_private->xwindow;
1544   sev.xclient.data.l[1] = tmp_ev.u.allflags;
1545   sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
1546
1547   if (event->dragrequest.isdrop)
1548     sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
1549       (event->dragrequest.drop_coords.y << 16);
1550   else
1551     sev.xclient.data.l[3] = 0;
1552   
1553   sev.xclient.data.l[4] = 0;
1554
1555   if (!gdk_send_xevent (event->dragrequest.requestor, False,
1556                        NoEventMask, &sev))
1557     GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
1558                            event->dragrequest.requestor));
1559
1560 }
1561
1562 void          
1563 gdk_window_add_filter     (GdkWindow     *window,
1564                            GdkFilterFunc  function,
1565                            gpointer       data)
1566 {
1567   GdkWindowPrivate *private;
1568   GList *tmp_list;
1569   GdkEventFilter *filter;
1570
1571   private = (GdkWindowPrivate*) window;
1572   if (private && private->destroyed)
1573     return;
1574
1575   if(private)
1576     tmp_list = private->filters;
1577   else
1578     tmp_list = gdk_default_filters;
1579
1580   while (tmp_list)
1581     {
1582       filter = (GdkEventFilter *)tmp_list->data;
1583       if ((filter->function == function) && (filter->data == data))
1584         return;
1585       tmp_list = tmp_list->next;
1586     }
1587
1588   filter = g_new (GdkEventFilter, 1);
1589   filter->function = function;
1590   filter->data = data;
1591
1592   if(private)
1593     private->filters = g_list_append (private->filters, filter);
1594   else
1595     gdk_default_filters = g_list_append (gdk_default_filters, filter);
1596 }
1597
1598 void
1599 gdk_window_remove_filter  (GdkWindow     *window,
1600                            GdkFilterFunc  function,
1601                            gpointer       data)
1602 {
1603   GdkWindowPrivate *private;
1604   GList *tmp_list;
1605   GdkEventFilter *filter;
1606
1607   private = (GdkWindowPrivate*) window;
1608
1609   if(private)
1610     tmp_list = private->filters;
1611   else
1612     tmp_list = gdk_default_filters;
1613
1614   while (tmp_list)
1615     {
1616       filter = (GdkEventFilter *)tmp_list->data;
1617       tmp_list = tmp_list->next;
1618
1619       if ((filter->function == function) && (filter->data == data))
1620         {
1621           if(private)
1622             private->filters = g_list_remove_link (private->filters, tmp_list);
1623           else
1624             gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
1625           g_list_free_1 (tmp_list);
1626           g_free (filter);
1627           
1628           return;
1629         }
1630     }
1631 }
1632
1633 void
1634 gdk_window_set_override_redirect(GdkWindow *window,
1635                                  gboolean override_redirect)
1636 {
1637   GdkWindowPrivate *private;
1638   XSetWindowAttributes attr;
1639
1640   g_return_if_fail (window != NULL);
1641   private = (GdkWindowPrivate*) window;
1642   if (private->destroyed)
1643     return;
1644
1645   attr.override_redirect = (override_redirect == FALSE)?False:True;
1646   XChangeWindowAttributes(gdk_display,
1647                           ((GdkWindowPrivate *)window)->xwindow,
1648                           CWOverrideRedirect,
1649                           &attr);
1650 }
1651
1652 void          
1653 gdk_window_set_icon        (GdkWindow *window, 
1654                             GdkWindow *icon_window,
1655                             GdkPixmap *pixmap,
1656                             GdkBitmap *mask)
1657 {
1658   XWMHints wm_hints;
1659   GdkWindowPrivate *window_private;
1660   GdkWindowPrivate *private;
1661
1662   g_return_if_fail (window != NULL);
1663   window_private = (GdkWindowPrivate*) window;
1664   if (window_private->destroyed)
1665     return;
1666
1667   wm_hints.flags = 0;
1668   
1669   if (icon_window != NULL)
1670     {
1671       private = (GdkWindowPrivate *)icon_window;
1672       wm_hints.flags |= IconWindowHint;
1673       wm_hints.icon_window = private->xwindow;
1674     }
1675
1676   if (pixmap != NULL)
1677     {
1678       private = (GdkWindowPrivate *)pixmap;
1679       wm_hints.flags |= IconPixmapHint;
1680       wm_hints.icon_pixmap = private->xwindow;
1681     }
1682
1683   if (mask != NULL)
1684     {
1685       private = (GdkWindowPrivate *)mask;
1686       wm_hints.flags |= IconMaskHint;
1687       wm_hints.icon_mask = private->xwindow;
1688     }
1689
1690   XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1691 }
1692
1693 void          
1694 gdk_window_set_icon_name   (GdkWindow *window, 
1695                             gchar *    name)
1696 {
1697   GdkWindowPrivate *window_private;
1698   XTextProperty property;
1699   gint res;
1700
1701   g_return_if_fail (window != NULL);
1702   window_private = (GdkWindowPrivate*) window;
1703   if (window_private->destroyed)
1704     return;
1705   res = XmbTextListToTextProperty (window_private->xdisplay,
1706                                    &name, 1, XStdICCTextStyle,
1707                                    &property);
1708   if (res < 0)
1709     {
1710       g_warning("Error converting icon name to text property: %d\n", res);
1711       return;
1712     }
1713
1714   XSetWMIconName (window_private->xdisplay, window_private->xwindow,
1715                   &property);
1716
1717   XFree(property.value);
1718 }
1719
1720 void          
1721 gdk_window_set_group   (GdkWindow *window, 
1722                         GdkWindow *leader)
1723 {
1724   XWMHints wm_hints;
1725   GdkWindowPrivate *window_private;
1726   GdkWindowPrivate *private;
1727
1728   g_return_if_fail (window != NULL);
1729   g_return_if_fail (leader != NULL);
1730   window_private = (GdkWindowPrivate*) window;
1731   if (window_private->destroyed)
1732     return;
1733
1734   private = (GdkWindowPrivate *)leader;
1735   wm_hints.flags |= WindowGroupHint;
1736   wm_hints.window_group = private->xwindow;
1737
1738   XSetWMHints (window_private->xdisplay, window_private->xwindow, &wm_hints);
1739 }
1740
1741 static void
1742 gdk_window_set_mwm_hints (GdkWindow *window,
1743                           MotifWmHints *new_hints)
1744 {
1745   static Atom hints_atom = None;
1746   MotifWmHints *hints;
1747   Atom type;
1748   gint format;
1749   gulong nitems;
1750   gulong bytes_after;
1751
1752   GdkWindowPrivate *window_private;
1753
1754   g_return_if_fail (window != NULL);
1755   window_private = (GdkWindowPrivate*) window;
1756   if (window_private->destroyed)
1757     return;
1758
1759   if (!hints_atom)
1760     hints_atom = XInternAtom (window_private->xdisplay, 
1761                               _XA_MOTIF_WM_HINTS, FALSE);
1762   
1763   XGetWindowProperty (window_private->xdisplay, window_private->xwindow,
1764                       hints_atom, 0, sizeof(MotifWmHints)/4,
1765                       False, AnyPropertyType, &type, &format, &nitems,
1766                       &bytes_after, (guchar **)&hints);
1767
1768   if (type == None)
1769     hints = new_hints;
1770   else
1771     {
1772       if (new_hints->flags & MWM_HINTS_FUNCTIONS)
1773         {
1774           hints->flags |= MWM_HINTS_FUNCTIONS;
1775           hints->functions = new_hints->functions;
1776         }
1777       if (new_hints->flags & MWM_HINTS_DECORATIONS)
1778         {
1779           hints->flags |= MWM_HINTS_DECORATIONS;
1780           hints->decorations = new_hints->decorations;
1781         }
1782     }
1783
1784   XChangeProperty (window_private->xdisplay, window_private->xwindow,
1785                    hints_atom, hints_atom, 32, PropModeReplace,
1786                    (guchar *)hints, sizeof(MotifWmHints)/4);
1787
1788   if (hints != new_hints)
1789     XFree (hints);
1790 }
1791
1792 void
1793 gdk_window_set_decorations (GdkWindow      *window,
1794                             GdkWMDecoration decorations)
1795 {
1796   MotifWmHints hints;
1797
1798   hints.flags = MWM_HINTS_DECORATIONS;
1799   hints.decorations = decorations;
1800
1801   gdk_window_set_mwm_hints (window, &hints);
1802 }
1803
1804 void
1805 gdk_window_set_functions (GdkWindow    *window,
1806                           GdkWMFunction functions)
1807 {
1808   MotifWmHints hints;
1809
1810   hints.flags = MWM_HINTS_FUNCTIONS;
1811   hints.functions = functions;
1812
1813   gdk_window_set_mwm_hints (window, &hints);
1814 }