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