]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkwindow-win32.c
7c4c88985a5812e6280b8748e4e504721dade37f
[~andy/gtk] / gdk / win32 / gdkwindow-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-2004 Tor Lillqvist
4  * Copyright (C) 2001-2004 Hans Breuer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /*
23  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
24  * file for a list of people on the GTK+ Team.  See the ChangeLog
25  * files for a list of changes.  These files are distributed with
26  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
27  */
28
29 #include <config.h>
30 #include <stdlib.h>
31
32 #include "gdk.h" /* gdk_rectangle_intersect */
33 #include "gdkevents.h"
34 #include "gdkpixmap.h"
35 #include "gdkwindow.h"
36 #include "gdkdisplay.h"
37 #include "gdkprivate-win32.h"
38 #include "gdkinput-win32.h"
39
40 #if defined __MINGW32__ || (WINVER < 0x0500)
41 typedef struct { 
42   DWORD        bV5Size; 
43   LONG         bV5Width; 
44   LONG         bV5Height; 
45   WORD         bV5Planes; 
46   WORD         bV5BitCount; 
47   DWORD        bV5Compression; 
48   DWORD        bV5SizeImage; 
49   LONG         bV5XPelsPerMeter; 
50   LONG         bV5YPelsPerMeter; 
51   DWORD        bV5ClrUsed; 
52   DWORD        bV5ClrImportant; 
53   DWORD        bV5RedMask; 
54   DWORD        bV5GreenMask; 
55   DWORD        bV5BlueMask; 
56   DWORD        bV5AlphaMask; 
57   DWORD        bV5CSType; 
58   CIEXYZTRIPLE bV5Endpoints; 
59   DWORD        bV5GammaRed; 
60   DWORD        bV5GammaGreen; 
61   DWORD        bV5GammaBlue; 
62   DWORD        bV5Intent; 
63   DWORD        bV5ProfileData; 
64   DWORD        bV5ProfileSize; 
65   DWORD        bV5Reserved; 
66 } BITMAPV5HEADER;
67
68 #endif
69
70 #if 0
71 #include <gdk-pixbuf/gdk-pixbuf.h>
72 #include <stdio.h>
73 #endif
74
75 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
76 static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
77                                                         GdkColormap *cmap);
78 static void         gdk_window_impl_win32_get_size     (GdkDrawable *drawable,
79                                                         gint *width,
80                                                         gint *height);
81 static GdkRegion*   gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
82 static void gdk_window_impl_win32_init       (GdkWindowImplWin32      *window);
83 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
84 static void gdk_window_impl_win32_finalize   (GObject                 *object);
85
86 static gpointer parent_class = NULL;
87
88 GType
89 _gdk_window_impl_win32_get_type (void)
90 {
91   static GType object_type = 0;
92
93   if (!object_type)
94     {
95       static const GTypeInfo object_info =
96       {
97         sizeof (GdkWindowImplWin32Class),
98         (GBaseInitFunc) NULL,
99         (GBaseFinalizeFunc) NULL,
100         (GClassInitFunc) gdk_window_impl_win32_class_init,
101         NULL,           /* class_finalize */
102         NULL,           /* class_data */
103         sizeof (GdkWindowImplWin32),
104         0,              /* n_preallocs */
105         (GInstanceInitFunc) gdk_window_impl_win32_init,
106       };
107       
108       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
109                                             "GdkWindowImplWin32",
110                                             &object_info, 0);
111     }
112   
113   return object_type;
114 }
115
116 GType
117 _gdk_window_impl_get_type (void)
118 {
119   return _gdk_window_impl_win32_get_type ();
120 }
121
122 static void
123 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
124 {
125   impl->width = 1;
126   impl->height = 1;
127
128   impl->hcursor = NULL;
129   impl->hicon_big = NULL;
130   impl->hicon_small = NULL;
131   impl->hint_flags = 0;
132   impl->extension_events_selected = FALSE;
133 }
134
135 static void
136 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
137 {
138   GObjectClass *object_class = G_OBJECT_CLASS (klass);
139   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
140   
141   parent_class = g_type_class_peek_parent (klass);
142
143   object_class->finalize = gdk_window_impl_win32_finalize;
144
145   drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
146   drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
147   drawable_class->get_size = gdk_window_impl_win32_get_size;
148
149   /* Visible and clip regions are the same */
150   drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
151   drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
152 }
153
154 static void
155 gdk_window_impl_win32_finalize (GObject *object)
156 {
157   GdkWindowObject *wrapper;
158   GdkDrawableImplWin32 *draw_impl;
159   GdkWindowImplWin32 *window_impl;
160   
161   g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
162
163   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
164   window_impl = GDK_WINDOW_IMPL_WIN32 (object);
165   
166   wrapper = (GdkWindowObject*) draw_impl->wrapper;
167
168   if (!GDK_WINDOW_DESTROYED (wrapper))
169     {
170       gdk_win32_handle_table_remove (draw_impl->handle);
171     }
172
173   if (window_impl->hcursor != NULL)
174     {
175       if (GetCursor () == window_impl->hcursor)
176         SetCursor (NULL);
177       GDI_CALL (DestroyCursor, (window_impl->hcursor));
178       window_impl->hcursor = NULL;
179     }
180   if (window_impl->hicon_big != NULL)
181     {
182       GDI_CALL (DestroyIcon, (window_impl->hicon_big));
183       window_impl->hicon_big = NULL;
184     }
185   if (window_impl->hicon_small != NULL)
186     {
187       GDI_CALL (DestroyIcon, (window_impl->hicon_small));
188       window_impl->hicon_small = NULL;
189     }
190
191   G_OBJECT_CLASS (parent_class)->finalize (object);
192 }
193
194 void
195 _gdk_win32_adjust_client_rect (GdkWindow *window,
196                                RECT      *rect)
197 {
198   LONG style, exstyle;
199
200   style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
201   exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
202   API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
203 }
204
205 void
206 _gdk_win32_get_adjusted_client_rect (GdkWindow *window,
207                                      RECT      *rect)
208 {
209   GetClientRect (GDK_WINDOW_HWND (window), rect);
210   _gdk_win32_adjust_client_rect (window, rect);
211 }
212
213 static GdkColormap*
214 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
215 {
216   GdkDrawableImplWin32 *drawable_impl;
217   
218   g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
219
220   drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
221
222   if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
223       drawable_impl->colormap == NULL)
224     {
225       drawable_impl->colormap = 
226         gdk_screen_get_system_colormap (gdk_drawable_get_screen (drawable));
227       g_object_ref (drawable_impl->colormap);
228     }
229   
230   return drawable_impl->colormap;
231 }
232
233 static void
234 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
235                                     GdkColormap *cmap)
236 {
237   GdkWindowImplWin32 *impl;
238   GdkDrawableImplWin32 *draw_impl;
239   
240   g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
241
242   impl = GDK_WINDOW_IMPL_WIN32 (drawable);
243   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
244
245   /* chain up */
246   GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
247   
248   if (cmap)
249     {
250       /* XXX */
251       g_print("gdk_window_impl_win32_set_colormap: XXX\n");
252     }
253 }
254
255 static void
256 gdk_window_impl_win32_get_size (GdkDrawable *drawable,
257                                 gint        *width,
258                                 gint        *height)
259 {
260   g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
261
262   if (width)
263     *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
264   if (height)
265     *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
266 }
267
268 static GdkRegion*
269 gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
270 {
271   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
272   GdkRectangle result_rect;
273   HDC hdc;
274
275   result_rect.x = 0;
276   result_rect.y = 0;
277   result_rect.width = impl->width;
278   result_rect.height = impl->height;
279
280   gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
281
282   /* take this win32 specific part into account (smaller when obscured) */
283   hdc = GetDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (impl));
284   if (hdc)
285     {
286       RECT r;
287       if (SIMPLEREGION == GetClipBox (hdc, &r))
288         {
289           GdkRectangle gr;
290
291           gr.x = r.left;
292           gr.y = r.top;
293           gr.width = r.right - r.left;
294           gr.height = r.bottom - r.top;
295
296           gdk_rectangle_intersect (&result_rect, &gr, &result_rect);
297         }
298       ReleaseDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (drawable), hdc);
299     }
300
301   return gdk_region_rectangle (&result_rect);
302 }
303
304 void
305 _gdk_windowing_window_init (void)
306 {
307   GdkWindowObject *private;
308   GdkWindowImplWin32 *impl;
309   GdkDrawableImplWin32 *draw_impl;
310   GdkRectangle rect;
311   gint i;
312
313   g_assert (_gdk_parent_root == NULL);
314   
315   _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
316   private = (GdkWindowObject *)_gdk_parent_root;
317   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
318   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
319   
320   draw_impl->handle = _gdk_root_window;
321   draw_impl->wrapper = GDK_DRAWABLE (private);
322   draw_impl->colormap = gdk_colormap_get_system ();
323   g_object_ref (draw_impl->colormap);
324   
325   private->window_type = GDK_WINDOW_ROOT;
326   private->depth = gdk_visual_get_system ()->depth;
327
328   rect = _gdk_monitors[0];
329   for (i = 1; i < _gdk_num_monitors; i++)
330     gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
331
332   impl->width = rect.width;
333   impl->height = rect.height;
334
335   _gdk_window_init_position (GDK_WINDOW (private));
336
337   gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
338
339   GDK_NOTE (MISC, g_print ("_gdk_parent_root=%p\n", GDK_WINDOW_HWND (_gdk_parent_root)));
340 }
341
342 static const gchar *
343 get_default_title (void)
344 {
345   const char *title;
346   title = g_get_application_name ();
347   if (!title)
348     title = g_get_prgname ();
349
350   return title;
351 }
352
353 /* RegisterGdkClass
354  *   is a wrapper function for RegisterWindowClassEx.
355  *   It creates at least one unique class for every 
356  *   GdkWindowType. If support for single window-specific icons
357  *   is ever needed (e.g Dialog specific), every such window should
358  *   get its own class
359  */
360 static ATOM
361 RegisterGdkClass (GdkWindowType wtype)
362 {
363   static ATOM klassTOPLEVEL = 0;
364   static ATOM klassDIALOG   = 0;
365   static ATOM klassCHILD    = 0;
366   static ATOM klassTEMP     = 0;
367   static HICON hAppIcon = NULL;
368   static WNDCLASSEX wcl; 
369   ATOM klass = 0;
370
371   wcl.cbSize = sizeof (WNDCLASSEX);
372   wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
373                   * on WM_SIZE and WM_MOVE. Flicker, Performance!
374                   */
375   wcl.lpfnWndProc = _gdk_win32_window_procedure;
376   wcl.cbClsExtra = 0;
377   wcl.cbWndExtra = 0;
378   wcl.hInstance = _gdk_app_hmodule;
379   wcl.hIcon = 0;
380   /* initialize once! */
381   if (0 == hAppIcon)
382     {
383       gchar sLoc [MAX_PATH+1];
384
385       if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
386         {
387           hAppIcon = ExtractIcon (_gdk_app_hmodule, sLoc, 0);
388           if (0 == hAppIcon)
389             {
390               if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
391                 hAppIcon = ExtractIcon (_gdk_dll_hinstance, sLoc, 0);
392             }
393         }
394       if (0 == hAppIcon) 
395         hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
396     }
397
398   wcl.lpszMenuName = NULL;
399   wcl.hIconSm = 0;
400
401   /* initialize once per class */
402   /*
403    * HB: Setting the background brush leads to flicker, because we
404    * don't get asked how to clear the background. This is not what
405    * we want, at least not for input_only windows ...
406    */
407 #define ONCE_PER_CLASS() \
408   wcl.hIcon = CopyIcon (hAppIcon); \
409   wcl.hIconSm = CopyIcon (hAppIcon); \
410   wcl.hbrBackground = NULL; \
411   wcl.hCursor = LoadCursor (NULL, IDC_ARROW); 
412   
413   switch (wtype)
414     {
415     case GDK_WINDOW_TOPLEVEL:
416       if (0 == klassTOPLEVEL)
417         {
418           wcl.lpszClassName = "gdkWindowToplevel";
419           
420           ONCE_PER_CLASS();
421           klassTOPLEVEL = RegisterClassEx (&wcl);
422         }
423       klass = klassTOPLEVEL;
424       break;
425       
426     case GDK_WINDOW_CHILD:
427       if (0 == klassCHILD)
428         {
429           wcl.lpszClassName = "gdkWindowChild";
430           
431           wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
432           ONCE_PER_CLASS();
433           klassCHILD = RegisterClassEx (&wcl);
434         }
435       klass = klassCHILD;
436       break;
437       
438     case GDK_WINDOW_DIALOG:
439       if (0 == klassDIALOG)
440         {
441           wcl.lpszClassName = "gdkWindowDialog";
442           wcl.style |= CS_SAVEBITS;
443           ONCE_PER_CLASS();
444           klassDIALOG = RegisterClassEx (&wcl);
445         }
446       klass = klassDIALOG;
447       break;
448       
449     case GDK_WINDOW_TEMP:
450       if (0 == klassTEMP)
451         {
452           wcl.lpszClassName = "gdkWindowTemp";
453           wcl.style |= CS_SAVEBITS;
454           ONCE_PER_CLASS();
455           klassTEMP = RegisterClassEx (&wcl);
456         }
457       klass = klassTEMP;
458       break;
459       
460     default:
461       g_assert_not_reached ();
462       break;
463     }
464   
465   if (klass == 0)
466     {
467       WIN32_API_FAILED ("RegisterClassEx");
468       g_error ("That is a fatal error");
469     }
470   return klass;
471 }
472
473 static GdkWindow*
474 gdk_window_new_internal (GdkWindow     *parent,
475                          GdkWindowAttr *attributes,
476                          gint           attributes_mask,
477                          gboolean       from_set_skip_taskbar_hint)
478 {
479   HANDLE hparent;
480   ATOM klass = 0;
481   DWORD dwStyle = 0, dwExStyle;
482   RECT rect;
483   GdkWindow *window;
484   GdkWindowObject *private;
485   GdkWindowImplWin32 *impl;
486   GdkDrawableImplWin32 *draw_impl;
487   GdkScreen *screen;
488   GdkVisual *visual;
489   const gchar *title;
490   char *mbtitle;
491   gint window_width, window_height;
492   gint offset_x = 0, offset_y = 0;
493
494   g_return_val_if_fail (attributes != NULL, NULL);
495
496   if (!parent)
497     {
498       screen = gdk_screen_get_default ();
499       parent = gdk_screen_get_root_window (screen);
500     }
501   else
502     screen = gdk_drawable_get_screen (parent);
503
504   g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
505   
506   GDK_NOTE (MISC,
507             g_print ("gdk_window_new: %s\n",
508                      (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
509                       (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
510                        (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
511                         (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
512                          "???"))))));
513
514   if (GDK_WINDOW_DESTROYED (parent))
515     return NULL;
516   
517   hparent = GDK_WINDOW_HWND (parent);
518
519   window = g_object_new (GDK_TYPE_WINDOW, NULL);
520   private = (GdkWindowObject *)window;
521   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
522   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
523   draw_impl->wrapper = GDK_DRAWABLE (window);
524
525   /* Windows with a foreign parent are treated as if they are children
526    * of the root window, except for actual creation.
527    */
528   if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
529     parent = _gdk_parent_root;
530   
531   private->parent = (GdkWindowObject *)parent;
532
533   private->accept_focus = TRUE;
534   private->focus_on_map = TRUE;
535
536   if (attributes_mask & GDK_WA_X)
537     private->x = attributes->x;
538   else
539     private->x = 0;
540   
541   if (attributes_mask & GDK_WA_Y)
542     private->y = attributes->y;
543   else if (attributes_mask & GDK_WA_X)
544     private->y = 100;           /* ??? We must put it somewhere... */
545   else
546     private->y = 0;
547   
548   if (attributes_mask & GDK_WA_VISUAL)
549     visual = attributes->visual;
550   else
551     visual = gdk_visual_get_system ();
552
553   impl->width = (attributes->width > 1) ? (attributes->width) : (1);
554   impl->height = (attributes->height > 1) ? (attributes->height) : (1);
555   impl->extension_events_selected = FALSE;
556   if (attributes->wclass == GDK_INPUT_ONLY)
557     {
558       /* Backwards compatiblity - we've always ignored
559        * attributes->window_type for input-only windows
560        * before
561        */
562       if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
563         private->window_type = GDK_WINDOW_TEMP;
564       else
565         private->window_type = GDK_WINDOW_CHILD;
566     }
567   else
568     private->window_type = attributes->window_type;
569
570   if (attributes->wclass == GDK_INPUT_OUTPUT)
571     {
572       dwExStyle = 0;
573
574       private->input_only = FALSE;
575       private->depth = visual->depth;
576       
577       if (attributes_mask & GDK_WA_COLORMAP)
578         {
579           draw_impl->colormap = attributes->colormap;
580           g_object_ref (attributes->colormap);
581         }
582       else
583         {
584           draw_impl->colormap = gdk_screen_get_system_colormap (screen);
585           g_object_ref (draw_impl->colormap);
586         }
587     }
588   else
589     {
590       dwExStyle = WS_EX_TRANSPARENT;
591       private->depth = 0;
592       private->input_only = TRUE;
593       draw_impl->colormap = gdk_screen_get_system_colormap (screen);
594       g_object_ref (draw_impl->colormap);
595       GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap"));
596     }
597
598   switch (private->window_type)
599     {
600     case GDK_WINDOW_TOPLEVEL:
601       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
602       hparent = _gdk_root_window;
603       offset_x = _gdk_offset_x;
604       offset_y = _gdk_offset_y;
605       break;
606
607     case GDK_WINDOW_CHILD:
608       dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
609       break;
610
611     case GDK_WINDOW_DIALOG:
612       dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
613 #if 0
614       dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
615 #endif
616       hparent = _gdk_root_window;
617       offset_x = _gdk_offset_x;
618       offset_y = _gdk_offset_y;
619       break;
620
621     case GDK_WINDOW_TEMP:
622       dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
623       /* a temp window is not necessarily a top level window */
624       dwStyle |= (_gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW);
625       dwExStyle |= WS_EX_TOOLWINDOW;
626       offset_x = _gdk_offset_x;
627       offset_y = _gdk_offset_y;
628       break;
629
630     case GDK_WINDOW_ROOT:
631       g_error ("cannot make windows of type GDK_WINDOW_ROOT");
632       break;
633
634     default:
635       g_assert_not_reached ();
636     }
637
638   _gdk_window_init_position (GDK_WINDOW (private));
639
640   if (private->window_type != GDK_WINDOW_CHILD)
641     {
642       rect.left = rect.top = 0;
643       rect.right = impl->position_info.width;
644       rect.bottom = impl->position_info.height;
645
646       AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
647
648       window_width = rect.right - rect.left;
649       window_height = rect.bottom - rect.top;
650     }
651   else
652     {
653       window_width = impl->position_info.width;
654       window_height = impl->position_info.height;
655     }
656
657   if (impl->position_info.big)
658     private->guffaw_gravity = TRUE;
659
660   if (attributes_mask & GDK_WA_TITLE)
661     title = attributes->title;
662   else
663     title = get_default_title ();
664   if (!title || !*title)
665     title = "GDK client window";
666
667   private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
668       
669   if (private->parent && private->parent->guffaw_gravity)
670     {
671       /* XXX ??? */
672     }
673
674   if (private->parent)
675     private->parent->children = g_list_prepend (private->parent->children, window);
676
677   klass = RegisterGdkClass (private->window_type);
678
679   mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
680   
681   {
682   HWND hwndNew =
683     CreateWindowEx (dwExStyle,
684                     MAKEINTRESOURCE(klass),
685                     mbtitle,
686                     dwStyle,
687                     ((attributes_mask & GDK_WA_X) ?
688                      impl->position_info.x - offset_x: CW_USEDEFAULT),
689                     impl->position_info.y - offset_y, 
690                     window_width, window_height,
691                     hparent,
692                     NULL,
693                     _gdk_app_hmodule,
694                     window);
695   if (GDK_WINDOW_HWND (window) != hwndNew)
696     {
697       g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
698                 GDK_WINDOW_HWND (window),
699                 hwndNew);
700
701       /* HB: IHMO due to a race condition the handle was increased by
702        * one, which causes much trouble. Because I can't find the 
703        * real bug, try to workaround it ...
704        * To reproduce: compile with MSVC 5, DEBUG=1
705        */
706 # if 0
707       gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
708       GDK_WINDOW_HWND (window) = hwndNew;
709       gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
710 # else
711       /* the old behaviour, but with warning */
712       draw_impl->handle = hwndNew;
713 # endif
714
715     }
716   }
717   g_object_ref (window);
718   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
719
720   GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n",
721                            mbtitle,
722                            window_width, window_height,
723                            ((attributes_mask & GDK_WA_X) ?
724                             impl->position_info.x - offset_x: CW_USEDEFAULT),
725                            impl->position_info.y - offset_y, 
726                            hparent,
727                            GDK_WINDOW_HWND (window)));
728
729   g_free (mbtitle);
730
731   if (draw_impl->handle == NULL)
732     {
733       WIN32_API_FAILED ("CreateWindowEx");
734       g_object_unref (window);
735       return NULL;
736     }
737
738   if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
739     gdk_window_set_skip_taskbar_hint (window, TRUE);
740
741   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
742                                   (attributes->cursor) :
743                                   NULL));
744
745   return window;
746 }
747
748 GdkWindow*
749 gdk_window_new (GdkWindow     *parent,
750                 GdkWindowAttr *attributes,
751                 gint           attributes_mask)
752 {
753   return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE);
754 }
755
756 GdkWindow *
757 gdk_window_foreign_new_for_display (GdkDisplay      *display,
758                                     GdkNativeWindow  anid)
759 {
760   GdkWindow *window;
761   GdkWindowObject *private;
762   GdkWindowImplWin32 *impl;
763   GdkDrawableImplWin32 *draw_impl;
764
765   HANDLE parent;
766   RECT rect;
767   POINT point;
768
769   g_return_val_if_fail (display == gdk_display_get_default (), NULL);
770
771   window = g_object_new (GDK_TYPE_WINDOW, NULL);
772   private = (GdkWindowObject *)window;
773   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
774   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
775   draw_impl->wrapper = GDK_DRAWABLE (window);
776   parent = GetParent ((HWND)anid);
777   
778   private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
779   if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
780     private->parent = (GdkWindowObject *)_gdk_parent_root;
781   
782   private->parent->children = g_list_prepend (private->parent->children, window);
783
784   draw_impl->handle = (HWND) anid;
785   GetClientRect ((HWND) anid, &rect);
786   point.x = rect.left;
787   point.y = rect.right;
788   ClientToScreen ((HWND) anid, &point);
789   if (parent != _gdk_root_window)
790     ScreenToClient (parent, &point);
791   private->x = point.x;
792   private->y = point.y;
793   impl->width = rect.right - rect.left;
794   impl->height = rect.bottom - rect.top;
795   private->window_type = GDK_WINDOW_FOREIGN;
796   private->destroyed = FALSE;
797   private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
798   if (IsWindowVisible ((HWND) anid))
799     private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
800   else
801     private->state |= GDK_WINDOW_STATE_WITHDRAWN;
802   if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
803     private->state |= GDK_WINDOW_STATE_ABOVE;
804   else
805     private->state &= (~GDK_WINDOW_STATE_ABOVE);
806   private->state &= (~GDK_WINDOW_STATE_BELOW);
807
808   private->depth = gdk_visual_get_system ()->depth;
809
810   _gdk_window_init_position (GDK_WINDOW (private));
811
812   g_object_ref (window);
813   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
814
815   return window;
816 }
817
818 GdkWindow*
819 gdk_window_lookup (GdkNativeWindow hwnd)
820 {
821   return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd); 
822 }
823
824 void
825 _gdk_windowing_window_destroy (GdkWindow *window,
826                                gboolean   recursing,
827                                gboolean   foreign_destroy)
828 {
829   GdkWindowObject *private = (GdkWindowObject *)window;
830
831   g_return_if_fail (GDK_IS_WINDOW (window));
832   
833   GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
834                            GDK_WINDOW_HWND (window)));
835
836   if (private->extension_events != 0)
837     _gdk_input_window_destroy (window);
838
839
840   if (!recursing && !foreign_destroy)
841     {
842       private->destroyed = TRUE;
843       DestroyWindow (GDK_WINDOW_HWND (window));
844     }
845   gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
846 }
847
848 void
849 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
850 {
851   /* It's somebody else's window, but in our hierarchy,
852    * so reparent it to the root window, and then call
853    * DestroyWindow() on it.
854    */
855   gdk_window_hide (window);
856   gdk_window_reparent (window, NULL, 0, 0);
857   
858   /* Is this too drastic? Many (most?) applications
859    * quit if any window receives WM_QUIT I think.
860    * OTOH, I don't think foreign windows are much
861    * used, so the question is maybe academic.
862    */
863   PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
864 }
865
866 /* This function is called when the window really gone.
867  */
868 void
869 gdk_window_destroy_notify (GdkWindow *window)
870 {
871   g_return_if_fail (window != NULL);
872   g_return_if_fail (GDK_IS_WINDOW (window));
873
874   GDK_NOTE (EVENTS,
875             g_print ("gdk_window_destroy_notify: %p%s\n",
876                      GDK_WINDOW_HWND (window),
877                      (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
878
879   if (!GDK_WINDOW_DESTROYED (window))
880     {
881       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
882         g_warning ("window %p unexpectedly destroyed",
883                    GDK_WINDOW_HWND (window));
884
885       _gdk_window_destroy (window, TRUE);
886     }
887   
888   gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
889   g_object_unref (window);
890 }
891
892 static void
893 get_outer_rect (GdkWindow *window,
894                 gint       width,
895                 gint       height,
896                 RECT      *rect)
897 {
898   LONG style, exstyle;
899       
900   style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
901   exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
902       
903   rect->left = rect->top = 0;
904   rect->right = width;
905   rect->bottom = height;
906       
907   API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
908 }
909
910 static void
911 adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
912                           RECT               *outer_rect,
913                           gint               *x,
914                           gint               *y)
915 {
916   if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
917     {
918       gint orig_x = *x, orig_y = *y;
919
920       switch (impl->hints.win_gravity)
921         {
922         case GDK_GRAVITY_NORTH:
923         case GDK_GRAVITY_CENTER:
924         case GDK_GRAVITY_SOUTH:
925           *x -= (outer_rect->right - outer_rect->left) / 2;
926           *x += impl->width / 2;
927           break;
928               
929         case GDK_GRAVITY_SOUTH_EAST:
930         case GDK_GRAVITY_EAST:
931         case GDK_GRAVITY_NORTH_EAST:
932           *x -= outer_rect->right - outer_rect->left;
933           *x += impl->width;
934           break;
935
936         case GDK_GRAVITY_STATIC:
937           *x += outer_rect->left;
938           break;
939
940         default:
941           break;
942         }
943
944       switch (impl->hints.win_gravity)
945         {
946         case GDK_GRAVITY_WEST:
947         case GDK_GRAVITY_CENTER:
948         case GDK_GRAVITY_EAST:
949           *y -= (outer_rect->bottom - outer_rect->top) / 2;
950           *y += impl->height / 2;
951           break;
952
953         case GDK_GRAVITY_SOUTH_WEST:
954         case GDK_GRAVITY_SOUTH:
955         case GDK_GRAVITY_SOUTH_EAST:
956           *y -= outer_rect->bottom - outer_rect->top;
957           *y += impl->height;
958           break;
959
960         case GDK_GRAVITY_STATIC:
961           *y += outer_rect->top;
962           break;
963
964         default:
965           break;
966         }
967       GDK_NOTE (MISC,
968                 (orig_x != *x || orig_y != *y) ?
969                 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
970                          orig_x, *x, orig_y, *y)
971                   : (void) 0);
972     }
973 }
974
975 static void
976 show_window_internal (GdkWindow *window,
977                       gboolean   raise,
978                       gboolean   deiconify)
979 {
980   GdkWindowObject *private;
981   HWND old_active_window;
982   gboolean focus_on_map = TRUE;
983
984   private = (GdkWindowObject *) window;
985
986   if (private->destroyed)
987     return;
988
989   GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
990                            GDK_WINDOW_HWND (window),
991                            _gdk_win32_window_state_to_string (private->state),
992                            (raise ? " raise" : ""),
993                            (deiconify ? " deiconify" : "")));
994   
995   /* If asked to show (not deiconify) an withdrawn and iconified
996    * window, do that.
997    */
998   if (!deiconify &&
999       !GDK_WINDOW_IS_MAPPED (window) &&
1000       (private->state & GDK_WINDOW_STATE_ICONIFIED))
1001     {   
1002       ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
1003       return;
1004     }
1005   
1006   /* If asked to just show an iconified window, do nothing. */
1007   if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
1008     return;
1009   
1010   /* If asked to deiconify an already noniconified window, do
1011    * nothing. (Especially, don't cause the window to rise and
1012    * activate. There are different calls for that.)
1013    */
1014   if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
1015     return;
1016   
1017   /* If asked to show (but not raise) a window that is already
1018    * visible, do nothing.
1019    */
1020   if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
1021     return;
1022
1023   /* Other cases */
1024   
1025   if (!GDK_WINDOW_IS_MAPPED (window))
1026     {
1027       gdk_synthesize_window_state (window,
1028                                    GDK_WINDOW_STATE_WITHDRAWN,
1029                                    0);
1030       focus_on_map = private->focus_on_map;
1031     }
1032
1033   /* Use SetWindowPos to show transparent windows so automatic redraws
1034    * in other windows can be suppressed.
1035    */
1036   if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1037     {
1038       UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1039       if (!raise)
1040         flags |= SWP_NOZORDER;
1041       if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1042         flags |= SWP_NOACTIVATE;
1043
1044       SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
1045       return;
1046     }
1047
1048   old_active_window = GetActiveWindow ();
1049
1050   if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE))
1051     {
1052       DWORD exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1053
1054       if (private->state & GDK_WINDOW_STATE_BELOW)
1055         exstyle &= (~WS_EX_TOPMOST);
1056       if (private->state & GDK_WINDOW_STATE_ABOVE)
1057         exstyle |= WS_EX_TOPMOST;
1058
1059       if (!SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle))
1060         WIN32_API_FAILED ("SetWindowLong");
1061     }
1062
1063   if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1064     gdk_window_fullscreen (window);
1065   else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1066     ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1067   else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1068     ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1069   else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1070     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1071   else
1072     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1073
1074   if (raise)
1075     {
1076       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1077         SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
1078                     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1079       else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL
1080                || GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1081         SetForegroundWindow (GDK_WINDOW_HWND (window));
1082       else
1083         BringWindowToTop (GDK_WINDOW_HWND (window));
1084     }
1085   else if (old_active_window != GDK_WINDOW_HWND (window))
1086     SetActiveWindow (old_active_window);
1087 }
1088
1089 void
1090 gdk_window_show_unraised (GdkWindow *window)
1091 {
1092   g_return_if_fail (GDK_IS_WINDOW (window));
1093   
1094   show_window_internal (window, FALSE, FALSE);
1095 }
1096
1097 void
1098 gdk_window_show (GdkWindow *window)
1099 {
1100   g_return_if_fail (GDK_IS_WINDOW (window));
1101
1102   show_window_internal (window, TRUE, FALSE);
1103 }
1104
1105 void
1106 gdk_window_hide (GdkWindow *window)
1107 {
1108   GdkWindowObject *private;
1109   
1110   g_return_if_fail (window != NULL);
1111
1112   private = (GdkWindowObject*) window;
1113   if (private->destroyed)
1114     return;
1115
1116   GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
1117                            GDK_WINDOW_HWND (window),
1118                            _gdk_win32_window_state_to_string (private->state)));
1119   
1120   if (GDK_WINDOW_IS_MAPPED (window))
1121     gdk_synthesize_window_state (window,
1122                                  0,
1123                                  GDK_WINDOW_STATE_WITHDRAWN);
1124   
1125   _gdk_window_clear_update_area (window);
1126   
1127   if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1128     ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1129   
1130   if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1131     {
1132       SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1133                     SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1134     }
1135   else
1136     {
1137       ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1138     }
1139 }
1140
1141 void
1142 gdk_window_withdraw (GdkWindow *window)
1143 {
1144   GdkWindowObject *private;
1145   
1146   g_return_if_fail (window != NULL);
1147   
1148   private = (GdkWindowObject*) window;
1149   if (private->destroyed)
1150     return;
1151
1152   GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
1153                            GDK_WINDOW_HWND (window),
1154                            _gdk_win32_window_state_to_string (private->state)));
1155   
1156   gdk_window_hide (window);     /* ??? */
1157 }
1158
1159 void
1160 gdk_window_move (GdkWindow *window,
1161                  gint       x,
1162                  gint       y)
1163 {
1164   GdkWindowObject *private = (GdkWindowObject *)window;
1165   GdkWindowImplWin32 *impl;
1166
1167   g_return_if_fail (window != NULL);
1168   g_return_if_fail (GDK_IS_WINDOW (window));
1169
1170   if (GDK_WINDOW_DESTROYED (window))
1171     return;
1172
1173   GDK_NOTE (MISC, g_print ("gdk_window_move: %p: +%d+%d\n",
1174                            GDK_WINDOW_HWND (window), x, y));
1175       
1176   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1177
1178   if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1179     return;
1180
1181   if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1182     _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
1183   else
1184     {
1185       RECT outer_rect;
1186
1187       get_outer_rect (window, impl->width, impl->height, &outer_rect);
1188       
1189       adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
1190
1191       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1192                                x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1193                                SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1194     }
1195 }
1196
1197 void
1198 gdk_window_resize (GdkWindow *window,
1199                    gint       width,
1200                    gint       height)
1201 {
1202   GdkWindowObject *private = (GdkWindowObject*) window;
1203   GdkWindowImplWin32 *impl;
1204
1205   g_return_if_fail (window != NULL);
1206   g_return_if_fail (GDK_IS_WINDOW (window));
1207
1208   if (GDK_WINDOW_DESTROYED (window))
1209     return;
1210
1211   if (width < 1)
1212     width = 1;
1213   if (height < 1)
1214     height = 1;
1215
1216   GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
1217                            GDK_WINDOW_HWND (window), width, height));
1218
1219   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1220   
1221   if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1222     return;
1223
1224   if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1225     _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1226   else
1227     {
1228       RECT outer_rect;
1229       get_outer_rect (window, width, height, &outer_rect);
1230
1231       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1232                                0, 0,
1233                                outer_rect.right - outer_rect.left,
1234                                outer_rect.bottom - outer_rect.top,
1235                                SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1236       private->resize_count += 1;
1237     }
1238 }
1239
1240 void
1241 gdk_window_move_resize (GdkWindow *window,
1242                         gint       x,
1243                         gint       y,
1244                         gint       width,
1245                         gint       height)
1246 {
1247   GdkWindowObject *private = (GdkWindowObject*) window;
1248   GdkWindowImplWin32 *impl;
1249
1250   g_return_if_fail (window != NULL);
1251   g_return_if_fail (GDK_IS_WINDOW (window));
1252
1253   if (GDK_WINDOW_DESTROYED (window))
1254     return;
1255
1256   if (width < 1)
1257     width = 1;
1258   if (height < 1)
1259     height = 1;
1260   
1261   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1262
1263   if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1264     return;
1265
1266   GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@+%d+%d\n",
1267                            GDK_WINDOW_HWND (window),
1268                            width, height, x, y));
1269   
1270   if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1271     _gdk_window_move_resize_child (window, x, y, width, height);
1272   else
1273     {
1274       RECT outer_rect;
1275
1276       get_outer_rect (window, width, height, &outer_rect);
1277
1278       adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
1279
1280       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1281                                x - _gdk_offset_x, y - _gdk_offset_y,
1282                                outer_rect.right - outer_rect.left,
1283                                outer_rect.bottom - outer_rect.top,
1284                                SWP_NOACTIVATE | SWP_NOZORDER));
1285     }
1286 }
1287
1288 void
1289 gdk_window_reparent (GdkWindow *window,
1290                      GdkWindow *new_parent,
1291                      gint       x,
1292                      gint       y)
1293 {
1294   GdkWindowObject *window_private;
1295   GdkWindowObject *parent_private;
1296   GdkWindowObject *old_parent_private;
1297   GdkWindowImplWin32 *impl;
1298
1299   g_return_if_fail (window != NULL);
1300   g_return_if_fail (GDK_IS_WINDOW (window));
1301   g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1302   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1303
1304   if (GDK_WINDOW_DESTROYED (window) ||
1305       (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1306     {
1307       return;
1308     }
1309
1310   if (!new_parent)
1311     new_parent = _gdk_parent_root;
1312
1313   window_private = (GdkWindowObject*) window;
1314   old_parent_private = (GdkWindowObject *) window_private->parent;
1315   parent_private = (GdkWindowObject*) new_parent;
1316   impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1317
1318   if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1319     {
1320       GDK_NOTE (MISC, g_print ("gdk_window_reparent: %p: %p\n",
1321                                GDK_WINDOW_HWND (window),
1322                                GDK_WINDOW_HWND (new_parent)));
1323
1324       API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1325                             GDK_WINDOW_HWND (new_parent)));
1326
1327       API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1328                              x, y, impl->width, impl->height, TRUE));
1329     }
1330
1331   /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1332    * the root window
1333    */
1334   if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1335     new_parent = _gdk_parent_root;
1336   
1337   window_private->parent = (GdkWindowObject *)new_parent;
1338
1339   if (old_parent_private)
1340     old_parent_private->children =
1341       g_list_remove (old_parent_private->children, window);
1342
1343 #if 0
1344   if ((old_parent_private &&
1345        (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1346       (!old_parent_private && parent_private->guffaw_gravity))
1347     gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1348 #endif
1349
1350   parent_private->children = g_list_prepend (parent_private->children, window);
1351   _gdk_window_init_position (GDK_WINDOW (window_private));
1352 }
1353
1354 void
1355 _gdk_windowing_window_clear_area (GdkWindow *window,
1356                                   gint       x,
1357                                   gint       y,
1358                                   gint       width,
1359                                   gint       height)
1360 {
1361   GdkWindowImplWin32 *impl;
1362
1363   g_return_if_fail (window != NULL);
1364   g_return_if_fail (GDK_IS_WINDOW (window));
1365   
1366   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1367
1368   if (!GDK_WINDOW_DESTROYED (window))
1369     {
1370       HDC hdc;
1371
1372       if (width == 0)
1373         width = impl->width - x;
1374       if (height == 0)
1375         height = impl->height - y;
1376       GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: "
1377                                "%dx%d@+%d+%d\n",
1378                                GDK_WINDOW_HWND (window),
1379                                width, height, x, y));
1380       hdc = GetDC (GDK_WINDOW_HWND (window));
1381       IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
1382       SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1383       GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
1384     }
1385 }
1386
1387 void
1388 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1389                                     gint       x,
1390                                     gint       y,
1391                                     gint       width,
1392                                     gint       height)
1393 {
1394   g_return_if_fail (window != NULL);
1395   g_return_if_fail (GDK_IS_WINDOW (window));
1396   
1397   if (!GDK_WINDOW_DESTROYED (window))
1398     {
1399       RECT rect;
1400
1401       GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: %p: "
1402                                "%dx%d@+%d+%d\n",
1403                                GDK_WINDOW_HWND (window),
1404                                width, height, x, y));
1405
1406       rect.left = x;
1407       rect.right = x + width + 1;
1408       rect.top = y;
1409       rect.bottom = y + height + 1;
1410       GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
1411       UpdateWindow (GDK_WINDOW_HWND (window));
1412     }
1413 }
1414
1415 void
1416 gdk_window_raise (GdkWindow *window)
1417 {
1418   g_return_if_fail (window != NULL);
1419   g_return_if_fail (GDK_IS_WINDOW (window));
1420   
1421   if (!GDK_WINDOW_DESTROYED (window))
1422     {
1423       GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
1424                                GDK_WINDOW_HWND (window)));
1425
1426       API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1427     }
1428 }
1429
1430 void
1431 gdk_window_lower (GdkWindow *window)
1432 {
1433   g_return_if_fail (window != NULL);
1434   g_return_if_fail (GDK_IS_WINDOW (window));
1435   
1436   if (!GDK_WINDOW_DESTROYED (window))
1437     {
1438       GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n",
1439                                GDK_WINDOW_HWND (window)));
1440
1441       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1442                                SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1443     }
1444 }
1445
1446 void
1447 gdk_window_set_hints (GdkWindow *window,
1448                       gint       x,
1449                       gint       y,
1450                       gint       min_width,
1451                       gint       min_height,
1452                       gint       max_width,
1453                       gint       max_height,
1454                       gint       flags)
1455 {
1456   /* Note that this function is obsolete */
1457
1458   GdkWindowImplWin32 *impl;
1459
1460   g_return_if_fail (window != NULL);
1461   g_return_if_fail (GDK_IS_WINDOW (window));
1462   
1463   if (GDK_WINDOW_DESTROYED (window))
1464     return;
1465   
1466   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1467
1468   GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @+%d+%d\n",
1469                            GDK_WINDOW_HWND (window),
1470                            min_width, min_height, max_width, max_height,
1471                            x, y));
1472
1473   if (flags)
1474     {
1475       GdkGeometry geom;
1476       gint geom_mask = 0;
1477
1478       geom.min_width  = min_width;
1479       geom.min_height = min_height;
1480       geom.max_width  = max_width;
1481       geom.max_height = max_height;
1482
1483       if (flags & GDK_HINT_MIN_SIZE)
1484         geom_mask |= GDK_HINT_MIN_SIZE;
1485
1486       if (flags & GDK_HINT_MAX_SIZE)
1487         geom_mask |= GDK_HINT_MAX_SIZE;
1488
1489       gdk_window_set_geometry_hints (window, &geom, geom_mask);
1490     }
1491 }
1492
1493 void 
1494 gdk_window_set_geometry_hints (GdkWindow      *window,
1495                                GdkGeometry    *geometry,
1496                                GdkWindowHints  geom_mask)
1497 {
1498   GdkWindowImplWin32 *impl;
1499 #if 0
1500   WINDOWPLACEMENT size_hints;
1501   RECT rect;
1502   gint new_width = 0, new_height = 0;
1503 #endif
1504
1505   g_return_if_fail (window != NULL);
1506   g_return_if_fail (GDK_IS_WINDOW (window));
1507   
1508   if (GDK_WINDOW_DESTROYED (window))
1509     return;
1510
1511   GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1512                            GDK_WINDOW_HWND (window)));
1513
1514   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1515
1516   impl->hint_flags = geom_mask;
1517   impl->hints = *geometry;
1518
1519   if (geom_mask & GDK_HINT_POS)
1520     ; /* even the X11 mplementation doesn't care */
1521
1522   if (geom_mask & GDK_HINT_MIN_SIZE)
1523     {
1524       GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1525                                geometry->min_width, geometry->min_height));
1526
1527 #if 0
1528       /* Check if the current size of the window is in bounds */
1529       GetClientRect (GDK_WINDOW_HWND (window), &rect);
1530
1531       if (rect.right < geometry->min_width &&
1532           rect.bottom < geometry->min_height)
1533         {
1534           new_width = geometry->min_width;
1535           new_height = geometry->min_height;
1536         }
1537       else if (rect.right < geometry->min_width)
1538         {
1539           new_width = geometry->min_width;
1540           new_height = rect.bottom;
1541         }
1542       else if (rect.bottom < geometry->min_height)
1543         {
1544           new_width = rect.right;
1545           new_height = geometry->min_height;
1546         }
1547 #endif
1548     }
1549   
1550   if (geom_mask & GDK_HINT_MAX_SIZE)
1551     {
1552       GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1553                                geometry->max_width, geometry->max_height));
1554
1555 #if 0
1556       /* Check if the current size of the window is in bounds */
1557       GetClientRect (GDK_WINDOW_HWND (window), &rect);
1558
1559       if (rect.right > geometry->max_width &&
1560           rect.bottom > geometry->max_height)
1561         {
1562           new_width = geometry->max_width;
1563           new_height = geometry->max_height;
1564         }
1565       else if (rect.right > geometry->max_width)
1566         {
1567           new_width = geometry->max_width;
1568           new_height = rect.bottom;
1569         }
1570       else if (rect.bottom > geometry->max_height)
1571         {
1572           new_width = rect.right;
1573           new_height = geometry->max_height;
1574         }
1575 #endif
1576     }
1577
1578 #if 0
1579   /* Apply new size constraints */
1580   if (new_width != 0 && new_height != 0)
1581     gdk_window_resize (window, new_width, new_height);
1582 #endif
1583
1584   if (geom_mask & GDK_HINT_BASE_SIZE)
1585     {
1586       GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1587                                geometry->base_width, geometry->base_height));
1588
1589 #if 0
1590       size_hints.length = sizeof (size_hints);
1591
1592       if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints)))
1593         {
1594           GDK_NOTE (MISC,
1595                     g_print ("... rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
1596                              size_hints.rcNormalPosition.left,
1597                              size_hints.rcNormalPosition.top,
1598                              size_hints.rcNormalPosition.right,
1599                              size_hints.rcNormalPosition.bottom));
1600           size_hints.rcNormalPosition.right =
1601             size_hints.rcNormalPosition.left + geometry->base_width;
1602           size_hints.rcNormalPosition.bottom =
1603             size_hints.rcNormalPosition.top + geometry->base_height;
1604           GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%ld,%ld)--(%ld,%ld)\n",
1605                                    size_hints.rcNormalPosition.left,
1606                                    size_hints.rcNormalPosition.top,
1607                                    size_hints.rcNormalPosition.right,
1608                                    size_hints.rcNormalPosition.bottom));
1609           API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints));
1610         }
1611 #endif
1612     }
1613   
1614   if (geom_mask & GDK_HINT_RESIZE_INC)
1615     {
1616       GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1617                                geometry->width_inc, geometry->height_inc));
1618     }
1619   
1620   if (geom_mask & GDK_HINT_ASPECT)
1621     {
1622       GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1623                                geometry->min_aspect, geometry->max_aspect));
1624     }
1625
1626   if (geom_mask & GDK_HINT_WIN_GRAVITY)
1627     {
1628       GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1629     }
1630 }
1631
1632 void
1633 gdk_window_set_title (GdkWindow   *window,
1634                       const gchar *title)
1635 {
1636   char *mbtitle;
1637
1638   g_return_if_fail (window != NULL);
1639   g_return_if_fail (GDK_IS_WINDOW (window));
1640   g_return_if_fail (title != NULL);
1641
1642   /* Empty window titles not allowed, so set it to just a period. */
1643   if (!title[0])
1644     title = ".";
1645   
1646   GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1647                            GDK_WINDOW_HWND (window), title));
1648   
1649   if (!GDK_WINDOW_DESTROYED (window))
1650     {
1651       /* As the title is in UTF-8 we must translate it
1652        * to the system codepage.
1653        */
1654       mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
1655       API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), mbtitle));
1656       g_free (mbtitle);
1657     }
1658 }
1659
1660 void          
1661 gdk_window_set_role (GdkWindow   *window,
1662                      const gchar *role)
1663 {
1664   g_return_if_fail (window != NULL);
1665   g_return_if_fail (GDK_IS_WINDOW (window));
1666   
1667   GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1668                            GDK_WINDOW_HWND (window),
1669                            (role ? role : "NULL")));
1670   /* XXX */
1671 }
1672
1673 void          
1674 gdk_window_set_transient_for (GdkWindow *window, 
1675                               GdkWindow *parent)
1676 {
1677   HWND window_id, parent_id;
1678
1679   g_return_if_fail (window != NULL);
1680   g_return_if_fail (GDK_IS_WINDOW (window));
1681   
1682   GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n",
1683                            GDK_WINDOW_HWND (window),
1684                            GDK_WINDOW_HWND (parent)));
1685
1686   if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
1687     return;
1688
1689   if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1690     {
1691       GDK_NOTE (MISC, g_print ("...a child window!\n"));
1692       return;
1693     }
1694   
1695   window_id = GDK_WINDOW_HWND (window);
1696   parent_id = GDK_WINDOW_HWND (parent);
1697
1698   /* This changes the *owner* of the window, despite the misleading
1699    * name. (Owner and parent are unrelated concepts.) At least that's
1700    * what people who seem to know what they talk about say on
1701    * USENET. Search on Google.
1702    */
1703   SetLastError (0);
1704   if (SetWindowLong (window_id, GWL_HWNDPARENT, (long) parent_id) == 0 &&
1705       GetLastError () != 0)
1706     WIN32_API_FAILED ("SetWindowLong");
1707 }
1708
1709 void
1710 gdk_window_set_background (GdkWindow      *window,
1711                            const GdkColor *color)
1712 {
1713   GdkWindowObject *private = (GdkWindowObject *)window;
1714   
1715   g_return_if_fail (window != NULL);
1716   g_return_if_fail (GDK_IS_WINDOW (window));
1717   
1718   GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
1719                            GDK_WINDOW_HWND (window), 
1720                            _gdk_win32_color_to_string (color)));
1721
1722   private->bg_color = *color;
1723
1724   if (private->bg_pixmap &&
1725       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1726       private->bg_pixmap != GDK_NO_BG)
1727     {
1728       g_object_unref (private->bg_pixmap);
1729       private->bg_pixmap = NULL;
1730     }
1731 }
1732
1733 void
1734 gdk_window_set_back_pixmap (GdkWindow *window,
1735                             GdkPixmap *pixmap,
1736                             gint       parent_relative)
1737 {
1738   GdkWindowObject *private = (GdkWindowObject *)window;
1739
1740   g_return_if_fail (window != NULL);
1741   g_return_if_fail (GDK_IS_WINDOW (window));
1742   g_return_if_fail (pixmap == NULL || !parent_relative);
1743   g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
1744   
1745   if (private->bg_pixmap &&
1746       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1747       private->bg_pixmap != GDK_NO_BG)
1748     g_object_unref (private->bg_pixmap);
1749
1750   if (parent_relative)
1751     {
1752       private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1753       GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
1754     }
1755   else
1756     {
1757       if (pixmap)
1758         {
1759           g_object_ref (pixmap);
1760           private->bg_pixmap = pixmap;
1761         }
1762       else
1763         {
1764           private->bg_pixmap = GDK_NO_BG;
1765         }
1766     }
1767 }
1768
1769 void
1770 gdk_window_set_cursor (GdkWindow *window,
1771                        GdkCursor *cursor)
1772 {
1773   GdkWindowImplWin32 *impl;
1774   GdkCursorPrivate *cursor_private;
1775   GdkWindowObject *parent_window;
1776   HCURSOR hcursor;
1777   HCURSOR hprevcursor;
1778   
1779   g_return_if_fail (window != NULL);
1780   g_return_if_fail (GDK_IS_WINDOW (window));
1781   
1782   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1783   cursor_private = (GdkCursorPrivate*) cursor;
1784   
1785   if (GDK_WINDOW_DESTROYED (window))
1786     return;
1787
1788   if (!cursor)
1789     hcursor = NULL;
1790   else
1791     hcursor = cursor_private->hcursor;
1792   
1793   GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
1794                            GDK_WINDOW_HWND (window),
1795                            hcursor));
1796
1797   /* First get the old cursor, if any (we wait to free the old one
1798    * since it may be the current cursor set in the Win32 API right
1799    * now).
1800    */
1801   hprevcursor = impl->hcursor;
1802
1803   if (hcursor == NULL)
1804     impl->hcursor = NULL;
1805   else
1806     {
1807       /* We must copy the cursor as it is OK to destroy the GdkCursor
1808        * while still in use for some window. See for instance
1809        * gimp_change_win_cursor() which calls gdk_window_set_cursor
1810        * (win, cursor), and immediately afterwards gdk_cursor_destroy
1811        * (cursor).
1812        */
1813       if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1814         WIN32_API_FAILED ("CopyCursor");
1815       GDK_NOTE (MISC, g_print ("...CopyCursor (%p) = %p\n",
1816                                hcursor, impl->hcursor));
1817     }
1818
1819   /* If the pointer is over our window, set new cursor if given */
1820   if (gdk_window_get_pointer(window, NULL, NULL, NULL) == window)
1821     if (impl->hcursor != NULL)
1822       SetCursor (impl->hcursor);
1823
1824   /* Destroy the previous cursor: Need to make sure it's no longer in
1825    * use before we destroy it, in case we're not over our window but
1826    * the cursor is still set to our old one.
1827    */
1828   if (hprevcursor != NULL)
1829     {
1830       if (GetCursor() == hprevcursor)
1831         {
1832           /* Look for a suitable cursor to use instead */
1833           hcursor = NULL;
1834           parent_window = GDK_WINDOW_OBJECT (window)->parent;
1835           while (hcursor == NULL)
1836             {
1837               if (parent_window)
1838                 {
1839                   impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1840                   hcursor = impl->hcursor;
1841                   parent_window = parent_window->parent;
1842                 }
1843               else
1844                 {
1845                   hcursor = LoadCursor (NULL, IDC_ARROW);
1846                 }
1847             }
1848           SetCursor (hcursor);
1849         }
1850
1851       GDK_NOTE (MISC, g_print ("...DestroyCursor (%p)\n",
1852                                hprevcursor));
1853       
1854       API_CALL (DestroyCursor, (hprevcursor));
1855     }
1856 }
1857
1858 void
1859 gdk_window_get_geometry (GdkWindow *window,
1860                          gint      *x,
1861                          gint      *y,
1862                          gint      *width,
1863                          gint      *height,
1864                          gint      *depth)
1865 {
1866   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1867   
1868   if (!window)
1869     window = _gdk_parent_root;
1870   
1871   if (!GDK_WINDOW_DESTROYED (window))
1872     {
1873       RECT rect;
1874
1875       API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1876
1877       if (window != _gdk_parent_root)
1878         {
1879           POINT pt;
1880           GdkWindow *parent = gdk_window_get_parent (window);
1881
1882           pt.x = rect.left;
1883           pt.y = rect.top;
1884           ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1885           ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1886           rect.left = pt.x;
1887           rect.top = pt.y;
1888
1889           pt.x = rect.right;
1890           pt.y = rect.bottom;
1891           ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1892           ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1893           rect.right = pt.x;
1894           rect.bottom = pt.y;
1895
1896           if (parent == _gdk_parent_root)
1897             {
1898               rect.left += _gdk_offset_x;
1899               rect.top += _gdk_offset_y;
1900               rect.right += _gdk_offset_x;
1901               rect.bottom += _gdk_offset_y;
1902             }
1903         }
1904
1905       if (x)
1906         *x = rect.left;
1907       if (y)
1908         *y = rect.top;
1909       if (width)
1910         *width = rect.right - rect.left;
1911       if (height)
1912         *height = rect.bottom - rect.top;
1913       if (depth)
1914         *depth = gdk_drawable_get_visual (window)->depth;
1915
1916       GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@+%ld+%ld\n",
1917                                GDK_WINDOW_HWND (window),
1918                                rect.right - rect.left, rect.bottom - rect.top,
1919                                gdk_drawable_get_visual (window)->depth,
1920                                rect.left, rect.top));
1921     }
1922 }
1923
1924 gint
1925 gdk_window_get_origin (GdkWindow *window,
1926                        gint      *x,
1927                        gint      *y)
1928 {
1929   gint return_val;
1930   gint tx = 0;
1931   gint ty = 0;
1932
1933   g_return_val_if_fail (window != NULL, 0);
1934
1935   if (!GDK_WINDOW_DESTROYED (window))
1936     {
1937       POINT pt;
1938
1939       pt.x = 0;
1940       pt.y = 0;
1941       ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1942       tx = pt.x;
1943       ty = pt.y;
1944       return_val = 1;
1945     }
1946   else
1947     return_val = 0;
1948   
1949   if (x)
1950     *x = tx + _gdk_offset_x;
1951   if (y)
1952     *y = ty + _gdk_offset_y;
1953
1954   GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: +%d+%d\n",
1955                            GDK_WINDOW_HWND (window),
1956                            tx, ty));
1957   return return_val;
1958 }
1959
1960 gboolean
1961 gdk_window_get_deskrelative_origin (GdkWindow *window,
1962                                     gint      *x,
1963                                     gint      *y)
1964 {
1965   return gdk_window_get_origin (window, x, y);
1966 }
1967
1968 void
1969 gdk_window_get_root_origin (GdkWindow *window,
1970                             gint      *x,
1971                             gint      *y)
1972 {
1973   GdkRectangle rect;
1974
1975   g_return_if_fail (GDK_IS_WINDOW (window));
1976
1977   gdk_window_get_frame_extents (window, &rect);
1978
1979   if (x)
1980     *x = rect.x;
1981
1982   if (y)
1983     *y = rect.y;
1984
1985   GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: +%d+%d\n",
1986                            GDK_WINDOW_HWND (window), rect.x, rect.y));
1987 }
1988
1989 void
1990 gdk_window_get_frame_extents (GdkWindow    *window,
1991                               GdkRectangle *rect)
1992 {
1993   GdkWindowObject *private;
1994   HWND hwnd;
1995   RECT r;
1996
1997   g_return_if_fail (GDK_IS_WINDOW (window));
1998   g_return_if_fail (rect != NULL);
1999
2000   private = GDK_WINDOW_OBJECT (window);
2001
2002   rect->x = 0;
2003   rect->y = 0;
2004   rect->width = 1;
2005   rect->height = 1;
2006   
2007   if (GDK_WINDOW_DESTROYED (window))
2008     return;
2009
2010   /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2011    * necessary to walk its parent chain?
2012    */
2013   while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2014     private = (GdkWindowObject*) private->parent;
2015
2016   hwnd = GDK_WINDOW_HWND (window);
2017
2018   /* find the frame window */
2019   while (HWND_DESKTOP != GetParent (hwnd))
2020     {
2021       hwnd = GetParent (hwnd);
2022       g_return_if_fail (NULL != hwnd);
2023     }
2024
2025   API_CALL (GetWindowRect, (hwnd, &r));
2026
2027   rect->x = r.left + _gdk_offset_x;
2028   rect->y = r.top + _gdk_offset_y;
2029   rect->width = r.right - r.left;
2030   rect->height = r.bottom - r.top;
2031
2032   GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@+%ld+%ld\n",
2033                            GDK_WINDOW_HWND (window),
2034                            r.right - r.left, r.bottom - r.top,
2035                            r.left, r.top));
2036 }
2037
2038 GdkWindow*
2039 _gdk_windowing_window_get_pointer (GdkDisplay      *display,
2040                                    GdkWindow       *window,
2041                                    gint            *x,
2042                                    gint            *y,
2043                                    GdkModifierType *mask)
2044 {
2045   GdkWindow *return_val;
2046   POINT screen_point, point;
2047   HWND hwnd, hwndc;
2048   BYTE kbd[256];
2049
2050   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2051   
2052   return_val = NULL;
2053   GetCursorPos (&screen_point);
2054   point = screen_point;
2055   ScreenToClient (GDK_WINDOW_HWND (window), &point);
2056
2057   *x = point.x;
2058   *y = point.y;
2059
2060   if (window == _gdk_parent_root)
2061     {
2062       *x += _gdk_offset_x;
2063       *y += _gdk_offset_y;
2064     }
2065
2066   hwnd = WindowFromPoint (screen_point);
2067   if (hwnd != NULL)
2068     {
2069       gboolean done = FALSE;
2070       
2071       while (!done)
2072         {
2073           point = screen_point;
2074           ScreenToClient (hwnd, &point);
2075           hwndc = ChildWindowFromPoint (hwnd, point);
2076           if (hwndc == NULL)
2077             done = TRUE;
2078           else if (hwndc == hwnd)
2079             done = TRUE;
2080           else
2081             hwnd = hwndc;
2082         }
2083       
2084       return_val = gdk_window_lookup ((GdkNativeWindow) hwnd);
2085     }
2086   else
2087     return_val = NULL;
2088       
2089   GetKeyboardState (kbd);
2090   *mask = 0;
2091   if (kbd[VK_SHIFT] & 0x80)
2092     *mask |= GDK_SHIFT_MASK;
2093   if (kbd[VK_CAPITAL] & 0x80)
2094     *mask |= GDK_LOCK_MASK;
2095   if (kbd[VK_CONTROL] & 0x80)
2096     *mask |= GDK_CONTROL_MASK;
2097   if (kbd[VK_MENU] & 0x80)
2098     *mask |= GDK_MOD1_MASK;
2099   if (kbd[VK_LBUTTON] & 0x80)
2100     *mask |= GDK_BUTTON1_MASK;
2101   if (kbd[VK_MBUTTON] & 0x80)
2102     *mask |= GDK_BUTTON2_MASK;
2103   if (kbd[VK_RBUTTON] & 0x80)
2104     *mask |= GDK_BUTTON3_MASK;
2105   
2106   return return_val;
2107 }
2108
2109 void
2110 _gdk_windowing_get_pointer (GdkDisplay       *display,
2111                             GdkScreen       **screen,
2112                             gint             *x,
2113                             gint             *y,
2114                             GdkModifierType  *mask)
2115 {
2116   GdkScreen *default_screen = gdk_display_get_default_screen (display);
2117   GdkWindow *root_window = gdk_screen_get_root_window (default_screen);
2118   
2119   *screen = default_screen;
2120   _gdk_windowing_window_get_pointer (display, root_window, x, y, mask);
2121 }
2122
2123 GdkWindow*
2124 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2125                                   gint       *win_x,
2126                                   gint       *win_y)
2127 {
2128   GdkWindow *window;
2129   POINT point, pointc;
2130   HWND hwnd, hwndc;
2131   RECT rect;
2132
2133   GetCursorPos (&pointc);
2134   point = pointc;
2135   hwnd = WindowFromPoint (point);
2136
2137   if (hwnd == NULL)
2138     {
2139       window = _gdk_parent_root;
2140       *win_x = pointc.x + _gdk_offset_x;
2141       *win_y = pointc.y + _gdk_offset_y;
2142       return window;
2143     }
2144       
2145   ScreenToClient (hwnd, &point);
2146
2147   do {
2148     hwndc = ChildWindowFromPoint (hwnd, point);
2149     ClientToScreen (hwnd, &point);
2150     ScreenToClient (hwndc, &point);
2151   } while (hwndc != hwnd && (hwnd = hwndc, 1));
2152
2153   window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2154
2155   if (window && (win_x || win_y))
2156     {
2157       GetClientRect (hwnd, &rect);
2158       *win_x = point.x - rect.left;
2159       *win_y = point.y - rect.top;
2160     }
2161
2162   GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: +%d+%d %p%s\n",
2163                            *win_x, *win_y,
2164                            hwnd,
2165                            (window == NULL ? " NULL" : "")));
2166
2167   return window;
2168 }
2169
2170 GdkEventMask  
2171 gdk_window_get_events (GdkWindow *window)
2172 {
2173   g_return_val_if_fail (window != NULL, 0);
2174   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2175
2176   if (GDK_WINDOW_DESTROYED (window))
2177     return 0;
2178
2179   return GDK_WINDOW_OBJECT (window)->event_mask;
2180 }
2181
2182 void          
2183 gdk_window_set_events (GdkWindow   *window,
2184                        GdkEventMask event_mask)
2185 {
2186   g_return_if_fail (window != NULL);
2187   g_return_if_fail (GDK_IS_WINDOW (window));
2188
2189   if (GDK_WINDOW_DESTROYED (window))
2190     return;
2191
2192   /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2193    * set it here, too. Not that I know or remember why it is
2194    * necessary, will have to test some day.
2195    */
2196   GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2197 }
2198
2199 void
2200 gdk_window_shape_combine_mask (GdkWindow *window,
2201                                GdkBitmap *mask,
2202                                gint x, gint y)
2203 {
2204   g_return_if_fail (window != NULL);
2205   g_return_if_fail (GDK_IS_WINDOW (window));
2206
2207   if (!mask)
2208     {
2209       GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2210                                GDK_WINDOW_HWND (window)));
2211       SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2212     }
2213   else
2214     {
2215       HRGN hrgn;
2216       RECT rect;
2217
2218       /* Convert mask bitmap to region */
2219       hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2220
2221       GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2222                                GDK_WINDOW_HWND (window),
2223                                GDK_WINDOW_HWND (mask)));
2224
2225       _gdk_win32_get_adjusted_client_rect (window, &rect);
2226
2227       OffsetRgn (hrgn, -rect.left, -rect.top);
2228       OffsetRgn (hrgn, x, y);
2229
2230       /* If this is a top-level window, add the title bar to the region */
2231       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2232         {
2233           HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2234           CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2235           DeleteObject (tmp);
2236         }
2237       
2238       SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2239     }
2240 }
2241
2242 void
2243 gdk_window_set_override_redirect (GdkWindow *window,
2244                                   gboolean   override_redirect)
2245 {
2246   g_return_if_fail (window != NULL);
2247   g_return_if_fail (GDK_IS_WINDOW (window));
2248
2249   g_warning ("gdk_window_set_override_redirect not implemented");
2250 }
2251
2252 void
2253 gdk_window_set_accept_focus (GdkWindow *window,
2254                              gboolean accept_focus)
2255 {
2256   GdkWindowObject *private;
2257   g_return_if_fail (window != NULL);
2258   g_return_if_fail (GDK_IS_WINDOW (window));
2259
2260   private = (GdkWindowObject *)window;  
2261   
2262   accept_focus = accept_focus != FALSE;
2263
2264   if (private->accept_focus != accept_focus)
2265     private->accept_focus = accept_focus;
2266 }
2267
2268 void
2269 gdk_window_set_focus_on_map (GdkWindow *window,
2270                              gboolean focus_on_map)
2271 {
2272   GdkWindowObject *private;
2273   g_return_if_fail (window != NULL);
2274   g_return_if_fail (GDK_IS_WINDOW (window));
2275
2276   private = (GdkWindowObject *)window;  
2277   
2278   focus_on_map = focus_on_map != FALSE;
2279
2280   if (private->focus_on_map != focus_on_map)
2281     private->focus_on_map = focus_on_map;
2282 }
2283
2284 static HICON
2285 pixbuf_to_hicon_alpha_winxp (GdkWindow *window,
2286                              GdkPixbuf *pixbuf)
2287 {
2288   /* Based on code from
2289    * http://www.dotnet247.com/247reference/msgs/13/66301.aspx
2290    */
2291   HDC hdc;
2292   BITMAPV5HEADER bi;
2293   HBITMAP hBitmap, hMonoBitmap;
2294   guchar *indata, *inrow;
2295   guchar *outdata, *outrow;
2296   HICON hAlphaIcon = NULL;
2297   ICONINFO ii;
2298   gint width, height, i, j, rowstride;
2299
2300   if (pixbuf == NULL)
2301     return NULL;
2302
2303   width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
2304   height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
2305
2306   ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
2307   bi.bV5Size = sizeof (BITMAPV5HEADER);
2308   bi.bV5Width = width;
2309   bi.bV5Height = height;
2310   bi.bV5Planes = 1;
2311   bi.bV5BitCount = 32;
2312   bi.bV5Compression = BI_BITFIELDS;
2313   /* The following mask specification specifies a supported 32 BPP
2314    * alpha format for Windows XP (BGRA format).
2315    */
2316   bi.bV5RedMask   = 0x00FF0000;
2317   bi.bV5GreenMask = 0x0000FF00;
2318   bi.bV5BlueMask  = 0x000000FF;
2319   bi.bV5AlphaMask = 0xFF000000;
2320
2321   /* Create the DIB section with an alpha channel. */
2322   hdc = GetDC (NULL);
2323   hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
2324                               (void **)&outdata, NULL, (DWORD)0);
2325   ReleaseDC (NULL, hdc);
2326
2327   /* Draw something on the DIB section */
2328   indata = gdk_pixbuf_get_pixels (pixbuf);
2329   rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2330   for (j=0; j<height; j++)
2331     {
2332       outrow = outdata + 4*j*width;
2333       inrow  = indata  + (height-j-1)*rowstride;
2334       for (i=0; i<width; i++)
2335         {
2336           outrow[4*i+0] = inrow[4*i+2];
2337           outrow[4*i+1] = inrow[4*i+1];
2338           outrow[4*i+2] = inrow[4*i+0];
2339           outrow[4*i+3] = inrow[4*i+3];
2340         }
2341     }
2342
2343   /* Create an empty mask bitmap */
2344   hMonoBitmap = CreateBitmap (width, height, 1, 1, NULL);
2345
2346   ii.fIcon = TRUE;
2347   ii.xHotspot = 0;
2348   ii.yHotspot = 0;
2349   ii.hbmMask = hMonoBitmap;
2350   ii.hbmColor = hBitmap;
2351
2352   /* Create the alpha cursor with the alpha DIB section */
2353   hAlphaIcon = CreateIconIndirect (&ii);
2354
2355   GDI_CALL (DeleteObject, (hBitmap));
2356   GDI_CALL (DeleteObject, (hMonoBitmap));
2357
2358   return hAlphaIcon;
2359 }
2360
2361 static HICON
2362 pixbuf_to_hicon_normal (GdkWindow *window,
2363                         GdkPixbuf *pixbuf)
2364 {
2365   GdkPixmap *pixmap;
2366   GdkBitmap *mask;
2367   HBITMAP hbmmask = NULL;
2368   ICONINFO ii;
2369   HICON hIcon;
2370   gint w = 0, h = 0;
2371
2372   if (pixbuf == NULL)
2373     return NULL;
2374
2375   /* create a normal icon with a bitmap mask */
2376   w = gdk_pixbuf_get_width (pixbuf);
2377   h = gdk_pixbuf_get_height (pixbuf);
2378   gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, 
2379                                                   gdk_drawable_get_colormap (window),
2380                                                   &pixmap,
2381                                                   &mask,
2382                                                   128);
2383
2384   /* we need the inverted mask for the XOR op */
2385   {
2386     HDC hdc1 = CreateCompatibleDC (NULL);
2387     HBITMAP hbmold1;
2388
2389     hbmmask = CreateCompatibleBitmap (hdc1, w, h);
2390     hbmold1 = SelectObject (hdc1, hbmmask);
2391     if (mask)
2392       {
2393         HDC hdc2 = CreateCompatibleDC (NULL);
2394         HBITMAP hbmold2 = SelectObject (hdc2, GDK_PIXMAP_HBITMAP (mask));
2395         GDI_CALL (BitBlt, (hdc1, 0,0,w,h, hdc2, 0,0, NOTSRCCOPY));
2396         GDI_CALL (SelectObject, (hdc2, hbmold2));
2397         GDI_CALL (DeleteDC, (hdc2));
2398       }
2399     else
2400       {
2401         RECT rect;
2402         GetClipBox (hdc1, &rect);
2403         GDI_CALL (FillRect, (hdc1, &rect, GetStockObject (BLACK_BRUSH)));
2404       }
2405     GDI_CALL (SelectObject, (hdc1, hbmold1));
2406     GDI_CALL (DeleteDC, (hdc1));
2407   }
2408
2409   ii.fIcon = TRUE;
2410   ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
2411   ii.hbmMask = hbmmask;
2412   ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap);
2413   hIcon = CreateIconIndirect (&ii);
2414   if (!hIcon)
2415     WIN32_API_FAILED ("CreateIconIndirect");
2416   GDI_CALL (DeleteObject, (hbmmask));
2417
2418 #if 0 /* to debug pixmap and mask setting */
2419   {
2420     static int num = 0;
2421     GdkPixbuf* pixbuf = NULL;
2422     char name[256];
2423
2424     pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, w, h);
2425     if (pixbuf)
2426       {
2427         num = (num + 1) % 999; /* restrict maximim number */
2428         sprintf (name, "c:\\temp\\ico%03dpixm.png", num); 
2429         gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
2430         gdk_pixbuf_unref (pixbuf);
2431       }
2432   }
2433 #endif
2434
2435   if (pixmap)
2436     g_object_unref (G_OBJECT (pixmap));
2437   if (mask)
2438     g_object_unref (G_OBJECT (mask));
2439
2440   return hIcon;
2441 }
2442
2443 static HICON
2444 pixbuf_to_hicon (GdkWindow *window,
2445                  GdkPixbuf *pixbuf)
2446 {
2447   static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
2448
2449   if (!is_win_xp_checked)
2450     {
2451       OSVERSIONINFO version;
2452
2453       is_win_xp_checked = TRUE;
2454       memset (&version, 0, sizeof (version));
2455       version.dwOSVersionInfoSize = sizeof (version);
2456       is_win_xp = GetVersionEx (&version)
2457         && version.dwPlatformId == VER_PLATFORM_WIN32_NT
2458         && (version.dwMajorVersion > 5
2459             || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
2460     }
2461
2462   if (pixbuf == NULL)
2463     return NULL;
2464
2465   if (is_win_xp && gdk_pixbuf_get_has_alpha (pixbuf))
2466     return pixbuf_to_hicon_alpha_winxp (window, pixbuf);
2467   else
2468     return pixbuf_to_hicon_normal (window, pixbuf);
2469 }
2470
2471 void          
2472 gdk_window_set_icon_list (GdkWindow *window,
2473                           GList     *pixbufs)
2474 {
2475   GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2476   gint big_diff, small_diff;
2477   gint big_w, big_h, small_w, small_h;
2478   gint w, h;
2479   gint dw, dh, diff;
2480   HICON small_hicon, big_hicon;
2481   GdkWindowImplWin32 *impl;
2482   gint i, big_i, small_i;
2483
2484   g_return_if_fail (GDK_IS_WINDOW (window));
2485
2486   if (GDK_WINDOW_DESTROYED (window))
2487     return;
2488
2489   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2490
2491   /* ideal sizes for small and large icons */
2492   big_w = GetSystemMetrics (SM_CXICON);
2493   big_h = GetSystemMetrics (SM_CYICON);
2494   small_w = GetSystemMetrics (SM_CXSMICON);
2495   small_h = GetSystemMetrics (SM_CYSMICON);
2496
2497   /* find closest sized icons in the list */
2498   big_pixbuf = NULL;
2499   small_pixbuf = NULL;
2500   big_diff = 0;
2501   small_diff = 0;
2502   i = 0;
2503   while (pixbufs)
2504     {
2505       pixbuf = (GdkPixbuf*) pixbufs->data;
2506       w = gdk_pixbuf_get_width (pixbuf);
2507       h = gdk_pixbuf_get_height (pixbuf);
2508
2509       dw = ABS (w - big_w);
2510       dh = ABS (h - big_h);
2511       diff = dw*dw + dh*dh;
2512       if (big_pixbuf == NULL || diff < big_diff)
2513         {
2514           big_pixbuf = pixbuf;
2515           big_diff = diff;
2516           big_i = i;
2517         }
2518
2519       dw = ABS(w - small_w);
2520       dh = ABS(h - small_h);
2521       diff = dw*dw + dh*dh;
2522       if (small_pixbuf == NULL || diff < small_diff)
2523         {
2524           small_pixbuf = pixbuf;
2525           small_diff = diff;
2526           small_i = i;
2527         }
2528
2529       pixbufs = g_list_next (pixbufs);
2530       i++;
2531     }
2532
2533   /* Create the icons */
2534   big_hicon = pixbuf_to_hicon (window, big_pixbuf);
2535   small_hicon = pixbuf_to_hicon (window, small_pixbuf);
2536
2537   /* Set the icons */
2538   SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2539                (LPARAM)big_hicon);
2540   SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2541                (LPARAM)small_hicon);
2542
2543   /* Store the icons, destroying any previous icons */
2544   if (impl->hicon_big)
2545     GDI_CALL (DestroyIcon, (impl->hicon_big));
2546   impl->hicon_big = big_hicon;
2547   if (impl->hicon_small)
2548     GDI_CALL (DestroyIcon, (impl->hicon_small));
2549   impl->hicon_small = small_hicon;
2550 }
2551
2552 void          
2553 gdk_window_set_icon (GdkWindow *window, 
2554                      GdkWindow *icon_window,
2555                      GdkPixmap *pixmap,
2556                      GdkBitmap *mask)
2557 {
2558   g_return_if_fail (window != NULL);
2559   g_return_if_fail (GDK_IS_WINDOW (window));
2560
2561   /* do nothing, use gdk_window_set_icon_list instead */
2562 }
2563
2564 void
2565 gdk_window_set_icon_name (GdkWindow   *window, 
2566                           const gchar *name)
2567 {
2568   g_return_if_fail (window != NULL);
2569   g_return_if_fail (GDK_IS_WINDOW (window));
2570
2571   if (GDK_WINDOW_DESTROYED (window))
2572     return;
2573   
2574   API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2575 }
2576
2577 GdkWindow *
2578 gdk_window_get_group (GdkWindow *window)
2579 {
2580   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2581   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2582
2583   if (GDK_WINDOW_DESTROYED (window))
2584     return NULL;
2585   
2586   g_warning ("gdk_window_get_group not yet implemented");
2587
2588   return NULL;
2589 }
2590
2591 void          
2592 gdk_window_set_group (GdkWindow *window, 
2593                       GdkWindow *leader)
2594 {
2595   g_return_if_fail (window != NULL);
2596   g_return_if_fail (GDK_IS_WINDOW (window));
2597   g_return_if_fail (leader != NULL);
2598   g_return_if_fail (GDK_IS_WINDOW (leader));
2599
2600   if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2601     return;
2602   
2603   g_warning ("gdk_window_set_group not implemented");
2604 }
2605
2606 void
2607 gdk_window_set_decorations (GdkWindow      *window,
2608                             GdkWMDecoration decorations)
2609 {
2610   LONG style, bits;
2611   const LONG settable_bits = WS_BORDER|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
2612
2613   g_return_if_fail (window != NULL);
2614   g_return_if_fail (GDK_IS_WINDOW (window));
2615   
2616   GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s%s%s%s%s%s%s\n",
2617                            GDK_WINDOW_HWND (window),
2618                            (decorations & GDK_DECOR_ALL ? "ALL " : ""),
2619                            (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2620                            (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2621                            (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2622                            (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2623                            (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2624                            (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2625
2626   style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2627
2628   bits = 0;
2629
2630   if (decorations & GDK_DECOR_BORDER)
2631     bits |= WS_BORDER;
2632   if (decorations & GDK_DECOR_RESIZEH)
2633     bits |= WS_THICKFRAME;
2634   if (decorations & GDK_DECOR_TITLE)
2635     bits |= WS_CAPTION;
2636   if (decorations & GDK_DECOR_MENU)
2637     bits |= WS_SYSMENU;
2638   if (decorations & GDK_DECOR_MINIMIZE)
2639     bits |= WS_MINIMIZEBOX;
2640   if (decorations & GDK_DECOR_MAXIMIZE)
2641     bits |= WS_MAXIMIZEBOX;
2642
2643   if (decorations & GDK_DECOR_ALL)
2644     style |= settable_bits, style &= ~bits;
2645   else
2646     style &= ~settable_bits, style |= bits;
2647   
2648   SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2649   SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
2650                 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2651                 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2652 }
2653
2654 gboolean
2655 gdk_window_get_decorations(GdkWindow       *window,
2656                            GdkWMDecoration *decorations)
2657 {
2658   LONG style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2659
2660   *decorations = 0;
2661
2662   if (style & WS_BORDER)
2663     *decorations |= GDK_DECOR_BORDER;
2664   if (style & WS_THICKFRAME)
2665     *decorations |= GDK_DECOR_RESIZEH;
2666   if (style & WS_CAPTION)
2667     *decorations |= GDK_DECOR_TITLE;
2668   if (style & WS_SYSMENU)
2669     *decorations |= GDK_DECOR_MENU;
2670   if (style & WS_MINIMIZEBOX)
2671     *decorations |= GDK_DECOR_MINIMIZE;
2672   if (style & WS_MAXIMIZEBOX)
2673     *decorations |= GDK_DECOR_MAXIMIZE;
2674
2675   return *decorations != 0;
2676 }
2677
2678 void
2679 gdk_window_set_functions (GdkWindow    *window,
2680                           GdkWMFunction functions)
2681 {
2682   LONG style, bits;
2683   const LONG settable_bits = (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU);
2684
2685   g_return_if_fail (window != NULL);
2686   g_return_if_fail (GDK_IS_WINDOW (window));
2687   
2688   GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s%s%s%s%s%s\n",
2689                            GDK_WINDOW_HWND (window),
2690                            (functions & GDK_FUNC_ALL ? "ALL " : ""),
2691                            (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2692                            (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2693                            (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2694                            (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2695                            (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2696
2697   style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2698
2699   bits = 0;
2700
2701   if (functions & GDK_FUNC_RESIZE)
2702     bits |= WS_THICKFRAME;
2703   if (functions & GDK_FUNC_MOVE)
2704     bits |= (WS_THICKFRAME|WS_SYSMENU);
2705   if (functions & GDK_FUNC_MINIMIZE)
2706     bits |= WS_MINIMIZEBOX;
2707   if (functions & GDK_FUNC_MAXIMIZE)
2708     bits |= WS_MAXIMIZEBOX;
2709   if (functions & GDK_FUNC_CLOSE)
2710     bits |= WS_SYSMENU;
2711   
2712   if (functions & GDK_FUNC_ALL)
2713     style |= settable_bits, style &= ~bits;
2714   else
2715     style &= ~settable_bits, style |= bits;
2716   
2717   SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2718   SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
2719                 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2720                 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2721 }
2722
2723 static void
2724 QueryTree (HWND   hwnd,
2725            HWND **children,
2726            gint  *nchildren)
2727 {
2728   guint i, n;
2729   HWND child;
2730
2731   n = 0;
2732   do {
2733     if (n == 0)
2734       child = GetWindow (hwnd, GW_CHILD);
2735     else
2736       child = GetWindow (child, GW_HWNDNEXT);
2737     if (child != NULL)
2738       n++;
2739   } while (child != NULL);
2740
2741   if (n > 0)
2742     {
2743       *children = g_new (HWND, n);
2744       for (i = 0; i < n; i++)
2745         {
2746           if (i == 0)
2747             child = GetWindow (hwnd, GW_CHILD);
2748           else
2749             child = GetWindow (child, GW_HWNDNEXT);
2750           *children[i] = child;
2751         }
2752     }
2753 }
2754
2755 static void
2756 gdk_propagate_shapes (HANDLE   win,
2757                       gboolean merge)
2758 {
2759    RECT emptyRect;
2760    HRGN region, childRegion;
2761    HWND *list = NULL;
2762    gint i, num;
2763
2764    SetRectEmpty (&emptyRect);
2765    region = CreateRectRgnIndirect (&emptyRect);
2766    if (merge)
2767      GetWindowRgn (win, region);
2768    
2769    QueryTree (win, &list, &num);
2770    if (list != NULL)
2771      {
2772        WINDOWPLACEMENT placement;
2773
2774        placement.length = sizeof (WINDOWPLACEMENT);
2775        /* go through all child windows and combine regions */
2776        for (i = 0; i < num; i++)
2777          {
2778            GetWindowPlacement (list[i], &placement);
2779            if (placement.showCmd == SW_SHOWNORMAL)
2780              {
2781                childRegion = CreateRectRgnIndirect (&emptyRect);
2782                GetWindowRgn (list[i], childRegion);
2783                CombineRgn (region, region, childRegion, RGN_OR);
2784                DeleteObject (childRegion);
2785              }
2786           }
2787        SetWindowRgn (win, region, TRUE);
2788        g_free (list);
2789      }
2790    else
2791      DeleteObject (region);
2792 }
2793
2794 void
2795 gdk_window_set_child_shapes (GdkWindow *window)
2796 {
2797   g_return_if_fail (window != NULL);
2798   g_return_if_fail (GDK_IS_WINDOW (window));
2799    
2800   if (GDK_WINDOW_DESTROYED (window))
2801     return;
2802
2803   gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2804 }
2805
2806 void
2807 gdk_window_merge_child_shapes (GdkWindow *window)
2808 {
2809   g_return_if_fail (window != NULL);
2810   g_return_if_fail (GDK_IS_WINDOW (window));
2811   
2812   if (GDK_WINDOW_DESTROYED (window))
2813     return;
2814
2815   gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2816 }
2817
2818 gboolean 
2819 gdk_window_set_static_gravities (GdkWindow *window,
2820                                  gboolean   use_static)
2821 {
2822   GdkWindowObject *private = (GdkWindowObject *)window;
2823   
2824   g_return_val_if_fail (window != NULL, FALSE);
2825   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2826
2827   if (!use_static == !private->guffaw_gravity)
2828     return TRUE;
2829   
2830   if (use_static)
2831     return FALSE;
2832   
2833   private->guffaw_gravity = use_static;
2834   
2835   return TRUE;
2836 }
2837
2838 void
2839 gdk_window_begin_resize_drag (GdkWindow     *window,
2840                               GdkWindowEdge  edge,
2841                               gint           button,
2842                               gint           root_x,
2843                               gint           root_y,
2844                               guint32        timestamp)
2845 {
2846   g_return_if_fail (GDK_IS_WINDOW (window));
2847   
2848   if (GDK_WINDOW_DESTROYED (window))
2849     return;
2850
2851   /* XXX: isn't all this default on win32 ... */  
2852 }
2853
2854 void
2855 gdk_window_begin_move_drag (GdkWindow *window,
2856                             gint       button,
2857                             gint       root_x,
2858                             gint       root_y,
2859                             guint32    timestamp)
2860 {
2861   g_return_if_fail (GDK_IS_WINDOW (window));
2862   
2863   if (GDK_WINDOW_DESTROYED (window))
2864     return;
2865
2866   /* XXX: isn't all this default on win32 ... */  
2867 }
2868
2869
2870 /*
2871  * Setting window states
2872  */
2873 void
2874 gdk_window_iconify (GdkWindow *window)
2875 {
2876   HWND old_active_window;
2877
2878   g_return_if_fail (window != NULL);
2879   g_return_if_fail (GDK_IS_WINDOW (window));
2880
2881   if (GDK_WINDOW_DESTROYED (window))
2882     return;
2883
2884   GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2885                            GDK_WINDOW_HWND (window),
2886                            _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2887
2888   if (GDK_WINDOW_IS_MAPPED (window))
2889     {
2890       old_active_window = GetActiveWindow ();
2891       ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2892       if (old_active_window != GDK_WINDOW_HWND (window))
2893         SetActiveWindow (old_active_window);
2894     }
2895   else
2896     {
2897       gdk_synthesize_window_state (window,
2898                                    0,
2899                                    GDK_WINDOW_STATE_ICONIFIED);
2900     }
2901 }
2902
2903 void
2904 gdk_window_deiconify (GdkWindow *window)
2905 {
2906   g_return_if_fail (window != NULL);
2907   g_return_if_fail (GDK_IS_WINDOW (window));
2908
2909   if (GDK_WINDOW_DESTROYED (window))
2910     return;
2911
2912   GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2913                            GDK_WINDOW_HWND (window),
2914                            _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2915
2916   if (GDK_WINDOW_IS_MAPPED (window))
2917     {  
2918       show_window_internal (window, FALSE, TRUE);
2919     }
2920   else
2921     {
2922       gdk_synthesize_window_state (window,
2923                                    GDK_WINDOW_STATE_ICONIFIED,
2924                                    0);
2925     }
2926 }
2927
2928 void
2929 gdk_window_stick (GdkWindow *window)
2930 {
2931   g_return_if_fail (GDK_IS_WINDOW (window));
2932
2933   if (GDK_WINDOW_DESTROYED (window))
2934     return;
2935
2936   /* FIXME: Do something? */
2937 }
2938
2939 void
2940 gdk_window_unstick (GdkWindow *window)
2941 {
2942   g_return_if_fail (GDK_IS_WINDOW (window));
2943
2944   if (GDK_WINDOW_DESTROYED (window))
2945     return;
2946
2947   /* FIXME: Do something? */
2948 }
2949
2950 void
2951 gdk_window_maximize (GdkWindow *window)
2952 {
2953   g_return_if_fail (GDK_IS_WINDOW (window));
2954
2955   if (GDK_WINDOW_DESTROYED (window))
2956     return;
2957
2958   GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2959                            GDK_WINDOW_HWND (window),
2960                            _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2961
2962   if (GDK_WINDOW_IS_MAPPED (window))
2963     ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2964   else
2965     gdk_synthesize_window_state (window,
2966                                  0,
2967                                  GDK_WINDOW_STATE_MAXIMIZED);
2968 }
2969
2970 void
2971 gdk_window_unmaximize (GdkWindow *window)
2972 {
2973   g_return_if_fail (GDK_IS_WINDOW (window));
2974
2975   if (GDK_WINDOW_DESTROYED (window))
2976     return;
2977
2978   GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2979                            GDK_WINDOW_HWND (window),
2980                            _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2981
2982   if (GDK_WINDOW_IS_MAPPED (window))
2983     ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2984   else
2985     gdk_synthesize_window_state (window,
2986                                  GDK_WINDOW_STATE_MAXIMIZED,
2987                                  0);
2988 }
2989
2990 typedef struct _FullscreenInfo FullscreenInfo;
2991
2992 struct _FullscreenInfo
2993 {
2994   RECT  r;
2995   guint hint_flags;
2996   LONG  style;
2997 };
2998
2999 void
3000 gdk_window_fullscreen (GdkWindow *window)
3001 {
3002   gint width, height;
3003   FullscreenInfo *fi;
3004   GdkWindowObject *private = (GdkWindowObject *) window;
3005
3006   g_return_if_fail (GDK_IS_WINDOW (window));
3007
3008   fi = g_new (FullscreenInfo, 1);
3009
3010   if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3011     g_free (fi);
3012   else
3013     {
3014       GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3015
3016       width = GetSystemMetrics (SM_CXSCREEN);
3017       height = GetSystemMetrics (SM_CYSCREEN);
3018  
3019       /* remember for restoring */
3020       fi->hint_flags = impl->hint_flags;
3021       impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3022       g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3023       fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3024
3025       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, 
3026                      (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3027       if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP /*not MOST, taskswitch!*/,
3028                          0, 0, width, height,
3029                          SWP_NOCOPYBITS | SWP_SHOWWINDOW))
3030         WIN32_API_FAILED ("SetWindowPos");
3031
3032       gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3033     }
3034 }
3035
3036 void
3037 gdk_window_unfullscreen (GdkWindow *window)
3038 {
3039   FullscreenInfo *fi;
3040   GdkWindowObject *private = (GdkWindowObject *) window;
3041
3042   g_return_if_fail (GDK_IS_WINDOW (window));
3043
3044   fi = g_object_get_data (G_OBJECT(window), "fullscreen-info");
3045   if (fi)
3046     {
3047       GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3048
3049       impl->hint_flags = fi->hint_flags;
3050       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3051       if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3052                          fi->r.left, fi->r.top, fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3053                          SWP_NOCOPYBITS | SWP_SHOWWINDOW))
3054          WIN32_API_FAILED ("SetWindowPos");
3055
3056       g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3057       g_free (fi);
3058
3059       gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3060     }
3061 }
3062
3063 void
3064 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
3065 {
3066   g_return_if_fail (GDK_IS_WINDOW (window));
3067
3068   if (GDK_WINDOW_DESTROYED (window))
3069     return;
3070
3071   if (GDK_WINDOW_IS_MAPPED (window))
3072     {
3073       if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3074                         0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE))
3075          WIN32_API_FAILED ("SetWindowPos");
3076     }
3077   else
3078     gdk_synthesize_window_state (window,
3079                                  setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3080                                  setting ? GDK_WINDOW_STATE_ABOVE : 0);
3081 }
3082
3083 void
3084 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
3085 {
3086   g_return_if_fail (GDK_IS_WINDOW (window));
3087
3088   if (GDK_WINDOW_DESTROYED (window))
3089     return;
3090
3091   if (GDK_WINDOW_IS_MAPPED (window))
3092     {
3093       if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3094                         0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE))
3095          WIN32_API_FAILED ("SetWindowPos");
3096     }
3097   else
3098     gdk_synthesize_window_state (window,
3099                                  setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3100                                  setting ? GDK_WINDOW_STATE_BELOW : 0);
3101 }
3102
3103 void
3104 gdk_window_focus (GdkWindow *window,
3105                   guint32    timestamp)
3106 {
3107   g_return_if_fail (GDK_IS_WINDOW (window));
3108
3109   if (GDK_WINDOW_DESTROYED (window))
3110     return;
3111   
3112   GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3113                            GDK_WINDOW_HWND (window),
3114                            _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3115
3116   if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3117     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3118   else
3119     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3120   SetFocus (GDK_WINDOW_HWND (window));
3121 }
3122
3123 void
3124 gdk_window_set_modal_hint (GdkWindow *window,
3125                            gboolean   modal)
3126 {
3127   GdkWindowObject *private;
3128
3129   g_return_if_fail (window != NULL);
3130   g_return_if_fail (GDK_IS_WINDOW (window));
3131   
3132   if (GDK_WINDOW_DESTROYED (window))
3133     return;
3134
3135   private = (GdkWindowObject*) window;
3136
3137   private->modal_hint = modal;
3138
3139   if (GDK_WINDOW_IS_MAPPED (window))
3140     API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
3141                              modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3142                              0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE));
3143 }
3144
3145 void
3146 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3147                                   gboolean   skips_taskbar)
3148 {
3149   static GdkWindow *owner = NULL;
3150   GdkWindowAttr wa;
3151
3152   g_return_if_fail (GDK_IS_WINDOW (window));
3153
3154   GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s\n",
3155                            GDK_WINDOW_HWND (window),
3156                            skips_taskbar ? "TRUE" : "FALSE"));
3157
3158   if (skips_taskbar)
3159     {
3160       if (owner == NULL)
3161         {
3162           wa.window_type = GDK_WINDOW_TEMP;
3163           wa.wclass = GDK_INPUT_OUTPUT;
3164           wa.width = wa.height = 1;
3165           wa.event_mask = 0;
3166           owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3167         }
3168
3169       SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT,
3170                      (long) GDK_WINDOW_HWND (owner));
3171
3172 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3173       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3174                      GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3175       SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
3176                     SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3177                     SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3178 #endif
3179     }
3180   else
3181     {
3182       SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT, 0);
3183     }
3184 }
3185
3186 void
3187 gdk_window_set_skip_pager_hint (GdkWindow *window,
3188                                 gboolean   skips_pager)
3189 {
3190   g_return_if_fail (GDK_IS_WINDOW (window));
3191 }
3192
3193 void
3194 gdk_window_set_type_hint (GdkWindow        *window,
3195                           GdkWindowTypeHint hint)
3196 {
3197   g_return_if_fail (window != NULL);
3198   g_return_if_fail (GDK_IS_WINDOW (window));
3199   
3200   if (GDK_WINDOW_DESTROYED (window))
3201     return;
3202
3203   GDK_NOTE (MISC, g_print ("gdk_window_set_type_hint: %p: %d\n",
3204                            GDK_WINDOW_HWND (window), hint));
3205   switch (hint)
3206     {
3207     case GDK_WINDOW_TYPE_HINT_DIALOG:
3208       break;
3209     case GDK_WINDOW_TYPE_HINT_MENU:
3210       gdk_window_set_decorations (window,
3211                                   GDK_DECOR_ALL |
3212                                   GDK_DECOR_RESIZEH |
3213                                   GDK_DECOR_MINIMIZE |
3214                                   GDK_DECOR_MAXIMIZE);
3215       break;
3216     case GDK_WINDOW_TYPE_HINT_TOOLBAR:
3217       gdk_window_set_skip_taskbar_hint (window, TRUE);
3218       break;
3219     case GDK_WINDOW_TYPE_HINT_UTILITY:
3220       break;
3221     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
3222       gdk_window_set_decorations (window,
3223                                   GDK_DECOR_ALL |
3224                                   GDK_DECOR_RESIZEH |
3225                                   GDK_DECOR_MENU |
3226                                   GDK_DECOR_MINIMIZE |
3227                                   GDK_DECOR_MAXIMIZE);
3228       break;
3229     case GDK_WINDOW_TYPE_HINT_DOCK:
3230       break;
3231     case GDK_WINDOW_TYPE_HINT_DESKTOP:
3232       break;
3233     default:
3234       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
3235       /* Fall thru */
3236     case GDK_WINDOW_TYPE_HINT_NORMAL:
3237       break;
3238     }
3239 }
3240
3241 void
3242 gdk_window_shape_combine_region (GdkWindow *window,
3243                                  GdkRegion *shape_region,
3244                                  gint       offset_x,
3245                                  gint       offset_y)
3246 {
3247   g_return_if_fail (GDK_IS_WINDOW (window));
3248
3249   if (GDK_WINDOW_DESTROYED (window))
3250     return;
3251
3252   /* XXX: even on X implemented conditional ... */  
3253 }
3254
3255 GdkWindow *
3256 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
3257 {
3258   g_return_val_if_fail (display == gdk_display_get_default(), NULL);
3259
3260   return gdk_window_lookup (anid);
3261 }
3262
3263 void
3264 gdk_window_enable_synchronized_configure (GdkWindow *window)
3265 {
3266 }
3267
3268 void
3269 gdk_window_configure_finished (GdkWindow *window)
3270 {
3271 }