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