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