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