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