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