]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkwindow.c
Change GDK_WINDOWING_WIN32 usage to #ifdef also here.
[~andy/gtk] / gdk / win32 / gdkwindow.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-1999 Tor Lillqvist
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "config.h"
29
30 #include <stdlib.h>
31 #include <stdio.h>
32
33 #include "gdkevents.h"
34 #include "gdkwindow.h"
35 #include "gdkprivate.h"
36 #include "gdkinputprivate.h"
37
38 /* The Win API function AdjustWindowRect may return negative values
39  * resulting in obscured title bars. This helper function is coreccting it.
40  */
41 BOOL
42 SafeAdjustWindowRectEx (RECT* lpRect, 
43                         DWORD dwStyle, 
44                         BOOL bMenu, 
45                         DWORD dwExStyle)
46 {
47   if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
48     return FALSE;
49   if (lpRect->left < 0)
50     {
51       lpRect->right -= lpRect->left;
52       lpRect->left = 0;
53     }
54   if (lpRect->top < 0)
55     {
56       lpRect->bottom -= lpRect->top;
57       lpRect->top = 0;
58     }
59   return TRUE;
60 }
61
62 /* Forward declarations */
63 static gboolean gdk_window_gravity_works (void);
64 static void     gdk_window_set_static_win_gravity (GdkWindow *window, 
65                                                    gboolean   on);
66
67 /* 
68  * The following fucntion by The Rasterman <raster@redhat.com>
69  * This function returns the X Window ID in which the x y location is in 
70  * (x and y being relative to the root window), excluding any windows listed
71  * in the GList excludes (this is a list of X Window ID's - gpointer being
72  * the Window ID).
73  * 
74  * This is primarily designed for internal gdk use - for DND for example
75  * when using a shaped icon window as the drag object - you exclude the
76  * X Window ID of the "icon" (perhaps more if excludes may be needed) and
77  * You can get back an X Window ID as to what X Window ID is infact under
78  * those X,Y co-ordinates.
79  */
80 HWND
81 gdk_window_xid_at_coords (gint     x,
82                           gint     y,
83                           GList   *excludes,
84                           gboolean excl_child)
85 {
86   POINT pt;
87   gboolean warned = FALSE;
88
89   pt.x = x;
90   pt.y = y;
91   /* This is probably not correct, just a quick hack */
92
93   if (!warned)
94     {
95       g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
96       warned = TRUE;
97     }
98
99   /* XXX */
100   return WindowFromPoint (pt);
101 }
102
103 void
104 gdk_window_init (void)
105 {
106   unsigned int width;
107   unsigned int height;
108 #if 0
109   width = GetSystemMetrics (SM_CXSCREEN);
110   height = GetSystemMetrics (SM_CYSCREEN);
111 #else
112   { RECT r; /* //HB: don't obscure tray window (task bar) */
113     SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
114     width  = r.right - r.left;
115     height = r.bottom - r.top;
116   }
117 #endif
118
119   gdk_root_parent.xwindow = gdk_root_window;
120   gdk_root_parent.window_type = GDK_WINDOW_ROOT;
121   gdk_root_parent.window.user_data = NULL;
122   gdk_root_parent.width = width;
123   gdk_root_parent.height = height;
124   gdk_root_parent.children = NULL;
125   gdk_root_parent.colormap = NULL;
126   gdk_root_parent.ref_count = 1;
127
128   gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
129 }
130
131 /* RegisterGdkClass
132  *   is a wrapper function for RegisterWindowClassEx.
133  *   It creates at least one unique class for every 
134  *   GdkWindowType. If support for single window-specific icons
135  *   is ever needed (e.g Dialog specific), every such window should
136  *   get its own class
137  */
138 ATOM
139 RegisterGdkClass(GdkWindowType wtype)
140 {
141   static ATOM klassTOPLEVEL = 0;
142   static ATOM klassDIALOG   = 0;
143   static ATOM klassCHILD    = 0;
144   static ATOM klassTEMP     = 0;
145   static HICON hAppIcon = NULL;
146   static WNDCLASSEX wcl; 
147   ATOM klass = 0;
148
149   wcl.cbSize = sizeof(WNDCLASSEX);     
150   wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
151                   * on WM_SIZE and WM_MOVE. Flicker, Performance!
152                   */
153   wcl.lpfnWndProc = gdk_WindowProc;
154   wcl.cbClsExtra = 0;
155   wcl.cbWndExtra = 0;
156   wcl.hInstance = gdk_ProgInstance;
157   wcl.hIcon = 0;
158   /* initialize once! */
159   if (0 == hAppIcon)
160     {
161       gchar sLoc [_MAX_PATH+1];
162       HINSTANCE hInst = GetModuleHandle(NULL);
163
164       if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
165         {
166           hAppIcon = ExtractIcon(hInst, sLoc, 0);
167           if (0 == hAppIcon)
168             {
169               char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
170
171               hAppIcon = ExtractIcon(hInst, gdklibname, 0);
172               g_free (gdklibname);
173             }
174           
175           if (0 == hAppIcon) 
176             hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
177         }
178     }
179
180   wcl.lpszMenuName = NULL;
181   wcl.hIconSm = 0;
182
183   /* initialize once per class */
184 #define ONCE_PER_CLASS() \
185   wcl.hIcon = CopyIcon (hAppIcon); \
186   wcl.hIconSm = CopyIcon (hAppIcon); \
187   wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
188   wcl.hCursor = LoadCursor (NULL, IDC_ARROW); 
189   
190   switch (wtype)
191   {
192     case GDK_WINDOW_TOPLEVEL:
193       if (0 == klassTOPLEVEL)
194       {
195         wcl.lpszClassName = "gdkWindowToplevel";
196
197         ONCE_PER_CLASS();
198         klassTOPLEVEL = RegisterClassEx(&wcl);
199       }
200       klass = klassTOPLEVEL;
201       break;
202     case GDK_WINDOW_CHILD:
203       if (0 == klassCHILD)
204       {
205         wcl.lpszClassName = "gdkWindowChild";
206
207         wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
208         ONCE_PER_CLASS();
209         klassCHILD = RegisterClassEx(&wcl);
210       }
211       klass = klassCHILD;
212       break;
213     case GDK_WINDOW_DIALOG:
214       if (0 == klassDIALOG)
215       {
216         wcl.lpszClassName = "gdkWindowDialog";
217         wcl.style |= CS_SAVEBITS;
218         ONCE_PER_CLASS();
219         klassDIALOG = RegisterClassEx(&wcl);
220       }
221       klass = klassDIALOG;
222       break;
223     case GDK_WINDOW_TEMP:
224       if (0 == klassTEMP)
225       {
226         wcl.lpszClassName = "gdkWindowTemp";
227         wcl.style |= CS_SAVEBITS;
228         ONCE_PER_CLASS();
229         klassTEMP = RegisterClassEx(&wcl);
230       }
231       klass = klassTEMP;
232       break;
233     case GDK_WINDOW_ROOT:
234       g_error ("cannot make windows of type GDK_WINDOW_ROOT");
235       break;
236     case GDK_WINDOW_PIXMAP:
237       g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
238       break;
239   }
240
241   return klass;
242 } /* RegisterGdkClass */
243
244
245 GdkWindow*
246 gdk_window_new (GdkWindow     *parent,
247                 GdkWindowAttr *attributes,
248                 gint           attributes_mask)
249 {
250   GdkWindow *window;
251   GdkWindowPrivate *private;
252   GdkWindowPrivate *parent_private;
253   GdkVisual *visual;
254   HANDLE xparent;
255   Visual *xvisual;
256   ATOM klass = 0;
257   DWORD dwStyle, dwExStyle;
258   RECT rect;
259   int width, height;
260   int x, y;
261   char *title;
262
263   g_return_val_if_fail (attributes != NULL, NULL);
264
265   if (!parent)
266     parent = (GdkWindow*) &gdk_root_parent;
267
268   parent_private = (GdkWindowPrivate*) parent;
269   if (parent_private->destroyed)
270     return NULL;
271
272   xparent = parent_private->xwindow;
273
274   private = g_new (GdkWindowPrivate, 1);
275   window = (GdkWindow*) private;
276
277   private->parent = parent;
278
279   private->destroyed = FALSE;
280   private->mapped = FALSE;
281   private->guffaw_gravity = FALSE;
282   private->resize_count = 0;
283   private->ref_count = 1;
284
285   private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
286   private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
287
288   private->width = (attributes->width > 1) ? (attributes->width) : (1);
289   private->height = (attributes->height > 1) ? (attributes->height) : (1);
290   private->window_type = attributes->window_type;
291   private->extension_events = 0;
292   private->extension_events_selected = FALSE;
293
294   private->filters = NULL;
295   private->children = NULL;
296
297   window->user_data = NULL;
298
299   if (attributes_mask & GDK_WA_VISUAL)
300     visual = attributes->visual;
301   else
302     visual = gdk_visual_get_system ();
303   xvisual = ((GdkVisualPrivate*) visual)->xvisual;
304
305   if (attributes_mask & GDK_WA_TITLE)
306     title = attributes->title;
307   else
308     title = g_get_prgname ();
309
310   private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
311   private->bg_type = GDK_WIN32_BG_NORMAL;
312   private->hint_flags = 0;
313   private->xcursor = NULL;
314       
315   if (parent_private && parent_private->guffaw_gravity)
316     {
317       /* XXX ??? */
318     }
319
320   if (attributes->wclass == GDK_INPUT_OUTPUT)
321     {
322       dwExStyle = 0;
323       if (attributes_mask & GDK_WA_COLORMAP)
324         private->colormap = attributes->colormap;
325       else
326         private->colormap = gdk_colormap_get_system ();
327     }
328   else
329     {
330       dwExStyle = WS_EX_TRANSPARENT;
331       private->colormap = NULL;
332       private->bg_type = GDK_WIN32_BG_TRANSPARENT;
333       private->bg_pixmap = NULL;
334     }
335
336   if (attributes_mask & GDK_WA_X)
337     x = attributes->x;
338   else
339     x = CW_USEDEFAULT;
340
341   if (attributes_mask & GDK_WA_Y)
342     y = attributes->y;
343   else if (attributes_mask & GDK_WA_X)
344     y = 100;                    /* ??? We must put it somewhere... */
345   else
346     y = 500;                    /* x is CW_USEDEFAULT, y doesn't matter then */
347
348   if (parent_private)
349     parent_private->children = g_list_prepend (parent_private->children, window);
350
351   switch (private->window_type)
352     {
353     case GDK_WINDOW_TOPLEVEL:
354       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
355       xparent = gdk_root_window;
356       break;
357     case GDK_WINDOW_CHILD:
358       dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
359       break;
360     case GDK_WINDOW_DIALOG:
361       dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
362       dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
363       xparent = gdk_root_window;
364       break;
365     case GDK_WINDOW_TEMP:
366       dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
367       dwExStyle |= WS_EX_TOOLWINDOW;
368       break;
369     case GDK_WINDOW_ROOT:
370       g_error ("cannot make windows of type GDK_WINDOW_ROOT");
371       break;
372     case GDK_WINDOW_PIXMAP:
373       g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
374       break;
375     }
376
377   klass = RegisterGdkClass (private->window_type);
378   if (!klass)
379     g_error ("RegisterClassEx failed");
380
381   if (private->window_type != GDK_WINDOW_CHILD)
382     {
383       if (x == CW_USEDEFAULT)
384         {
385           rect.left = 100;
386           rect.top = 100;
387         }
388       else
389         {
390           rect.left = x;
391           rect.top = y;
392         }
393
394       rect.right = rect.left + private->width;
395       rect.bottom = rect.top + private->height;
396
397       if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
398         g_warning ("gdk_window_new: AdjustWindowRectEx failed");
399
400       if (x != CW_USEDEFAULT)
401         {
402           x = rect.left;
403           y = rect.top;
404         }
405       width = rect.right - rect.left;
406       height = rect.bottom - rect.top;
407     }
408   else
409     {
410       width = private->width;
411       height = private->height;
412     }
413
414   private->xwindow =
415     CreateWindowEx (dwExStyle,
416                     MAKEINTRESOURCE(klass),
417                     title,
418                     dwStyle,
419                     x, y, 
420                     width, height,
421                     xparent,
422                     NULL,
423                     gdk_ProgInstance,
424                     NULL);
425   GDK_NOTE (MISC,
426             g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
427                      (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
428                       (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
429                        (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
430                         (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
431                          "???")))),
432                      title,
433                      dwStyle,
434                      private->event_mask,
435                      width, height, (x == CW_USEDEFAULT ? -9999 : x), y, 
436                      xparent,
437                      private->xwindow));
438
439   gdk_window_ref (window);
440   gdk_xid_table_insert (&private->xwindow, window);
441
442   if (private->colormap)
443     gdk_colormap_ref (private->colormap);
444
445   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
446                                   (attributes->cursor) :
447                                   NULL));
448
449   return window;
450 }
451
452 GdkWindow *
453 gdk_window_foreign_new (guint32 anid)
454 {
455   GdkWindow *window;
456   GdkWindowPrivate *private;
457   GdkWindowPrivate *parent_private;
458   HANDLE parent;
459   RECT rect;
460   POINT point;
461
462   private = g_new (GdkWindowPrivate, 1);
463   window = (GdkWindow*) private;
464
465   parent = GetParent ((HWND) anid);
466   private->parent = gdk_xid_table_lookup (parent);
467
468   parent_private = (GdkWindowPrivate *)private->parent;
469   
470   if (parent_private)
471     parent_private->children = g_list_prepend (parent_private->children, window);
472
473   private->xwindow = (HWND) anid;
474   GetClientRect ((HWND) anid, &rect);
475   point.x = rect.left;
476   point.y = rect.right;
477   ClientToScreen ((HWND) anid, &point);
478   if (parent != HWND_DESKTOP)
479     ScreenToClient (parent, &point);
480   private->x = point.x;
481   private->y = point.y;
482   private->width = rect.right - rect.left;
483   private->height = rect.bottom - rect.top;
484   private->resize_count = 0;
485   private->ref_count = 1;
486   private->window_type = GDK_WINDOW_FOREIGN;
487   private->destroyed = FALSE;
488   private->mapped = IsWindowVisible (private->xwindow);
489   private->guffaw_gravity = FALSE;
490   private->extension_events = 0;
491   private->extension_events_selected = FALSE;
492
493   private->colormap = NULL;
494
495   private->filters = NULL;
496   private->children = NULL;
497
498   window->user_data = NULL;
499
500   gdk_window_ref (window);
501   gdk_xid_table_insert (&private->xwindow, window);
502
503   return window;
504 }
505
506 /* Call this function when you want a window and all its children to
507  * disappear.  When xdestroy is true, a request to destroy the XWindow
508  * is sent out.  When it is false, it is assumed that the XWindow has
509  * been or will be destroyed by destroying some ancestor of this
510  * window.
511  */
512 static void
513 gdk_window_internal_destroy (GdkWindow *window,
514                              gboolean   xdestroy,
515                              gboolean   our_destroy)
516 {
517   GdkWindowPrivate *private;
518   GdkWindowPrivate *temp_private;
519   GdkWindow *temp_window;
520   GList *children;
521   GList *tmp;
522
523   g_return_if_fail (window != NULL);
524
525   private = (GdkWindowPrivate*) window;
526
527   GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
528                            private->xwindow));
529
530   switch (private->window_type)
531     {
532     case GDK_WINDOW_TOPLEVEL:
533     case GDK_WINDOW_CHILD:
534     case GDK_WINDOW_DIALOG:
535     case GDK_WINDOW_TEMP:
536     case GDK_WINDOW_FOREIGN:
537       if (!private->destroyed)
538         {
539           if (private->parent)
540             {
541               GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
542               if (parent_private->children)
543                 parent_private->children = g_list_remove (parent_private->children, window);
544             }
545
546           if (private->window_type != GDK_WINDOW_FOREIGN)
547             {
548               children = tmp = private->children;
549               private->children = NULL;
550
551               while (tmp)
552                 {
553                   temp_window = tmp->data;
554                   tmp = tmp->next;
555                   
556                   temp_private = (GdkWindowPrivate*) temp_window;
557                   if (temp_private)
558                     gdk_window_internal_destroy (temp_window, FALSE,
559                                                  our_destroy);
560                 }
561
562               g_list_free (children);
563             }
564
565           if (private->extension_events != 0)
566             gdk_input_window_destroy (window);
567
568           if (private->filters)
569             {
570               tmp = private->filters;
571
572               while (tmp)
573                 {
574                   g_free (tmp->data);
575                   tmp = tmp->next;
576                 }
577
578               g_list_free (private->filters);
579               private->filters = NULL;
580             }
581           
582           if (private->window_type == GDK_WINDOW_FOREIGN)
583             {
584               if (our_destroy && (private->parent != NULL))
585                 {
586                   /* It's somebody elses window, but in our hierarchy,
587                    * so reparent it to the root window, and then send
588                    * it a delete event, as if we were a WM
589                    */
590                   gdk_window_hide (window);
591                   gdk_window_reparent (window, NULL, 0, 0);
592                   
593                   /* Is this too drastic? Many (most?) applications
594                    * quit if any window receives WM_QUIT I think.
595                    * OTOH, I don't think foreign windows are much
596                    * used, so the question is maybe academic.
597                    */
598                   PostMessage (private->xwindow, WM_QUIT, 0, 0);
599                 }
600             }
601           else if (xdestroy)
602             DestroyWindow (private->xwindow);
603
604           if (private->colormap)
605             gdk_colormap_unref (private->colormap);
606
607           private->mapped = FALSE;
608           private->destroyed = TRUE;
609         }
610       break;
611
612     case GDK_WINDOW_ROOT:
613       g_error ("attempted to destroy root window");
614       break;
615
616     case GDK_WINDOW_PIXMAP:
617       g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
618       break;
619     }
620 }
621
622 /* Like internal_destroy, but also destroys the reference created by
623    gdk_window_new. */
624
625 void
626 gdk_window_destroy (GdkWindow *window)
627 {
628   gdk_window_internal_destroy (window, TRUE, TRUE);
629   gdk_window_unref (window);
630 }
631
632 /* This function is called when the XWindow is really gone.  */
633
634 void
635 gdk_window_destroy_notify (GdkWindow *window)
636 {
637   GdkWindowPrivate *private;
638
639   g_return_if_fail (window != NULL);
640
641   private = (GdkWindowPrivate*) window;
642
643   GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x  %d\n",
644                              private->xwindow, private->destroyed));
645
646   if (!private->destroyed)
647     {
648       if (private->window_type == GDK_WINDOW_FOREIGN)
649         gdk_window_internal_destroy (window, FALSE, FALSE);
650       else
651         g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
652     }
653   
654   gdk_xid_table_remove (private->xwindow);
655   gdk_window_unref (window);
656 }
657
658 GdkWindow*
659 gdk_window_ref (GdkWindow *window)
660 {
661   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
662   g_return_val_if_fail (window != NULL, NULL);
663
664   private->ref_count += 1;
665
666   GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
667                            private->xwindow, private->ref_count));
668
669   return window;
670 }
671
672 void
673 gdk_window_unref (GdkWindow *window)
674 {
675   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
676   g_return_if_fail (window != NULL);
677
678   private->ref_count -= 1;
679
680   GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
681                            private->xwindow, private->ref_count,
682                            (private->ref_count == 0 ? " freeing" : "")));
683
684   if (private->ref_count == 0)
685     {
686       if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
687         gdk_pixmap_unref (private->bg_pixmap);
688
689       if (!private->destroyed)
690         {
691           if (private->window_type == GDK_WINDOW_FOREIGN)
692             gdk_xid_table_remove (private->xwindow);
693           else
694             g_warning ("losing last reference to undestroyed window");
695         }
696       g_dataset_destroy (window);
697       g_free (window);
698     }
699 }
700
701 void
702 gdk_window_show (GdkWindow *window)
703 {
704   GdkWindowPrivate *private;
705
706   g_return_if_fail (window != NULL);
707
708   private = (GdkWindowPrivate*) window;
709   if (!private->destroyed)
710     {
711       GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
712
713       private->mapped = TRUE;
714       if (private->window_type == GDK_WINDOW_TEMP)
715         {
716           ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
717           SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
718                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
719 #if 0
720           ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
721 #endif
722         }
723       else
724         {
725           ShowWindow (private->xwindow, SW_SHOWNORMAL);
726           ShowWindow (private->xwindow, SW_RESTORE);
727           SetForegroundWindow (private->xwindow);
728 #if 0
729           ShowOwnedPopups (private->xwindow, TRUE);
730 #endif
731         }
732     }
733 }
734
735 void
736 gdk_window_hide (GdkWindow *window)
737 {
738   GdkWindowPrivate *private;
739
740   g_return_if_fail (window != NULL);
741
742   private = (GdkWindowPrivate*) window;
743   if (!private->destroyed)
744     {
745       GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
746
747       private->mapped = FALSE;
748       if (private->window_type == GDK_WINDOW_TOPLEVEL)
749         ShowOwnedPopups (private->xwindow, FALSE);
750 #if 1
751       ShowWindow (private->xwindow, SW_HIDE);
752 #elif 0
753       ShowWindow (private->xwindow, SW_MINIMIZE);
754 #else
755       CloseWindow (private->xwindow);
756 #endif
757     }
758 }
759
760 void
761 gdk_window_withdraw (GdkWindow *window)
762 {
763   GdkWindowPrivate *private;
764
765   g_return_if_fail (window != NULL);
766
767   private = (GdkWindowPrivate*) window;
768   if (!private->destroyed)
769     {
770       GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
771
772       gdk_window_hide (window); /* XXX */
773     }
774 }
775
776 void
777 gdk_window_move (GdkWindow *window,
778                  gint       x,
779                  gint       y)
780 {
781   GdkWindowPrivate *private;
782
783   g_return_if_fail (window != NULL);
784
785   private = (GdkWindowPrivate*) window;
786   if (!private->destroyed)
787     {
788       RECT rect;
789
790       GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
791                                private->xwindow, x, y));
792
793       GetClientRect (private->xwindow, &rect);
794
795       if (private->window_type != GDK_WINDOW_CHILD)
796         {
797           POINT ptTL, ptBR;
798           DWORD dwStyle;
799           DWORD dwExStyle;
800
801           ptTL.x = 0;
802           ptTL.y = 0; 
803           ClientToScreen (private->xwindow, &ptTL);
804           rect.left = x;
805           rect.top = y;
806
807           ptBR.x = rect.right;
808           ptBR.y = rect.bottom;
809           ClientToScreen (private->xwindow, &ptBR);
810           rect.right = x + ptBR.x - ptTL.x;
811           rect.bottom = y + ptBR.y - ptTL.y;
812
813           dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
814           dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
815           if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
816             g_warning ("gdk_window_move: AdjustWindowRectEx failed");
817
818           x = rect.left;
819           y = rect.top;
820         }
821       else
822         {
823           private->x = x;
824           private->y = y;
825         }
826       GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
827                                private->xwindow,
828                                rect.right - rect.left, rect.bottom - rect.top,
829                                x, y));
830       if (!MoveWindow (private->xwindow,
831                        x, y, rect.right - rect.left, rect.bottom - rect.top,
832                        TRUE))
833         g_warning ("gdk_window_move: MoveWindow failed");
834     }
835 }
836
837 void
838 gdk_window_resize (GdkWindow *window,
839                    gint       width,
840                    gint       height)
841 {
842   GdkWindowPrivate *private;
843
844   g_return_if_fail (window != NULL);
845
846   if ((gint16) width < 1)
847     width = 1;
848   if ((gint16) height < 1)
849     height = 1;
850
851   private = (GdkWindowPrivate*) window;
852
853   if (!private->destroyed &&
854       ((private->resize_count > 0) ||
855        (private->width != (guint16) width) ||
856        (private->height != (guint16) height)))
857     {
858       int x, y;
859
860       GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
861                                private->xwindow, width, height));
862       
863       if (private->window_type != GDK_WINDOW_CHILD)
864         {
865           POINT pt;
866           RECT rect;
867           DWORD dwStyle;
868           DWORD dwExStyle;
869
870           pt.x = 0;
871           pt.y = 0; 
872           ClientToScreen (private->xwindow, &pt);
873           rect.left = pt.x;
874           rect.top = pt.y;
875           rect.right = pt.x + width;
876           rect.bottom = pt.y + height;
877
878           dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
879           dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
880           if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
881             g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
882
883           x = rect.left;
884           y = rect.top;
885           width = rect.right - rect.left;
886           height = rect.bottom - rect.top;
887         }
888       else
889         {
890           x = private->x;
891           y = private->y;
892           private->width = width;
893           private->height = height;
894         }
895
896       private->resize_count += 1;
897
898       GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
899                                private->xwindow, width, height, x, y));
900       if (!MoveWindow (private->xwindow,
901                        x, y, width, height,
902                        TRUE))
903         g_warning ("gdk_window_resize: MoveWindow failed");
904     }
905 }
906
907 void
908 gdk_window_move_resize (GdkWindow *window,
909                         gint       x,
910                         gint       y,
911                         gint       width,
912                         gint       height)
913 {
914   GdkWindowPrivate *private;
915
916   g_return_if_fail (window != NULL);
917
918   if ((gint16) width < 1)
919     width = 1;
920   if ((gint16) height < 1)
921     height = 1;
922
923   private = (GdkWindowPrivate*) window;
924   if (!private->destroyed)
925     {
926       RECT rect;
927       DWORD dwStyle;
928       DWORD dwExStyle;
929
930       GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
931                                private->xwindow, width, height, x, y));
932       
933       rect.left = x;
934       rect.top = y;
935       rect.right = x + width;
936       rect.bottom = y + height;
937
938       dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
939       dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
940       if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
941         g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
942
943       if (private->window_type == GDK_WINDOW_CHILD)
944         {
945           private->x = x;
946           private->y = y;
947           private->width = width;
948           private->height = height;
949         }
950       GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
951                                private->xwindow,
952                                rect.right - rect.left, rect.bottom - rect.top,
953                                rect.left, rect.top));
954       if (!MoveWindow (private->xwindow,
955                        rect.left, rect.top,
956                        rect.right - rect.left, rect.bottom - rect.top,
957                        TRUE))
958         g_warning ("gdk_window_move_resize: MoveWindow failed");
959
960       if (private->guffaw_gravity)
961         {
962           GList *tmp_list = private->children;
963           while (tmp_list)
964             {
965               GdkWindowPrivate *child_private = tmp_list->data;
966               
967               child_private->x -= x - private->x;
968               child_private->y -= y - private->y;
969               
970               tmp_list = tmp_list->next;
971             }
972         }
973       
974     }
975 }
976
977 void
978 gdk_window_reparent (GdkWindow *window,
979                      GdkWindow *new_parent,
980                      gint       x,
981                      gint       y)
982 {
983   GdkWindowPrivate *window_private;
984   GdkWindowPrivate *parent_private;
985   GdkWindowPrivate *old_parent_private;
986
987   g_return_if_fail (window != NULL);
988
989   if (!new_parent)
990     new_parent = (GdkWindow*) &gdk_root_parent;
991
992   window_private = (GdkWindowPrivate*) window;
993   old_parent_private = (GdkWindowPrivate*)window_private->parent;
994   parent_private = (GdkWindowPrivate*) new_parent;
995
996   if (!window_private->destroyed && !parent_private->destroyed)
997     {
998       GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
999                                window_private->xwindow,
1000                                parent_private->xwindow));
1001       if (!SetParent (window_private->xwindow, parent_private->xwindow))
1002         g_warning ("gdk_window_reparent: SetParent failed");
1003
1004       if (!MoveWindow (window_private->xwindow,
1005                        x, y,
1006                        window_private->width, window_private->height,
1007                        TRUE))
1008         g_warning ("gdk_window_reparent: MoveWindow failed");
1009     }
1010   
1011   window_private->parent = new_parent;
1012
1013   if (old_parent_private)
1014     old_parent_private->children = g_list_remove (old_parent_private->children, window);
1015
1016   if ((old_parent_private &&
1017        (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1018       (!old_parent_private && parent_private->guffaw_gravity))
1019     gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1020   
1021   parent_private->children = g_list_prepend (parent_private->children, window);
1022 }
1023
1024 void
1025 gdk_window_clear (GdkWindow *window)
1026 {
1027   GdkWindowPrivate *private;
1028
1029   g_return_if_fail (window != NULL);
1030
1031   private = (GdkWindowPrivate*) window;
1032
1033   if (!private->destroyed)
1034     {
1035       gdk_window_clear_area (window, 0, 0, private->width, private->height);
1036     }
1037 }
1038
1039
1040 void
1041 gdk_window_clear_area (GdkWindow *window,
1042                        gint       x,
1043                        gint       y,
1044                        gint       width,
1045                        gint       height)
1046 {
1047   GdkWindowPrivate *private;
1048   
1049   g_return_if_fail (window != NULL);
1050   
1051   private = (GdkWindowPrivate*) window;
1052   
1053   if (!private->destroyed)
1054     {
1055       HDC hdc;
1056
1057       if (width == -1)
1058         width = G_MAXSHORT/2;           /* Yeah, right */
1059       if (height == -1)
1060         height = G_MAXSHORT/2;
1061       GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1062                                private->xwindow, width, height, x, y));
1063       hdc = GetDC (private->xwindow);
1064       IntersectClipRect (hdc, x, y, x + width, y + height);
1065       SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1066       ReleaseDC (private->xwindow, hdc);
1067     }
1068 }
1069
1070 void
1071 gdk_window_clear_area_e (GdkWindow *window,
1072                          gint       x,
1073                          gint       y,
1074                          gint       width,
1075                          gint       height)
1076 {
1077   GdkWindowPrivate *private;
1078   
1079   g_return_if_fail (window != NULL);
1080   
1081   private = (GdkWindowPrivate*) window;
1082   
1083   if (!private->destroyed)
1084     {
1085       RECT rect;
1086
1087       GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1088                                private->xwindow, width, height, x, y));
1089
1090       rect.left = x;
1091       rect.right = x + width;
1092       rect.top = y;
1093       rect.bottom = y + height;
1094       if (!InvalidateRect (private->xwindow, &rect, TRUE))
1095         g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1096       UpdateWindow (private->xwindow);
1097     }
1098 }
1099
1100 void
1101 gdk_window_copy_area (GdkWindow    *window,
1102                       GdkGC        *gc,
1103                       gint          x,
1104                       gint          y,
1105                       GdkWindow    *source_window,
1106                       gint          source_x,
1107                       gint          source_y,
1108                       gint          width,
1109                       gint          height)
1110 {
1111   GdkWindowPrivate *src_private;
1112   GdkWindowPrivate *dest_private;
1113   GdkGCPrivate *gc_private;
1114   
1115   g_return_if_fail (window != NULL);
1116   g_return_if_fail (gc != NULL);
1117   
1118   if (source_window == NULL)
1119     source_window = window;
1120   
1121   src_private = (GdkWindowPrivate*) source_window;
1122   dest_private = (GdkWindowPrivate*) window;
1123   gc_private = (GdkGCPrivate*) gc;
1124   
1125   if (!src_private->destroyed && !dest_private->destroyed)
1126     {
1127       HDC hdcDest, hdcSrc;
1128
1129       if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1130         g_warning ("gdk_window_copy_area: GetDC failed");
1131
1132       if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1133         g_warning ("gdk_window_copy_area: GetDC failed");
1134
1135       if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1136         g_warning ("gdk_window_copy_area: BitBlt failed");
1137
1138       ReleaseDC (dest_private->xwindow, hdcDest);
1139       ReleaseDC (src_private->xwindow, hdcSrc);
1140     }
1141 }
1142
1143 void
1144 gdk_window_raise (GdkWindow *window)
1145 {
1146   GdkWindowPrivate *private;
1147   
1148   g_return_if_fail (window != NULL);
1149   
1150   private = (GdkWindowPrivate*) window;
1151   
1152   if (!private->destroyed)
1153     {
1154       GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1155
1156       if (!BringWindowToTop (private->xwindow))
1157         g_warning ("gdk_window_raise: BringWindowToTop failed");
1158     }
1159 }
1160
1161 void
1162 gdk_window_lower (GdkWindow *window)
1163 {
1164   GdkWindowPrivate *private;
1165   
1166   g_return_if_fail (window != NULL);
1167   
1168   private = (GdkWindowPrivate*) window;
1169   
1170   if (!private->destroyed)
1171     {
1172       GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1173
1174       if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1175                          SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1176         g_warning ("gdk_window_lower: SetWindowPos failed");
1177     }
1178 }
1179
1180 void
1181 gdk_window_set_user_data (GdkWindow *window,
1182                           gpointer   user_data)
1183 {
1184   g_return_if_fail (window != NULL);
1185   
1186   window->user_data = user_data;
1187 }
1188
1189 void
1190 gdk_window_set_hints (GdkWindow *window,
1191                       gint       x,
1192                       gint       y,
1193                       gint       min_width,
1194                       gint       min_height,
1195                       gint       max_width,
1196                       gint       max_height,
1197                       gint       flags)
1198 {
1199   GdkWindowPrivate *private;
1200   WINDOWPLACEMENT size_hints;
1201   RECT rect;
1202   DWORD dwStyle;
1203   DWORD dwExStyle;
1204   int diff;
1205   
1206   g_return_if_fail (window != NULL);
1207   
1208   private = (GdkWindowPrivate*) window;
1209   if (private->destroyed)
1210     return;
1211   
1212   GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1213                            private->xwindow,
1214                            min_width, min_height, max_width, max_height,
1215                            x, y));
1216
1217   private->hint_flags = flags;
1218   size_hints.length = sizeof (size_hints);
1219
1220   if (flags)
1221     {
1222       if (flags & GDK_HINT_POS)
1223         if (!GetWindowPlacement (private->xwindow, &size_hints))
1224           g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1225         else
1226           {
1227             GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1228                                      " (%d,%d)--(%d,%d)\n",
1229                                      size_hints.rcNormalPosition.left,
1230                                      size_hints.rcNormalPosition.top,
1231                                      size_hints.rcNormalPosition.right,
1232                                      size_hints.rcNormalPosition.bottom));
1233             /* What are the corresponding window coordinates for client
1234              * area coordinates x, y
1235              */
1236             rect.left = x;
1237             rect.top = y;
1238             rect.right = rect.left + 200;       /* dummy */
1239             rect.bottom = rect.top + 200;
1240             dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1241             dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1242             AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1243             size_hints.flags = 0;
1244             size_hints.showCmd = SW_SHOWNA;
1245
1246             /* Set the normal position hint to that location, with unchanged
1247              * width and height.
1248              */
1249             diff = size_hints.rcNormalPosition.left - rect.left;
1250             size_hints.rcNormalPosition.left = rect.left;
1251             size_hints.rcNormalPosition.right -= diff;
1252             diff = size_hints.rcNormalPosition.top - rect.top;
1253             size_hints.rcNormalPosition.top = rect.top;
1254             size_hints.rcNormalPosition.bottom -= diff;
1255             GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1256                                      size_hints.rcNormalPosition.left,
1257                                      size_hints.rcNormalPosition.top,
1258                                      size_hints.rcNormalPosition.right,
1259                                      size_hints.rcNormalPosition.bottom));
1260             if (!SetWindowPlacement (private->xwindow, &size_hints))
1261               g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1262             private->hint_x = rect.left;
1263             private->hint_y = rect.top;
1264           }
1265
1266       if (flags & GDK_HINT_MIN_SIZE)
1267         {
1268           rect.left = 0;
1269           rect.top = 0;
1270           rect.right = min_width;
1271           rect.bottom = min_height;
1272           dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1273           dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1274           AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1275           private->hint_min_width = rect.right - rect.left;
1276           private->hint_min_height = rect.bottom - rect.top;
1277
1278           /* Also chek if he current size of the window is in bounds. */
1279           GetClientRect (private->xwindow, &rect);
1280           if (rect.right < min_width && rect.bottom < min_height)
1281             gdk_window_resize (window, min_width, min_height);
1282           else if (rect.right < min_width)
1283             gdk_window_resize (window, min_width, rect.bottom);
1284           else if (rect.bottom < min_height)
1285             gdk_window_resize (window, rect.right, min_height);
1286         }
1287       if (flags & GDK_HINT_MAX_SIZE)
1288         {
1289           rect.left = 0;
1290           rect.top = 0;
1291           rect.right = max_width;
1292           rect.bottom = max_height;
1293           dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1294           dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1295           AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1296           private->hint_max_width = rect.right - rect.left;
1297           private->hint_max_height = rect.bottom - rect.top;
1298           /* Again, check if the window is too large currently. */
1299           GetClientRect (private->xwindow, &rect);
1300           if (rect.right > max_width && rect.bottom > max_height)
1301             gdk_window_resize (window, max_width, max_height);
1302           else if (rect.right > max_width)
1303             gdk_window_resize (window, max_width, rect.bottom);
1304           else if (rect.bottom > max_height)
1305             gdk_window_resize (window, rect.right, max_height);
1306         }
1307     }
1308 }
1309
1310 void 
1311 gdk_window_set_geometry_hints (GdkWindow      *window,
1312                                GdkGeometry    *geometry,
1313                                GdkWindowHints  geom_mask)
1314 {
1315   GdkWindowPrivate *private;
1316   WINDOWPLACEMENT size_hints;
1317   RECT rect;
1318   DWORD dwStyle;
1319   DWORD dwExStyle;
1320   int diff;
1321   
1322   g_return_if_fail (window != NULL);
1323   
1324   private = (GdkWindowPrivate*) window;
1325   if (private->destroyed)
1326     return;
1327   
1328   size_hints.length = sizeof (size_hints);
1329
1330   private->hint_flags = geom_mask;
1331
1332   if (geom_mask & GDK_HINT_POS)
1333     ; /* XXX */
1334
1335   if (geom_mask & GDK_HINT_MIN_SIZE)
1336     {
1337       rect.left = 0;
1338       rect.top = 0;
1339       rect.right = geometry->min_width;
1340       rect.bottom = geometry->min_height;
1341       dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1342       dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1343       AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1344       private->hint_min_width = rect.right - rect.left;
1345       private->hint_min_height = rect.bottom - rect.top;
1346
1347       /* Also check if he current size of the window is in bounds */
1348       GetClientRect (private->xwindow, &rect);
1349       if (rect.right < geometry->min_width
1350           && rect.bottom < geometry->min_height)
1351         gdk_window_resize (window, geometry->min_width, geometry->min_height);
1352       else if (rect.right < geometry->min_width)
1353         gdk_window_resize (window, geometry->min_width, rect.bottom);
1354       else if (rect.bottom < geometry->min_height)
1355         gdk_window_resize (window, rect.right, geometry->min_height);
1356     }
1357   
1358   if (geom_mask & GDK_HINT_MAX_SIZE)
1359     {
1360       rect.left = 0;
1361       rect.top = 0;
1362       rect.right = geometry->max_width;
1363       rect.bottom = geometry->max_height;
1364       dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1365       dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1366       AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1367       private->hint_max_width = rect.right - rect.left;
1368       private->hint_max_height = rect.bottom - rect.top;
1369
1370       /* Again, check if the window is too large currently. */
1371       GetClientRect (private->xwindow, &rect);
1372       if (rect.right > geometry->max_width
1373           && rect.bottom > geometry->max_height)
1374         gdk_window_resize (window, geometry->max_width, geometry->max_height);
1375       else if (rect.right > geometry->max_width)
1376         gdk_window_resize (window, geometry->max_width, rect.bottom);
1377       else if (rect.bottom > geometry->max_height)
1378         gdk_window_resize (window, rect.right, geometry->max_height);
1379     }
1380   
1381   /* I don't know what to do when called with zero base_width and height. */
1382   if (geom_mask & GDK_HINT_BASE_SIZE
1383       && geometry->base_width > 0
1384       && geometry->base_height > 0)
1385     if (!GetWindowPlacement (private->xwindow, &size_hints))
1386       g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1387     else
1388       {
1389         GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1390                                  " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1391                                  size_hints.rcNormalPosition.left,
1392                                  size_hints.rcNormalPosition.top,
1393                                  size_hints.rcNormalPosition.right,
1394                                  size_hints.rcNormalPosition.bottom));
1395         size_hints.rcNormalPosition.right =
1396           size_hints.rcNormalPosition.left + geometry->base_width;
1397         size_hints.rcNormalPosition.bottom =
1398           size_hints.rcNormalPosition.top + geometry->base_height;
1399         GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1400                                  size_hints.rcNormalPosition.left,
1401                                  size_hints.rcNormalPosition.top,
1402                                  size_hints.rcNormalPosition.right,
1403                                  size_hints.rcNormalPosition.bottom));
1404         if (!SetWindowPlacement (private->xwindow, &size_hints))
1405           g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1406       }
1407   
1408   if (geom_mask & GDK_HINT_RESIZE_INC)
1409     {
1410       /* XXX */
1411     }
1412   
1413   if (geom_mask & GDK_HINT_ASPECT)
1414     {
1415       /* XXX */
1416     }
1417 }
1418
1419 void
1420 gdk_window_set_title (GdkWindow   *window,
1421                       const gchar *title)
1422 {
1423   GdkWindowPrivate *private;
1424   
1425   g_return_if_fail (window != NULL);
1426   
1427   private = (GdkWindowPrivate*) window;
1428   GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1429                            private->xwindow, title));
1430   if (!private->destroyed)
1431     {
1432       if (!SetWindowText (private->xwindow, title))
1433         g_warning ("gdk_window_set_title: SetWindowText failed");
1434     }
1435 }
1436
1437 void          
1438 gdk_window_set_role (GdkWindow   *window,
1439                      const gchar *role)
1440 {
1441   GdkWindowPrivate *private;
1442   
1443   g_return_if_fail (window != NULL);
1444   
1445   private = (GdkWindowPrivate*) window;
1446
1447   GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1448                            private->xwindow, (role ? role : "NULL")));
1449   /* XXX */
1450 }
1451
1452 void          
1453 gdk_window_set_transient_for (GdkWindow *window, 
1454                               GdkWindow *parent)
1455 {
1456   GdkWindowPrivate *private;
1457   GdkWindowPrivate *parent_private;
1458   
1459   g_return_if_fail (window != NULL);
1460   
1461   private = (GdkWindowPrivate*) window;
1462   parent_private = (GdkWindowPrivate*) parent;
1463
1464   GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1465                            private->xwindow, parent_private->xwindow));
1466   /* XXX */
1467 }
1468
1469 void
1470 gdk_window_set_background (GdkWindow *window,
1471                            GdkColor  *color)
1472 {
1473   GdkWindowPrivate *private;
1474   
1475   g_return_if_fail (window != NULL);
1476   
1477   private = (GdkWindowPrivate*) window;
1478   if (!private->destroyed)
1479     {
1480       GdkColormapPrivate *colormap_private =
1481         (GdkColormapPrivate *) private->colormap;
1482
1483       GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1484                                private->xwindow, 
1485                                gdk_color_to_string (color)));
1486
1487       if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1488         {
1489           if (private->bg_pixmap != NULL)
1490             {
1491               gdk_pixmap_unref (private->bg_pixmap);
1492               private->bg_pixmap = NULL;
1493             }
1494           private->bg_type = GDK_WIN32_BG_NORMAL;
1495         }
1496       private->bg_type = GDK_WIN32_BG_PIXEL;
1497       private->bg_pixel = *color;
1498     }
1499 }
1500
1501 void
1502 gdk_window_set_back_pixmap (GdkWindow *window,
1503                             GdkPixmap *pixmap,
1504                             gint       parent_relative)
1505 {
1506   GdkWindowPrivate *window_private;
1507
1508   g_return_if_fail (window != NULL);
1509   
1510   window_private = (GdkWindowPrivate*) window;
1511
1512   if (!window_private->destroyed)
1513     {
1514       GdkColormapPrivate *colormap_private =
1515         (GdkColormapPrivate *) window_private->colormap;
1516       if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1517         {
1518           if (window_private->bg_pixmap != NULL)
1519             {
1520               gdk_pixmap_unref (window_private->bg_pixmap);
1521               window_private->bg_pixmap = NULL;
1522             }
1523           window_private->bg_type = GDK_WIN32_BG_NORMAL;
1524         }
1525       if (parent_relative)
1526         {
1527           window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1528         }
1529       else if (!pixmap)
1530         {
1531           
1532         }
1533       else
1534         {
1535           /* We must cache the pixmap in the WindowPrivate and
1536            * paint it each time we get WM_ERASEBKGND
1537            */
1538           window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1539           window_private->bg_pixmap = pixmap;
1540           gdk_pixmap_ref (pixmap);
1541         }
1542     }
1543 }
1544
1545 void
1546 gdk_window_set_cursor (GdkWindow *window,
1547                        GdkCursor *cursor)
1548 {
1549   GdkWindowPrivate *window_private;
1550   GdkCursorPrivate *cursor_private;
1551   HCURSOR xcursor;
1552   
1553   g_return_if_fail (window != NULL);
1554   
1555   window_private = (GdkWindowPrivate*) window;
1556   cursor_private = (GdkCursorPrivate*) cursor;
1557   
1558   if (!window_private->destroyed)
1559     {
1560       if (!cursor)
1561         xcursor = LoadCursor (NULL, IDC_ARROW);
1562       else
1563         xcursor = cursor_private->xcursor;
1564
1565       GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1566                                window_private->xwindow, xcursor));
1567       window_private->xcursor = xcursor;
1568       SetCursor (xcursor);
1569     }
1570 }
1571
1572 void
1573 gdk_window_set_colormap (GdkWindow   *window,
1574                          GdkColormap *colormap)
1575 {
1576   GdkWindowPrivate *window_private;
1577   GdkColormapPrivate *colormap_private;
1578   
1579   g_return_if_fail (window != NULL);
1580   g_return_if_fail (colormap != NULL);
1581   
1582   window_private = (GdkWindowPrivate*) window;
1583   colormap_private = (GdkColormapPrivate*) colormap;
1584   
1585   if (!window_private->destroyed)
1586     {
1587       /* XXX ??? */
1588       GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1589                                window_private->xwindow,
1590                                colormap_private->xcolormap));
1591       if (window_private->colormap)
1592         gdk_colormap_unref (window_private->colormap);
1593       window_private->colormap = colormap;
1594       gdk_colormap_ref (window_private->colormap);
1595       
1596       if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1597         gdk_window_add_colormap_windows (window);
1598     }
1599 }
1600
1601 void
1602 gdk_window_get_user_data (GdkWindow *window,
1603                           gpointer  *data)
1604 {
1605   g_return_if_fail (window != NULL);
1606   
1607   *data = window->user_data;
1608 }
1609
1610 void
1611 gdk_window_get_geometry (GdkWindow *window,
1612                          gint      *x,
1613                          gint      *y,
1614                          gint      *width,
1615                          gint      *height,
1616                          gint      *depth)
1617 {
1618   GdkWindowPrivate *window_private;
1619   
1620   if (!window)
1621     window = (GdkWindow*) &gdk_root_parent;
1622   
1623   window_private = (GdkWindowPrivate*) window;
1624   
1625   if (!window_private->destroyed)
1626     {
1627       RECT rect;
1628
1629       if (!GetClientRect (window_private->xwindow, &rect))
1630         g_warning ("gdk_window_get_geometry: GetClientRect failed");
1631
1632       if (x)
1633         *x = rect.left;
1634       if (y)
1635         *y = rect.top;
1636       if (width)
1637         *width = rect.right - rect.left;
1638       if (height)
1639         *height = rect.bottom - rect.top;
1640       if (depth)
1641         *depth = gdk_window_get_visual (window)->depth;
1642     }
1643 }
1644
1645 void
1646 gdk_window_get_position (GdkWindow *window,
1647                          gint      *x,
1648                          gint      *y)
1649 {
1650   GdkWindowPrivate *window_private;
1651   
1652   g_return_if_fail (window != NULL);
1653   
1654   window_private = (GdkWindowPrivate*) window;
1655   
1656   if (x)
1657     *x = window_private->x;
1658   if (y)
1659     *y = window_private->y;
1660 }
1661
1662 void
1663 gdk_window_get_size (GdkWindow *window,
1664                      gint       *width,
1665                      gint       *height)
1666 {
1667   GdkWindowPrivate *window_private;
1668   
1669   g_return_if_fail (window != NULL);
1670   
1671   window_private = (GdkWindowPrivate*) window;
1672   
1673   if (width)
1674     *width = window_private->width;
1675   if (height)
1676     *height = window_private->height;
1677 }
1678
1679 GdkVisual*
1680 gdk_window_get_visual (GdkWindow *window)
1681 {
1682   GdkWindowPrivate *window_private;
1683    
1684   g_return_val_if_fail (window != NULL, NULL);
1685
1686   window_private = (GdkWindowPrivate*) window;
1687   /* Huh? ->parent is never set for a pixmap. We should just return
1688    * null immeditately. Well, do it then!
1689    */
1690   if (window_private->window_type == GDK_WINDOW_PIXMAP)
1691     return NULL;
1692   
1693   if (!window_private->destroyed)
1694     {
1695        if (window_private->colormap == NULL)
1696          return gdk_visual_get_system (); /* XXX ??? */
1697        else
1698          return ((GdkColormapPrivate *)window_private->colormap)->visual;
1699     }
1700   
1701   return NULL;
1702 }
1703
1704 GdkColormap*
1705 gdk_window_get_colormap (GdkWindow *window)
1706 {
1707   GdkWindowPrivate *window_private;
1708   
1709   g_return_val_if_fail (window != NULL, NULL);
1710   window_private = (GdkWindowPrivate*) window;
1711
1712   g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1713   if (!window_private->destroyed)
1714     {
1715       if (window_private->colormap == NULL)
1716         return gdk_colormap_get_system (); /* XXX ??? */
1717       else
1718         return window_private->colormap;
1719     }
1720   
1721   return NULL;
1722 }
1723
1724 GdkWindowType
1725 gdk_window_get_type (GdkWindow *window)
1726 {
1727   GdkWindowPrivate *window_private;
1728
1729   g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1730
1731   window_private = (GdkWindowPrivate*) window;
1732   return window_private->window_type;
1733 }
1734
1735 gint
1736 gdk_window_get_origin (GdkWindow *window,
1737                        gint      *x,
1738                        gint      *y)
1739 {
1740   GdkWindowPrivate *private;
1741   gint return_val;
1742   gint tx = 0;
1743   gint ty = 0;
1744
1745   g_return_val_if_fail (window != NULL, 0);
1746
1747   private = (GdkWindowPrivate*) window;
1748
1749   if (!private->destroyed)
1750     {
1751       POINT pt;
1752
1753       pt.x = 0;
1754       pt.y = 0;
1755       ClientToScreen (private->xwindow, &pt);
1756       tx = pt.x;
1757       ty = pt.y;
1758       return_val = 1;
1759     }
1760   else
1761     return_val = 0;
1762   
1763   if (x)
1764     *x = tx;
1765   if (y)
1766     *y = ty;
1767
1768   GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1769                            private->xwindow, tx, ty));
1770   return return_val;
1771 }
1772
1773 gboolean
1774 gdk_window_get_deskrelative_origin (GdkWindow *window,
1775                                     gint      *x,
1776                                     gint      *y)
1777 {
1778   return gdk_window_get_origin (window, x, y);
1779 }
1780
1781 void
1782 gdk_window_get_root_origin (GdkWindow *window,
1783                             gint      *x,
1784                             gint      *y)
1785 {
1786   GdkWindowPrivate *private;
1787   POINT pt;
1788
1789   g_return_if_fail (window != NULL);
1790
1791   private = (GdkWindowPrivate*) window;
1792   if (x)
1793     *x = 0;
1794   if (y)
1795     *y = 0;
1796   if (private->destroyed)
1797     return;
1798       
1799   while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1800     private = (GdkWindowPrivate*) private->parent;
1801   if (private->destroyed)
1802     return;
1803
1804   pt.x = 0;
1805   pt.y = 0;
1806   ClientToScreen (private->xwindow, &pt);
1807   if (x)
1808     *x = pt.x;
1809   if (y)
1810     *y = pt.y;
1811
1812   GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1813                            ((GdkWindowPrivate *) window)->xwindow,
1814                            private->xwindow, pt.x, pt.y));
1815 }
1816
1817 GdkWindow*
1818 gdk_window_get_pointer (GdkWindow       *window,
1819                         gint            *x,
1820                         gint            *y,
1821                         GdkModifierType *mask)
1822 {
1823   GdkWindowPrivate *private;
1824   GdkWindow *return_val;
1825   POINT pointc, point;
1826   HWND hwnd, hwndc;
1827
1828   if (!window)
1829     window = (GdkWindow*) &gdk_root_parent;
1830
1831   private = (GdkWindowPrivate*) window;
1832
1833   return_val = NULL;
1834   GetCursorPos (&pointc);
1835   point = pointc;
1836   ScreenToClient (private->xwindow, &point);
1837
1838   if (x)
1839     *x = point.x;
1840   if (y)
1841     *y = point.y;
1842
1843   hwnd = WindowFromPoint (point);
1844   point = pointc;
1845   ScreenToClient (hwnd, &point);
1846   
1847   do {
1848     hwndc = ChildWindowFromPoint (hwnd, point);
1849     ClientToScreen (hwnd, &point);
1850     ScreenToClient (hwndc, &point);
1851   } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1852
1853   return_val = gdk_window_lookup (hwnd);
1854
1855   if (mask)
1856     {
1857       BYTE kbd[256];
1858
1859       GetKeyboardState (kbd);
1860       *mask = 0;
1861       if (kbd[VK_SHIFT] & 0x80)
1862         *mask |= GDK_SHIFT_MASK;
1863       if (kbd[VK_CAPITAL] & 0x80)
1864         *mask |= GDK_LOCK_MASK;
1865       if (kbd[VK_CONTROL] & 0x80)
1866         *mask |= GDK_CONTROL_MASK;
1867       if (kbd[VK_MENU] & 0x80)
1868         *mask |= GDK_MOD1_MASK;
1869       if (kbd[VK_LBUTTON] & 0x80)
1870         *mask |= GDK_BUTTON1_MASK;
1871       if (kbd[VK_MBUTTON] & 0x80)
1872         *mask |= GDK_BUTTON2_MASK;
1873       if (kbd[VK_RBUTTON] & 0x80)
1874         *mask |= GDK_BUTTON3_MASK;
1875     }
1876   
1877   return return_val;
1878 }
1879
1880 GdkWindow*
1881 gdk_window_at_pointer (gint *win_x,
1882                        gint *win_y)
1883 {
1884   GdkWindowPrivate *private;
1885   GdkWindow *window;
1886   POINT point, pointc;
1887   HWND hwnd, hwndc;
1888   RECT rect;
1889
1890   private = &gdk_root_parent;
1891
1892   GetCursorPos (&pointc);
1893   point = pointc;
1894   hwnd = WindowFromPoint (point);
1895
1896   if (hwnd == NULL)
1897     {
1898       window = (GdkWindow *) &gdk_root_parent;
1899       if (win_x)
1900         *win_x = pointc.x;
1901       if (win_y)
1902         *win_y = pointc.y;
1903       return window;
1904     }
1905       
1906   ScreenToClient (hwnd, &point);
1907
1908   do {
1909     hwndc = ChildWindowFromPoint (hwnd, point);
1910     ClientToScreen (hwnd, &point);
1911     ScreenToClient (hwndc, &point);
1912   } while (hwndc != hwnd && (hwnd = hwndc, 1));
1913
1914   window = gdk_window_lookup (hwnd);
1915
1916   if (window && (win_x || win_y))
1917     {
1918       GetClientRect (hwnd, &rect);
1919       if (win_x)
1920         *win_x = point.x - rect.left;
1921       if (win_y)
1922         *win_y = point.y - rect.top;
1923     }
1924
1925   GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1926                            point.x, point.y, hwnd,
1927                            (window == NULL ? " NULL" : "")));
1928
1929   return window;
1930 }
1931
1932 GdkWindow*
1933 gdk_window_get_parent (GdkWindow *window)
1934 {
1935   g_return_val_if_fail (window != NULL, NULL);
1936
1937   return ((GdkWindowPrivate*) window)->parent;
1938 }
1939
1940 GdkWindow*
1941 gdk_window_get_toplevel (GdkWindow *window)
1942 {
1943   GdkWindowPrivate *private;
1944
1945   g_return_val_if_fail (window != NULL, NULL);
1946
1947   private = (GdkWindowPrivate*) window;
1948
1949   while (private->window_type == GDK_WINDOW_CHILD)
1950     {
1951       window = ((GdkWindowPrivate*) window)->parent;
1952       private = (GdkWindowPrivate*) window;
1953     }
1954
1955   return window;
1956 }
1957
1958 GList*
1959 gdk_window_get_children (GdkWindow *window)
1960 {
1961   GdkWindowPrivate *private;
1962   GList *children;
1963
1964   g_return_val_if_fail (window != NULL, NULL);
1965
1966   private = (GdkWindowPrivate*) window;
1967   if (private->destroyed)
1968     return NULL;
1969
1970   /* XXX ??? */
1971   g_warning ("gdk_window_get_children ???");
1972   children = NULL;
1973
1974   return children;
1975 }
1976
1977 GdkEventMask  
1978 gdk_window_get_events (GdkWindow *window)
1979 {
1980   GdkWindowPrivate *private;
1981
1982   g_return_val_if_fail (window != NULL, 0);
1983
1984   private = (GdkWindowPrivate*) window;
1985   if (private->destroyed)
1986     return 0;
1987
1988   return private->event_mask;
1989 }
1990
1991 void          
1992 gdk_window_set_events (GdkWindow   *window,
1993                        GdkEventMask event_mask)
1994 {
1995   GdkWindowPrivate *private;
1996
1997   g_return_if_fail (window != NULL);
1998
1999   private = (GdkWindowPrivate*) window;
2000   if (private->destroyed)
2001     return;
2002
2003   private->event_mask = event_mask;
2004 }
2005
2006 void
2007 gdk_window_add_colormap_windows (GdkWindow *window)
2008 {
2009   g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2010 }
2011
2012 /*
2013  * This needs the X11 shape extension.
2014  * If not available, shaped windows will look
2015  * ugly, but programs still work.    Stefan Wille
2016  */
2017 void
2018 gdk_window_shape_combine_mask (GdkWindow *window,
2019                                GdkBitmap *mask,
2020                                gint x, gint y)
2021 {
2022   GdkWindowPrivate *window_private;
2023
2024   g_return_if_fail (window != NULL);
2025
2026   window_private = (GdkWindowPrivate*) window;
2027   
2028   if (!mask)
2029     {
2030       GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2031                                window_private->xwindow));
2032       SetWindowRgn (window_private->xwindow, NULL, TRUE);
2033     }
2034   else
2035     {
2036       GdkPixmapPrivate *pixmap_private;
2037       HRGN hrgn;
2038       DWORD dwStyle;
2039       DWORD dwExStyle;
2040       RECT rect;
2041
2042       /* Convert mask bitmap to region */
2043       pixmap_private = (GdkPixmapPrivate*) mask;
2044       hrgn = BitmapToRegion (pixmap_private->xwindow);
2045
2046       GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2047                                window_private->xwindow,
2048                                pixmap_private->xwindow));
2049
2050       /* SetWindowRgn wants window (not client) coordinates */ 
2051       dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2052       dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2053       GetClientRect (window_private->xwindow, &rect);
2054       AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2055       OffsetRgn (hrgn, -rect.left, -rect.top);
2056
2057       OffsetRgn (hrgn, x, y);
2058
2059       /* If this is a top-level window, add the title bar to the region */
2060       if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2061         {
2062           CombineRgn (hrgn, hrgn,
2063                       CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2064                       RGN_OR);
2065         }
2066       
2067       SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2068     }
2069 }
2070
2071 void          
2072 gdk_window_add_filter (GdkWindow     *window,
2073                        GdkFilterFunc  function,
2074                        gpointer       data)
2075 {
2076   GdkWindowPrivate *private;
2077   GList *tmp_list;
2078   GdkEventFilter *filter;
2079
2080   private = (GdkWindowPrivate*) window;
2081   if (private && private->destroyed)
2082     return;
2083
2084   if (private)
2085     tmp_list = private->filters;
2086   else
2087     tmp_list = gdk_default_filters;
2088
2089   while (tmp_list)
2090     {
2091       filter = (GdkEventFilter *)tmp_list->data;
2092       if ((filter->function == function) && (filter->data == data))
2093         return;
2094       tmp_list = tmp_list->next;
2095     }
2096
2097   filter = g_new (GdkEventFilter, 1);
2098   filter->function = function;
2099   filter->data = data;
2100
2101   if (private)
2102     private->filters = g_list_append (private->filters, filter);
2103   else
2104     gdk_default_filters = g_list_append (gdk_default_filters, filter);
2105 }
2106
2107 void
2108 gdk_window_remove_filter (GdkWindow     *window,
2109                           GdkFilterFunc  function,
2110                           gpointer       data)
2111 {
2112   GdkWindowPrivate *private;
2113   GList *tmp_list, *node;
2114   GdkEventFilter *filter;
2115
2116   private = (GdkWindowPrivate*) window;
2117
2118   if(private)
2119     tmp_list = private->filters;
2120   else
2121     tmp_list = gdk_default_filters;
2122
2123   while (tmp_list)
2124     {
2125       filter = (GdkEventFilter *)tmp_list->data;
2126       node = tmp_list;
2127       tmp_list = tmp_list->next;
2128
2129       if ((filter->function == function) && (filter->data == data))
2130         {
2131           if(private)
2132             private->filters = g_list_remove_link (private->filters, node);
2133           else
2134             gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2135           g_list_free_1 (node);
2136           g_free (filter);
2137           
2138           return;
2139         }
2140     }
2141 }
2142
2143 void
2144 gdk_window_set_override_redirect (GdkWindow *window,
2145                                   gboolean   override_redirect)
2146 {
2147   g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2148 }
2149
2150 void          
2151 gdk_window_set_icon (GdkWindow *window, 
2152                      GdkWindow *icon_window,
2153                      GdkPixmap *pixmap,
2154                      GdkBitmap *mask)
2155 {
2156   g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2157 }
2158
2159 void          
2160 gdk_window_set_icon_name (GdkWindow *window, 
2161                           gchar     *name)
2162 {
2163   GdkWindowPrivate *window_private;
2164
2165   g_return_if_fail (window != NULL);
2166   window_private = (GdkWindowPrivate*) window;
2167   if (window_private->destroyed)
2168     return;
2169
2170   if (!SetWindowText (window_private->xwindow, name))
2171     g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2172 }
2173
2174 void          
2175 gdk_window_set_group (GdkWindow *window, 
2176                       GdkWindow *leader)
2177 {
2178   g_warning ("gdk_window_set_group not implemented"); /* XXX */
2179 }
2180
2181 void
2182 gdk_window_set_decorations (GdkWindow      *window,
2183                             GdkWMDecoration decorations)
2184 {
2185   GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2186   LONG style, exstyle;
2187
2188   style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2189   exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2190
2191   style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2192             |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2193
2194   exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2195
2196   if (decorations & GDK_DECOR_ALL)
2197     style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2198   if (decorations & GDK_DECOR_BORDER)
2199     style |= (WS_BORDER);
2200   if (decorations & GDK_DECOR_RESIZEH)
2201     style |= (WS_THICKFRAME);
2202   if (decorations & GDK_DECOR_TITLE)
2203     style |= (WS_CAPTION);
2204   if (decorations & GDK_DECOR_MENU)
2205     style |= (WS_SYSMENU);
2206   if (decorations & GDK_DECOR_MINIMIZE)
2207     style |= (WS_MINIMIZEBOX);
2208   if (decorations & GDK_DECOR_MAXIMIZE)
2209     style |= (WS_MAXIMIZEBOX);
2210   
2211   SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2212 }
2213
2214 void
2215 gdk_window_set_functions (GdkWindow    *window,
2216                           GdkWMFunction functions)
2217 {
2218   GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2219   LONG style, exstyle;
2220
2221   style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2222   exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2223
2224   style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2225             |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2226             |WS_SYSMENU);
2227
2228   exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2229
2230   if (functions & GDK_FUNC_ALL)
2231     style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2232   if (functions & GDK_FUNC_RESIZE)
2233     style |= (WS_THICKFRAME);
2234   if (functions & GDK_FUNC_MOVE)
2235     style |= (WS_THICKFRAME);
2236   if (functions & GDK_FUNC_MINIMIZE)
2237     style |= (WS_MINIMIZEBOX);
2238   if (functions & GDK_FUNC_MAXIMIZE)
2239     style |= (WS_MAXIMIZEBOX);
2240   
2241   SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2242 }
2243
2244 GList *
2245 gdk_window_get_toplevels (void)
2246 {
2247   GList *new_list = NULL;
2248   GList *tmp_list;
2249
2250   tmp_list = gdk_root_parent.children;
2251   while (tmp_list)
2252     {
2253       new_list = g_list_prepend (new_list, tmp_list->data);
2254       tmp_list = tmp_list->next;
2255     }
2256
2257   return new_list;
2258 }
2259
2260 /* 
2261  * propagate the shapes from all child windows of a GDK window to the parent 
2262  * window. Shamelessly ripped from Enlightenment's code
2263  * 
2264  * - Raster
2265  */
2266
2267 static void
2268 QueryTree (HWND hwnd,
2269            HWND **children,
2270            gint *nchildren)
2271 {
2272   guint i, n;
2273   HWND child;
2274
2275   n = 0;
2276   do {
2277     if (n == 0)
2278       child = GetWindow (hwnd, GW_CHILD);
2279     else
2280       child = GetWindow (child, GW_HWNDNEXT);
2281     if (child != NULL)
2282       n++;
2283   } while (child != NULL);
2284
2285   if (n > 0)
2286     {
2287       *children = g_new (HWND, n);
2288       for (i = 0; i < n; i++)
2289         {
2290           if (i == 0)
2291             child = GetWindow (hwnd, GW_CHILD);
2292           else
2293             child = GetWindow (child, GW_HWNDNEXT);
2294           *children[i] = child;
2295         }
2296     }
2297 }
2298
2299 static void
2300 gdk_propagate_shapes (HANDLE   win,
2301                       gboolean merge)
2302 {
2303    RECT emptyRect;
2304    HRGN region, childRegion;
2305    RECT rect;
2306    HWND *list = NULL;
2307    gint i, num;
2308
2309    SetRectEmpty (&emptyRect);
2310    region = CreateRectRgnIndirect (&emptyRect);
2311    if (merge)
2312      GetWindowRgn (win, region);
2313    
2314    QueryTree (win, &list, &num);
2315    if (list != NULL)
2316      {
2317        WINDOWPLACEMENT placement;
2318
2319        placement.length = sizeof (WINDOWPLACEMENT);
2320        /* go through all child windows and combine regions */
2321        for (i = 0; i < num; i++)
2322          {
2323            GetWindowPlacement (list[i], &placement);
2324            if (placement.showCmd = SW_SHOWNORMAL)
2325              {
2326                childRegion = CreateRectRgnIndirect (&emptyRect);
2327                GetWindowRgn (list[i], childRegion);
2328                CombineRgn (region, region, childRegion, RGN_OR);
2329                DeleteObject (childRegion);
2330              }
2331           }
2332        SetWindowRgn (win, region, TRUE);
2333      }
2334    else
2335      DeleteObject (region);
2336 }
2337
2338 void
2339 gdk_window_set_child_shapes (GdkWindow *window)
2340 {
2341   GdkWindowPrivate *private;
2342    
2343   g_return_if_fail (window != NULL);
2344    
2345   private = (GdkWindowPrivate*) window;
2346   if (private->destroyed)
2347     return;
2348
2349   gdk_propagate_shapes ( private->xwindow, FALSE);
2350 }
2351
2352 void
2353 gdk_window_merge_child_shapes (GdkWindow *window)
2354 {
2355   GdkWindowPrivate *private;
2356   
2357   g_return_if_fail (window != NULL);
2358   
2359   private = (GdkWindowPrivate*) window;
2360   if (private->destroyed)
2361     return;
2362
2363   gdk_propagate_shapes (private->xwindow, TRUE);
2364 }
2365
2366 /*************************************************************
2367  * gdk_window_is_visible:
2368  *     Check if the given window is mapped.
2369  *   arguments:
2370  *     window: 
2371  *   results:
2372  *     is the window mapped
2373  *************************************************************/
2374
2375 gboolean 
2376 gdk_window_is_visible (GdkWindow *window)
2377 {
2378   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2379
2380   g_return_val_if_fail (window != NULL, FALSE);
2381
2382   return private->mapped;
2383 }
2384
2385 /*************************************************************
2386  * gdk_window_is_viewable:
2387  *     Check if the window and all ancestors of the window
2388  *     are mapped. (This is not necessarily "viewable" in
2389  *     the X sense, since we only check as far as we have
2390  *     GDK window parents, not to the root window)
2391  *   arguments:
2392  *     window:
2393  *   results:
2394  *     is the window viewable
2395  *************************************************************/
2396
2397 gboolean 
2398 gdk_window_is_viewable (GdkWindow *window)
2399 {
2400   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2401
2402   g_return_val_if_fail (window != NULL, FALSE);
2403
2404   while (private && 
2405          (private != &gdk_root_parent) &&
2406          (private->window_type != GDK_WINDOW_FOREIGN))
2407     {
2408       if (!private->mapped)
2409         return FALSE;
2410
2411       private = (GdkWindowPrivate *)private->parent;
2412     }
2413
2414   return TRUE;
2415 }
2416
2417 void          
2418 gdk_drawable_set_data (GdkDrawable   *drawable,
2419                        const gchar   *key,
2420                        gpointer       data,
2421                        GDestroyNotify destroy_func)
2422 {
2423   g_dataset_set_data_full (drawable, key, data, destroy_func);
2424 }
2425
2426
2427 /* Support for windows that can be guffaw-scrolled
2428  * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2429  */
2430
2431 static gboolean
2432 gdk_window_gravity_works (void)
2433 {
2434   enum { UNKNOWN, NO, YES };
2435   static gint gravity_works = UNKNOWN;
2436
2437   if (gravity_works == UNKNOWN)
2438     {
2439       GdkWindowAttr attr;
2440       GdkWindow *parent;
2441       GdkWindow *child;
2442       gint y;
2443       
2444       attr.window_type = GDK_WINDOW_TEMP;
2445       attr.wclass = GDK_INPUT_OUTPUT;
2446       attr.x = 0;
2447       attr.y = 0;
2448       attr.width = 100;
2449       attr.height = 100;
2450       attr.event_mask = 0;
2451       
2452       parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2453       
2454       attr.window_type = GDK_WINDOW_CHILD;
2455       child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2456
2457       gdk_window_set_static_win_gravity (child, TRUE);
2458       
2459       gdk_window_resize (parent, 100, 110);
2460       gdk_window_move (parent, 0, -10);
2461       gdk_window_move_resize (parent, 0, 0, 100, 100);
2462       
2463       gdk_window_resize (parent, 100, 110);
2464       gdk_window_move (parent, 0, -10);
2465       gdk_window_move_resize (parent, 0, 0, 100, 100);
2466       
2467       gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2468       
2469       gdk_window_destroy (parent);
2470       gdk_window_destroy (child);
2471   
2472       gravity_works = ((y == -20) ? YES : NO);
2473     }
2474
2475   return (gravity_works == YES);
2476 }
2477
2478 static void
2479 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2480 {
2481   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2482
2483   g_return_if_fail (window != NULL);
2484
2485   GDK_NOTE (MISC,
2486             g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2487 }
2488
2489 static void
2490 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2491 {
2492   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2493
2494   g_return_if_fail (window != NULL);
2495
2496   GDK_NOTE (MISC,
2497             g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2498 }
2499
2500 /*************************************************************
2501  * gdk_window_set_static_gravities:
2502  *     Set the bit gravity of the given window to static,
2503  *     and flag it so all children get static subwindow
2504  *     gravity.
2505  *   arguments:
2506  *     window: window for which to set static gravity
2507  *     use_static: Whether to turn static gravity on or off.
2508  *   results:
2509  *     Does the XServer support static gravity?
2510  *************************************************************/
2511
2512 gboolean 
2513 gdk_window_set_static_gravities (GdkWindow *window,
2514                                  gboolean   use_static)
2515 {
2516   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2517   GList *tmp_list;
2518
2519   g_return_val_if_fail (window != NULL, FALSE);
2520   
2521   if (!use_static == !private->guffaw_gravity)
2522     return TRUE;
2523   
2524   if (use_static && !gdk_window_gravity_works ())
2525     return FALSE;
2526
2527   private->guffaw_gravity = use_static;
2528
2529   gdk_window_set_static_bit_gravity (window, use_static);
2530
2531   tmp_list = private->children;
2532   while (tmp_list)
2533     {
2534       gdk_window_set_static_win_gravity (window, use_static);
2535       
2536       tmp_list = tmp_list->next;
2537     }
2538
2539   return TRUE;
2540 }