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