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