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