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