1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 Tor Lillqvist
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.
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.
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.
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/.
30 #include "gdkevents.h"
31 #include "gdkpixmap.h"
32 #include "gdkwindow.h"
33 #include "gdkinternals.h"
34 #include "gdkprivate-win32.h"
36 static gboolean gdk_window_gravity_works (void);
37 static void gdk_window_set_static_win_gravity (GdkWindow *window,
40 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
41 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
43 static void gdk_window_impl_win32_get_size (GdkDrawable *drawable,
46 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
47 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
48 static void gdk_window_impl_win32_finalize (GObject *object);
50 static gpointer parent_class = NULL;
53 gdk_window_impl_win32_get_type (void)
55 static GType object_type = 0;
59 static const GTypeInfo object_info =
61 sizeof (GdkWindowImplWin32Class),
63 (GBaseFinalizeFunc) NULL,
64 (GClassInitFunc) gdk_window_impl_win32_class_init,
65 NULL, /* class_finalize */
66 NULL, /* class_data */
67 sizeof (GdkWindowImplWin32),
69 (GInstanceInitFunc) gdk_window_impl_win32_init,
72 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
81 _gdk_window_impl_get_type (void)
83 return gdk_window_impl_win32_get_type ();
87 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
95 impl->extension_events_selected = FALSE;
96 impl->input_locale = GetKeyboardLayout (0);
97 TranslateCharsetInfo ((DWORD FAR *) GetACP (), &impl->charset_info,
102 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
104 GObjectClass *object_class = G_OBJECT_CLASS (klass);
105 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
107 parent_class = g_type_class_peek_parent (klass);
109 object_class->finalize = gdk_window_impl_win32_finalize;
111 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
112 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
113 drawable_class->get_size = gdk_window_impl_win32_get_size;
117 gdk_window_impl_win32_finalize (GObject *object)
119 GdkWindowObject *wrapper;
120 GdkDrawableImplWin32 *draw_impl;
121 GdkWindowImplWin32 *window_impl;
123 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
125 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
126 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
128 wrapper = (GdkWindowObject*) draw_impl->wrapper;
130 if (!GDK_WINDOW_DESTROYED (wrapper))
132 gdk_win32_handle_table_remove (draw_impl->handle);
135 if (window_impl->hcursor != NULL)
137 DestroyCursor (window_impl->hcursor);
138 window_impl->hcursor = NULL;
141 G_OBJECT_CLASS (parent_class)->finalize (object);
145 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
147 GdkDrawableImplWin32 *drawable_impl;
148 GdkWindowImplWin32 *window_impl;
150 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
152 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
153 window_impl = GDK_WINDOW_IMPL_WIN32 (drawable);
155 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
156 drawable_impl->colormap == NULL)
158 drawable_impl->colormap = gdk_colormap_get_system ();
161 return drawable_impl->colormap;
165 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
168 GdkWindowImplWin32 *impl;
169 GdkDrawableImplWin32 *draw_impl;
171 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
172 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
174 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
175 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
177 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
184 gdk_window_impl_win32_get_size (GdkDrawable *drawable,
188 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
191 *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
193 *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
197 _gdk_windowing_window_init (void)
199 GdkWindowObject *private;
200 GdkWindowImplWin32 *impl;
201 GdkDrawableImplWin32 *draw_impl;
206 g_assert (gdk_parent_root == NULL);
208 SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
209 width = rect.right - rect.left;
210 height = rect.bottom - rect.top;
212 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
213 private = (GdkWindowObject *)gdk_parent_root;
214 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
215 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
217 draw_impl->handle = gdk_root_window;
218 draw_impl->wrapper = GDK_DRAWABLE (private);
220 private->window_type = GDK_WINDOW_ROOT;
221 private->depth = gdk_visual_get_system ()->depth;
223 impl->height = height;
225 gdk_win32_handle_table_insert (&gdk_root_window, gdk_parent_root);
228 /* The Win API function AdjustWindowRect may return negative values
229 * resulting in obscured title bars. This helper function is coreccting it.
232 SafeAdjustWindowRectEx (RECT* lpRect,
237 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
239 WIN32_API_FAILED ("AdjustWindowRectEx");
242 if (lpRect->left < 0)
244 lpRect->right -= lpRect->left;
249 lpRect->bottom -= lpRect->top;
256 * is a wrapper function for RegisterWindowClassEx.
257 * It creates at least one unique class for every
258 * GdkWindowType. If support for single window-specific icons
259 * is ever needed (e.g Dialog specific), every such window should
263 RegisterGdkClass (GdkWindowType wtype)
265 static ATOM klassTOPLEVEL = 0;
266 static ATOM klassDIALOG = 0;
267 static ATOM klassCHILD = 0;
268 static ATOM klassTEMP = 0;
269 static HICON hAppIcon = NULL;
270 static WNDCLASSEX wcl;
273 wcl.cbSize = sizeof(WNDCLASSEX);
274 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
275 * on WM_SIZE and WM_MOVE. Flicker, Performance!
277 wcl.lpfnWndProc = gdk_window_procedure;
280 wcl.hInstance = gdk_app_hmodule;
282 /* initialize once! */
285 gchar sLoc [_MAX_PATH+1];
287 if (0 != GetModuleFileName (gdk_app_hmodule, sLoc, _MAX_PATH))
289 hAppIcon = ExtractIcon (gdk_app_hmodule, sLoc, 0);
292 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
294 hAppIcon = ExtractIcon (gdk_app_hmodule, gdklibname, 0);
299 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
303 wcl.lpszMenuName = NULL;
306 /* initialize once per class */
307 #define ONCE_PER_CLASS() \
308 wcl.hIcon = CopyIcon (hAppIcon); \
309 wcl.hIconSm = CopyIcon (hAppIcon); \
310 wcl.hbrBackground = CreateSolidBrush (RGB (0,0,0)); \
311 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
315 case GDK_WINDOW_TOPLEVEL:
316 if (0 == klassTOPLEVEL)
318 wcl.lpszClassName = "gdkWindowToplevel";
321 klassTOPLEVEL = RegisterClassEx (&wcl);
323 klass = klassTOPLEVEL;
326 case GDK_WINDOW_CHILD:
329 wcl.lpszClassName = "gdkWindowChild";
331 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
333 klassCHILD = RegisterClassEx (&wcl);
338 case GDK_WINDOW_DIALOG:
339 if (0 == klassDIALOG)
341 wcl.lpszClassName = "gdkWindowDialog";
342 wcl.style |= CS_SAVEBITS;
344 klassDIALOG = RegisterClassEx (&wcl);
349 case GDK_WINDOW_TEMP:
352 wcl.lpszClassName = "gdkWindowTemp";
353 wcl.style |= CS_SAVEBITS;
355 klassTEMP = RegisterClassEx (&wcl);
361 g_assert_not_reached ();
367 WIN32_API_FAILED ("RegisterClassEx");
368 g_error ("That is a fatal error");
374 gdk_window_new (GdkWindow *parent,
375 GdkWindowAttr *attributes,
376 gint attributes_mask)
379 GdkWindowObject *private;
380 GdkWindowObject *parent_private;
381 GdkWindowImplWin32 *impl;
382 GdkDrawableImplWin32 *draw_impl;
388 DWORD dwStyle, dwExStyle;
400 g_return_val_if_fail (attributes != NULL, NULL);
403 parent = gdk_parent_root;
405 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
407 parent_private = (GdkWindowObject*) parent;
408 if (GDK_WINDOW_DESTROYED (parent))
411 hparent = GDK_WINDOW_HWND (parent);
413 window = g_object_new (GDK_TYPE_WINDOW, NULL);
414 private = (GdkWindowObject *)window;
415 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
416 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
417 draw_impl->wrapper = GDK_DRAWABLE (window);
419 private->parent = (GdkWindowObject *)parent;
421 if (attributes_mask & GDK_WA_X)
426 if (attributes_mask & GDK_WA_Y)
428 else if (attributes_mask & GDK_WA_X)
429 y = 100; /* ??? We must put it somewhere... */
431 y = 0; /* x is CW_USEDEFAULT, y doesn't matter then */
435 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
436 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
437 impl->extension_events_selected = FALSE;
438 private->window_type = attributes->window_type;
440 _gdk_window_init_position (GDK_WINDOW (private));
441 if (impl->position_info.big)
442 private->guffaw_gravity = TRUE;
444 if (attributes_mask & GDK_WA_VISUAL)
445 visual = attributes->visual;
447 visual = gdk_visual_get_system ();
448 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
450 if (attributes_mask & GDK_WA_TITLE)
451 title = attributes->title;
453 title = g_get_prgname ();
455 title = "GDK client window";
457 impl->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
459 if (parent_private && parent_private->guffaw_gravity)
464 if (attributes->wclass == GDK_INPUT_OUTPUT)
468 private->input_only = FALSE;
469 private->depth = visual->depth;
471 if (attributes_mask & GDK_WA_COLORMAP)
473 draw_impl->colormap = attributes->colormap;
474 gdk_colormap_ref (attributes->colormap);
478 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
480 draw_impl->colormap =
481 gdk_colormap_get_system ();
482 gdk_colormap_ref (draw_impl->colormap);
486 draw_impl->colormap =
487 gdk_colormap_new (visual, FALSE);
493 dwExStyle = WS_EX_TRANSPARENT;
495 private->input_only = TRUE;
496 draw_impl->colormap = NULL;
500 parent_private->children = g_list_prepend (parent_private->children, window);
502 switch (private->window_type)
504 case GDK_WINDOW_TOPLEVEL:
505 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
506 hparent = gdk_root_window;
509 case GDK_WINDOW_CHILD:
510 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
513 case GDK_WINDOW_DIALOG:
514 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
516 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
518 hparent = gdk_root_window;
521 case GDK_WINDOW_TEMP:
522 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
523 dwExStyle |= WS_EX_TOOLWINDOW;
526 case GDK_WINDOW_ROOT:
527 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
531 klass = RegisterGdkClass (private->window_type);
533 if (private->window_type != GDK_WINDOW_CHILD)
535 if (x == CW_USEDEFAULT)
546 rect.right = rect.left + impl->width;
547 rect.bottom = rect.top + impl->height;
549 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
551 if (x != CW_USEDEFAULT)
556 width = rect.right - rect.left;
557 height = rect.bottom - rect.top;
562 height = impl->height;
565 titlelen = strlen (title);
566 wctitle = g_new (wchar_t, titlelen + 1);
567 mbtitle = g_new (char, 3*titlelen + 1);
568 wlen = gdk_nmbstowchar_ts (wctitle, title, titlelen, titlelen);
570 WideCharToMultiByte (GetACP (), 0, wctitle, -1,
571 mbtitle, 3*titlelen, NULL, NULL);
573 #ifdef WITHOUT_WM_CREATE
574 draw_impl->handle = CreateWindowEx (dwExStyle,
575 MAKEINTRESOURCE(klass),
587 CreateWindowEx (dwExStyle,
588 MAKEINTRESOURCE(klass),
597 if (GDK_WINDOW_HWND (window) != hwndNew)
599 g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%#x, %#x) HWND mismatch.",
600 GDK_WINDOW_HWND (window), hwndNew);
602 /* HB: IHMO due to a race condition the handle was increased by
603 * one, which causes much trouble. Because I can't find the
604 * real bug, try to workaround it ...
605 * To reproduce: compile with MSVC 5, DEBUG=1
608 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
609 GDK_WINDOW_HWND (window) = hwndNew;
610 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
612 /* the old behaviour, but with warning */
613 GDK_WINDOW_HWND (window) = hwndNew;
618 gdk_drawable_ref (window);
619 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
623 g_print ("gdk_window_new: %s %s %dx%d@+%d+%d %#x = %#x\n"
624 "...locale %#x codepage %d\n",
625 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
626 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
627 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
628 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
631 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
633 GDK_WINDOW_HWND (window),
635 impl->charset_info.ciACP));
640 if (draw_impl->handle == NULL)
642 WIN32_API_FAILED ("CreateWindowEx");
643 g_object_unref ((GObject *) window);
647 #ifdef WITHOUT_WM_CREATE
648 gdk_drawable_ref (window);
649 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
652 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
653 (attributes->cursor) :
660 gdk_window_foreign_new (GdkNativeWindow anid)
663 GdkWindowObject *private;
664 GdkWindowObject *parent_private;
665 GdkWindowImplWin32 *impl;
666 GdkDrawableImplWin32 *draw_impl;
672 window = g_object_new (GDK_TYPE_WINDOW, NULL);
673 private = (GdkWindowObject *)window;
674 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
675 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
676 draw_impl->wrapper = GDK_DRAWABLE (window);
678 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
680 parent_private = (GdkWindowObject *)private->parent;
683 parent_private->children = g_list_prepend (parent_private->children, window);
685 draw_impl->handle = (HWND) anid;
686 GetClientRect ((HWND) anid, &rect);
688 point.y = rect.right;
689 ClientToScreen ((HWND) anid, &point);
690 if (parent != gdk_root_window)
691 ScreenToClient (parent, &point);
692 private->x = point.x;
693 private->y = point.y;
694 impl->width = rect.right - rect.left;
695 impl->height = rect.bottom - rect.top;
696 private->window_type = GDK_WINDOW_FOREIGN;
697 private->destroyed = FALSE;
698 private->mapped = IsWindowVisible ((HWND) anid);
699 private->depth = gdk_visual_get_system ()->depth;
701 gdk_drawable_ref (window);
702 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
708 _gdk_windowing_window_destroy (GdkWindow *window,
710 gboolean foreign_destroy)
712 GdkWindowObject *private = (GdkWindowObject *)window;
714 g_return_if_fail (GDK_IS_WINDOW (window));
716 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %#x\n",
717 GDK_WINDOW_HWND (window)));
719 if (private->extension_events != 0)
720 gdk_input_window_destroy (window);
722 if (private->window_type == GDK_WINDOW_FOREIGN)
724 if (!foreign_destroy && (private->parent != NULL))
726 /* It's somebody else's window, but in our hierarchy,
727 * so reparent it to the root window, and then call
728 * DestroyWindow() on it.
730 gdk_window_hide (window);
731 gdk_window_reparent (window, NULL, 0, 0);
733 /* Is this too drastic? Many (most?) applications
734 * quit if any window receives WM_QUIT I think.
735 * OTOH, I don't think foreign windows are much
736 * used, so the question is maybe academic.
738 PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
741 else if (!recursing && !foreign_destroy)
742 DestroyWindow (GDK_WINDOW_HWND (window));
745 /* This function is called when the window really gone.
748 gdk_window_destroy_notify (GdkWindow *window)
750 g_return_if_fail (window != NULL);
753 g_print ("gdk_window_destroy_notify: %#x %s\n",
754 GDK_WINDOW_HWND (window),
755 (GDK_WINDOW_DESTROYED (window) ? "(destroyed)" : "")));
757 if (!GDK_WINDOW_DESTROYED (window))
759 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
760 g_warning ("window %#x unexpectedly destroyed",
761 GDK_WINDOW_HWND (window));
763 _gdk_window_destroy (window, TRUE);
766 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
767 gdk_drawable_unref (window);
771 gdk_window_show (GdkWindow *window)
773 GdkWindowObject *private;
775 g_return_if_fail (GDK_IS_WINDOW (window));
777 private = (GdkWindowObject*) window;
778 if (!private->destroyed)
780 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
781 GDK_WINDOW_HWND (window)));
783 private->mapped = TRUE;
784 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
786 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
787 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
788 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
790 /* Don't put on toolbar */
791 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
796 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
797 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
798 SetForegroundWindow (GDK_WINDOW_HWND (window));
799 BringWindowToTop (GDK_WINDOW_HWND (window));
801 ShowOwnedPopups (GDK_WINDOW_HWND (window), TRUE);
808 gdk_window_hide (GdkWindow *window)
810 GdkWindowObject *private;
812 g_return_if_fail (window != NULL);
814 private = (GdkWindowObject*) window;
815 if (!private->destroyed)
817 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
818 GDK_WINDOW_HWND (window)));
820 private->mapped = FALSE;
821 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
822 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
824 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
829 gdk_window_withdraw (GdkWindow *window)
831 GdkWindowObject *private;
833 g_return_if_fail (window != NULL);
835 private = (GdkWindowObject*) window;
836 if (!private->destroyed)
838 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
839 GDK_WINDOW_HWND (window)));
841 gdk_window_hide (window); /* ??? */
846 gdk_window_move (GdkWindow *window,
850 GdkWindowObject *private = (GdkWindowObject *)window;
851 GdkWindowImplWin32 *impl;
853 g_return_if_fail (window != NULL);
854 g_return_if_fail (GDK_IS_WINDOW (window));
856 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
858 gdk_window_move_resize (window, x, y, impl->width, impl->height);
862 gdk_window_resize (GdkWindow *window,
866 GdkWindowObject *private = (GdkWindowObject*) window;
867 GdkWindowImplWin32 *impl;
870 g_return_if_fail (window != NULL);
871 g_return_if_fail (GDK_IS_WINDOW (window));
878 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
880 if (!private->destroyed)
882 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
883 GDK_WINDOW_HWND (window), width, height));
885 if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
894 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
897 rect.right = pt.x + width;
898 rect.bottom = pt.y + height;
900 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
901 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
902 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
903 WIN32_API_FAILED ("AdjustWindowRectEx");
907 width = rect.right - rect.left;
908 height = rect.bottom - rect.top;
915 impl->height = height;
918 private->resize_count += 1;
921 g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
922 GDK_WINDOW_HWND (window), width, height, x, y));
923 if (!MoveWindow (GDK_WINDOW_HWND (window), x, y, width, height, TRUE))
924 WIN32_API_FAILED ("MoveWindow");
929 gdk_window_move_resize (GdkWindow *window,
935 GdkWindowObject *private = (GdkWindowObject*) window;
936 GdkWindowImplWin32 *impl;
938 g_return_if_fail (window != NULL);
939 g_return_if_fail (GDK_IS_WINDOW (window));
946 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
948 if (!private->destroyed)
954 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
955 GDK_WINDOW_HWND (window), width, height, x, y));
957 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
958 _gdk_window_move_resize_child (window, x, y, width, height);
963 rect.right = x + width;
964 rect.bottom = y + height;
966 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
967 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
968 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
969 WIN32_API_FAILED ("AdjustWindowRectEx");
971 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
972 GDK_WINDOW_HWND (window),
973 rect.right - rect.left, rect.bottom - rect.top,
974 rect.left, rect.top));
975 if (!MoveWindow (GDK_WINDOW_HWND (window),
977 rect.right - rect.left, rect.bottom - rect.top,
979 WIN32_API_FAILED ("MoveWindow");
985 gdk_window_reparent (GdkWindow *window,
986 GdkWindow *new_parent,
990 GdkWindowObject *window_private;
991 GdkWindowObject *parent_private;
992 GdkWindowObject *old_parent_private;
993 GdkWindowImplWin32 *impl;
995 g_return_if_fail (window != NULL);
998 new_parent = gdk_parent_root;
1000 window_private = (GdkWindowObject*) window;
1001 old_parent_private = (GdkWindowObject *) window_private->parent;
1002 parent_private = (GdkWindowObject*) new_parent;
1003 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1005 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1007 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1008 GDK_WINDOW_HWND (window),
1009 GDK_WINDOW_HWND (new_parent)));
1010 if (!SetParent (GDK_WINDOW_HWND (window),
1011 GDK_WINDOW_HWND (new_parent)))
1012 WIN32_API_FAILED ("SetParent");
1014 if (!MoveWindow (GDK_WINDOW_HWND (window),
1015 x, y, impl->width, impl->height, TRUE))
1016 WIN32_API_FAILED ("MoveWindow");
1019 window_private->parent = (GdkWindowObject *)new_parent;
1021 if (old_parent_private)
1022 old_parent_private->children =
1023 g_list_remove (old_parent_private->children, window);
1025 if ((old_parent_private &&
1026 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1027 (!old_parent_private && parent_private->guffaw_gravity))
1028 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1030 parent_private->children = g_list_prepend (parent_private->children, window);
1034 _gdk_windowing_window_clear_area (GdkWindow *window,
1040 GdkWindowImplWin32 *impl;
1042 g_return_if_fail (window != NULL);
1043 g_return_if_fail (GDK_IS_WINDOW (window));
1045 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1047 if (!GDK_WINDOW_DESTROYED (window))
1052 width = impl->width - x;
1054 height = impl->height - y;
1055 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: "
1056 "%#x %dx%d@+%d+%d\n",
1057 GDK_WINDOW_HWND (window), width, height, x, y));
1058 hdc = GetDC (GDK_WINDOW_HWND (window));
1059 IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
1060 SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1061 ReleaseDC (GDK_WINDOW_HWND (window), hdc);
1066 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1072 g_return_if_fail (window != NULL);
1073 g_return_if_fail (GDK_IS_WINDOW (window));
1075 if (!GDK_WINDOW_DESTROYED (window))
1079 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: "
1080 "%#x %dx%d@+%d+%d\n",
1081 GDK_WINDOW_HWND (window), width, height, x, y));
1084 rect.right = x + width + 1;
1086 rect.bottom = y + height + 1;
1087 if (!InvalidateRect (GDK_WINDOW_HWND (window), &rect, TRUE))
1088 WIN32_GDI_FAILED ("InvalidateRect");
1089 UpdateWindow (GDK_WINDOW_HWND (window));
1094 gdk_window_raise (GdkWindow *window)
1096 g_return_if_fail (window != NULL);
1097 g_return_if_fail (GDK_IS_WINDOW (window));
1099 if (!GDK_WINDOW_DESTROYED (window))
1101 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
1102 GDK_WINDOW_HWND (window)));
1104 if (!BringWindowToTop (GDK_WINDOW_HWND (window)))
1105 WIN32_API_FAILED ("BringWindowToTop");
1110 gdk_window_lower (GdkWindow *window)
1112 g_return_if_fail (window != NULL);
1113 g_return_if_fail (GDK_IS_WINDOW (window));
1115 if (!GDK_WINDOW_DESTROYED (window))
1117 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1118 GDK_WINDOW_HWND (window)));
1120 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1121 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1122 WIN32_API_FAILED ("SetWindowPos");
1127 gdk_window_set_hints (GdkWindow *window,
1136 GdkWindowImplWin32 *impl;
1137 WINDOWPLACEMENT size_hints;
1143 g_return_if_fail (window != NULL);
1144 g_return_if_fail (GDK_IS_WINDOW (window));
1146 if (GDK_WINDOW_DESTROYED (window))
1149 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1151 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1152 GDK_WINDOW_HWND (window),
1153 min_width, min_height, max_width, max_height,
1156 impl->hint_flags = flags;
1157 size_hints.length = sizeof (size_hints);
1161 if (flags & GDK_HINT_POS)
1162 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1163 WIN32_API_FAILED ("GetWindowPlacement");
1166 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1167 " (%d,%d)--(%d,%d)\n",
1168 size_hints.rcNormalPosition.left,
1169 size_hints.rcNormalPosition.top,
1170 size_hints.rcNormalPosition.right,
1171 size_hints.rcNormalPosition.bottom));
1172 /* What are the corresponding window coordinates for client
1173 * area coordinates x, y
1177 rect.right = rect.left + 200; /* dummy */
1178 rect.bottom = rect.top + 200;
1179 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1180 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1181 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1182 size_hints.flags = 0;
1183 size_hints.showCmd = SW_SHOWNA;
1185 /* Set the normal position hint to that location, with unchanged
1188 diff = size_hints.rcNormalPosition.left - rect.left;
1189 size_hints.rcNormalPosition.left = rect.left;
1190 size_hints.rcNormalPosition.right -= diff;
1191 diff = size_hints.rcNormalPosition.top - rect.top;
1192 size_hints.rcNormalPosition.top = rect.top;
1193 size_hints.rcNormalPosition.bottom -= diff;
1194 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1195 size_hints.rcNormalPosition.left,
1196 size_hints.rcNormalPosition.top,
1197 size_hints.rcNormalPosition.right,
1198 size_hints.rcNormalPosition.bottom));
1199 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1200 WIN32_API_FAILED ("SetWindowPlacement");
1201 impl->hint_x = rect.left;
1202 impl->hint_y = rect.top;
1205 if (flags & GDK_HINT_MIN_SIZE)
1209 rect.right = min_width;
1210 rect.bottom = min_height;
1211 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1212 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1213 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1214 impl->hint_min_width = rect.right - rect.left;
1215 impl->hint_min_height = rect.bottom - rect.top;
1217 /* Also chek if he current size of the window is in bounds. */
1218 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1219 if (rect.right < min_width && rect.bottom < min_height)
1220 gdk_window_resize (window, min_width, min_height);
1221 else if (rect.right < min_width)
1222 gdk_window_resize (window, min_width, rect.bottom);
1223 else if (rect.bottom < min_height)
1224 gdk_window_resize (window, rect.right, min_height);
1227 if (flags & GDK_HINT_MAX_SIZE)
1231 rect.right = max_width;
1232 rect.bottom = max_height;
1233 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1234 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1235 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1236 impl->hint_max_width = rect.right - rect.left;
1237 impl->hint_max_height = rect.bottom - rect.top;
1238 /* Again, check if the window is too large currently. */
1239 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1240 if (rect.right > max_width && rect.bottom > max_height)
1241 gdk_window_resize (window, max_width, max_height);
1242 else if (rect.right > max_width)
1243 gdk_window_resize (window, max_width, rect.bottom);
1244 else if (rect.bottom > max_height)
1245 gdk_window_resize (window, rect.right, max_height);
1251 gdk_window_set_geometry_hints (GdkWindow *window,
1252 GdkGeometry *geometry,
1253 GdkWindowHints geom_mask)
1255 GdkWindowImplWin32 *impl;
1256 WINDOWPLACEMENT size_hints;
1262 g_return_if_fail (window != NULL);
1263 g_return_if_fail (GDK_IS_WINDOW (window));
1265 if (GDK_WINDOW_DESTROYED (window))
1268 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1269 size_hints.length = sizeof (size_hints);
1271 impl->hint_flags = geom_mask;
1273 if (geom_mask & GDK_HINT_POS)
1276 if (geom_mask & GDK_HINT_MIN_SIZE)
1280 rect.right = geometry->min_width;
1281 rect.bottom = geometry->min_height;
1282 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1283 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1284 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1285 impl->hint_min_width = rect.right - rect.left;
1286 impl->hint_min_height = rect.bottom - rect.top;
1288 /* Also check if he current size of the window is in bounds */
1289 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1290 if (rect.right < geometry->min_width
1291 && rect.bottom < geometry->min_height)
1292 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1293 else if (rect.right < geometry->min_width)
1294 gdk_window_resize (window, geometry->min_width, rect.bottom);
1295 else if (rect.bottom < geometry->min_height)
1296 gdk_window_resize (window, rect.right, geometry->min_height);
1299 if (geom_mask & GDK_HINT_MAX_SIZE)
1303 rect.right = geometry->max_width;
1304 rect.bottom = geometry->max_height;
1305 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1306 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1307 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1308 impl->hint_max_width = rect.right - rect.left;
1309 impl->hint_max_height = rect.bottom - rect.top;
1311 /* Again, check if the window is too large currently. */
1312 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1313 if (rect.right > geometry->max_width
1314 && rect.bottom > geometry->max_height)
1315 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1316 else if (rect.right > geometry->max_width)
1317 gdk_window_resize (window, geometry->max_width, rect.bottom);
1318 else if (rect.bottom > geometry->max_height)
1319 gdk_window_resize (window, rect.right, geometry->max_height);
1322 /* I don't know what to do when called with zero base_width and height. */
1323 if (geom_mask & GDK_HINT_BASE_SIZE
1324 && geometry->base_width > 0
1325 && geometry->base_height > 0)
1326 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1327 WIN32_API_FAILED ("GetWindowPlacement");
1330 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1331 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1332 size_hints.rcNormalPosition.left,
1333 size_hints.rcNormalPosition.top,
1334 size_hints.rcNormalPosition.right,
1335 size_hints.rcNormalPosition.bottom));
1336 size_hints.rcNormalPosition.right =
1337 size_hints.rcNormalPosition.left + geometry->base_width;
1338 size_hints.rcNormalPosition.bottom =
1339 size_hints.rcNormalPosition.top + geometry->base_height;
1340 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1341 size_hints.rcNormalPosition.left,
1342 size_hints.rcNormalPosition.top,
1343 size_hints.rcNormalPosition.right,
1344 size_hints.rcNormalPosition.bottom));
1345 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1346 WIN32_API_FAILED ("SetWindowPlacement");
1349 if (geom_mask & GDK_HINT_RESIZE_INC)
1354 if (geom_mask & GDK_HINT_ASPECT)
1361 gdk_window_set_title (GdkWindow *window,
1369 g_return_if_fail (window != NULL);
1370 g_return_if_fail (GDK_IS_WINDOW (window));
1371 g_return_if_fail (title != NULL);
1373 /* Empty window titles not allowed, so set it to just a period. */
1377 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1378 GDK_WINDOW_HWND (window), title));
1380 if (!GDK_WINDOW_DESTROYED (window))
1382 /* As the title is in UTF-8 we must translate it
1383 * to the system codepage.
1385 titlelen = strlen (title);
1386 wcstr = g_new (wchar_t, titlelen + 1);
1387 mbstr = g_new (char, 3*titlelen + 1);
1388 wlen = gdk_nmbstowchar_ts (wcstr, title, titlelen, titlelen);
1390 WideCharToMultiByte (GetACP (), 0, wcstr, -1,
1391 mbstr, 3*titlelen, NULL, NULL);
1393 if (!SetWindowText (GDK_WINDOW_HWND (window), mbstr))
1394 WIN32_API_FAILED ("SetWindowText");
1402 gdk_window_set_role (GdkWindow *window,
1405 g_return_if_fail (window != NULL);
1406 g_return_if_fail (GDK_IS_WINDOW (window));
1408 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1409 GDK_WINDOW_HWND (window), (role ? role : "NULL")));
1414 gdk_window_set_transient_for (GdkWindow *window,
1417 g_return_if_fail (window != NULL);
1418 g_return_if_fail (GDK_IS_WINDOW (window));
1420 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1421 GDK_WINDOW_HWND (window),
1422 GDK_WINDOW_HWND (parent)));
1427 gdk_window_set_background (GdkWindow *window,
1430 GdkWindowObject *private = (GdkWindowObject *)window;
1432 g_return_if_fail (window != NULL);
1433 g_return_if_fail (GDK_IS_WINDOW (window));
1435 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1436 GDK_WINDOW_HWND (window),
1437 gdk_win32_color_to_string (color)));
1439 private->bg_color = *color;
1441 if (private->bg_pixmap &&
1442 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1443 private->bg_pixmap != GDK_NO_BG)
1445 gdk_drawable_unref (private->bg_pixmap);
1446 private->bg_pixmap = NULL;
1451 gdk_window_set_back_pixmap (GdkWindow *window,
1453 gint parent_relative)
1455 GdkWindowObject *private = (GdkWindowObject *)window;
1457 g_return_if_fail (window != NULL);
1458 g_return_if_fail (GDK_IS_WINDOW (window));
1459 g_return_if_fail (pixmap == NULL || !parent_relative);
1461 if (private->bg_pixmap &&
1462 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1463 private->bg_pixmap != GDK_NO_BG)
1464 gdk_drawable_unref (private->bg_pixmap);
1466 if (parent_relative)
1468 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1474 gdk_drawable_ref (pixmap);
1475 private->bg_pixmap = pixmap;
1479 private->bg_pixmap = GDK_NO_BG;
1485 gdk_window_set_cursor (GdkWindow *window,
1488 GdkWindowImplWin32 *impl;
1489 GdkCursorPrivate *cursor_private;
1493 g_return_if_fail (window != NULL);
1494 g_return_if_fail (GDK_IS_WINDOW (window));
1496 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1497 cursor_private = (GdkCursorPrivate*) cursor;
1499 if (!GDK_WINDOW_DESTROYED (window))
1504 hcursor = cursor_private->hcursor;
1506 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1507 GDK_WINDOW_HWND (window), hcursor));
1508 if (impl->hcursor != NULL)
1510 GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n", impl->hcursor));
1512 DestroyCursor (impl->hcursor);
1513 impl->hcursor = NULL;
1515 if (hcursor != NULL)
1517 /* We must copy the cursor as it is OK to destroy the GdkCursor
1518 * while still in use for some window. See for instance
1519 * gimp_change_win_cursor() which calls
1520 * gdk_window_set_cursor (win, cursor), and immediately
1521 * afterwards gdk_cursor_destroy (cursor).
1523 impl->hcursor = CopyCursor (hcursor);
1524 GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
1525 hcursor, impl->hcursor));
1528 if (ChildWindowFromPoint (GDK_WINDOW_HWND (window), pt) == GDK_WINDOW_HWND (window))
1529 SetCursor (impl->hcursor);
1535 gdk_window_get_geometry (GdkWindow *window,
1542 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1545 window = gdk_parent_root;
1547 if (!GDK_WINDOW_DESTROYED (window))
1551 if (!GetClientRect (GDK_WINDOW_HWND (window), &rect))
1552 WIN32_API_FAILED ("GetClientRect");
1559 *width = rect.right - rect.left;
1561 *height = rect.bottom - rect.top;
1563 *depth = gdk_drawable_get_visual (window)->depth;
1568 gdk_window_get_origin (GdkWindow *window,
1576 g_return_val_if_fail (window != NULL, 0);
1578 if (!GDK_WINDOW_DESTROYED (window))
1584 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1597 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1598 GDK_WINDOW_HWND (window), tx, ty));
1603 gdk_window_get_deskrelative_origin (GdkWindow *window,
1607 return gdk_window_get_origin (window, x, y);
1611 gdk_window_get_root_origin (GdkWindow *window,
1615 GdkWindowObject *rover;
1618 g_return_if_fail (window != NULL);
1619 g_return_if_fail (GDK_IS_WINDOW (window));
1621 rover = (GdkWindowObject*) window;
1627 if (GDK_WINDOW_DESTROYED (window))
1630 while (rover->parent && ((GdkWindowObject*) rover->parent)->parent)
1631 rover = (GdkWindowObject *) rover->parent;
1632 if (rover->destroyed)
1637 ClientToScreen (GDK_WINDOW_HWND (rover), &pt);
1643 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1644 GDK_WINDOW_HWND (window),
1645 GDK_WINDOW_HWND (rover), pt.x, pt.y));
1649 gdk_window_get_pointer (GdkWindow *window,
1652 GdkModifierType *mask)
1654 GdkWindow *return_val;
1655 POINT pointc, point;
1658 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1661 window = gdk_parent_root;
1664 GetCursorPos (&pointc);
1666 ScreenToClient (GDK_WINDOW_HWND (window), &point);
1673 hwnd = WindowFromPoint (point);
1675 ScreenToClient (hwnd, &point);
1678 hwndc = ChildWindowFromPoint (hwnd, point);
1679 ClientToScreen (hwnd, &point);
1680 ScreenToClient (hwndc, &point);
1681 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1683 return_val = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1689 GetKeyboardState (kbd);
1691 if (kbd[VK_SHIFT] & 0x80)
1692 *mask |= GDK_SHIFT_MASK;
1693 if (kbd[VK_CAPITAL] & 0x80)
1694 *mask |= GDK_LOCK_MASK;
1695 if (kbd[VK_CONTROL] & 0x80)
1696 *mask |= GDK_CONTROL_MASK;
1697 if (kbd[VK_MENU] & 0x80)
1698 *mask |= GDK_MOD1_MASK;
1699 if (kbd[VK_LBUTTON] & 0x80)
1700 *mask |= GDK_BUTTON1_MASK;
1701 if (kbd[VK_MBUTTON] & 0x80)
1702 *mask |= GDK_BUTTON2_MASK;
1703 if (kbd[VK_RBUTTON] & 0x80)
1704 *mask |= GDK_BUTTON3_MASK;
1711 gdk_window_at_pointer (gint *win_x,
1715 POINT point, pointc;
1719 GetCursorPos (&pointc);
1721 hwnd = WindowFromPoint (point);
1725 window = gdk_parent_root;
1733 ScreenToClient (hwnd, &point);
1736 hwndc = ChildWindowFromPoint (hwnd, point);
1737 ClientToScreen (hwnd, &point);
1738 ScreenToClient (hwndc, &point);
1739 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1741 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1743 if (window && (win_x || win_y))
1745 GetClientRect (hwnd, &rect);
1747 *win_x = point.x - rect.left;
1749 *win_y = point.y - rect.top;
1752 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1753 point.x, point.y, hwnd,
1754 (window == NULL ? " NULL" : "")));
1760 gdk_window_get_events (GdkWindow *window)
1762 g_return_val_if_fail (window != NULL, 0);
1763 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1765 if (GDK_WINDOW_DESTROYED (window))
1768 return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask;
1772 gdk_window_set_events (GdkWindow *window,
1773 GdkEventMask event_mask)
1775 g_return_if_fail (window != NULL);
1776 g_return_if_fail (GDK_IS_WINDOW (window));
1778 if (GDK_WINDOW_DESTROYED (window))
1781 GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask = event_mask;
1785 gdk_window_shape_combine_mask (GdkWindow *window,
1789 g_return_if_fail (window != NULL);
1790 g_return_if_fail (GDK_IS_WINDOW (window));
1794 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1795 GDK_WINDOW_HWND (window)));
1796 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
1805 /* Convert mask bitmap to region */
1806 hrgn = BitmapToRegion (GDK_WINDOW_HWND (mask));
1808 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1809 GDK_WINDOW_HWND (window),
1810 GDK_WINDOW_HWND (mask)));
1812 /* SetWindowRgn wants window (not client) coordinates */
1813 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1814 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1815 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1816 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1817 OffsetRgn (hrgn, -rect.left, -rect.top);
1819 OffsetRgn (hrgn, x, y);
1821 /* If this is a top-level window, add the title bar to the region */
1822 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1824 CombineRgn (hrgn, hrgn,
1825 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1829 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
1834 gdk_window_set_override_redirect (GdkWindow *window,
1835 gboolean override_redirect)
1837 g_return_if_fail (window != NULL);
1838 g_return_if_fail (GDK_IS_WINDOW (window));
1840 g_warning ("gdk_window_set_override_redirect not implemented");
1844 gdk_window_set_icon (GdkWindow *window,
1845 GdkWindow *icon_window,
1849 g_return_if_fail (window != NULL);
1850 g_return_if_fail (GDK_IS_WINDOW (window));
1852 if (GDK_WINDOW_DESTROYED (window))
1855 /* Nothing to do, really. As we share window classes between windows
1856 * we can't have window-specific icons, sorry. Don't print any warning
1862 gdk_window_set_icon_name (GdkWindow *window,
1865 g_return_if_fail (window != NULL);
1866 g_return_if_fail (GDK_IS_WINDOW (window));
1868 if (GDK_WINDOW_DESTROYED (window))
1871 if (!SetWindowText (GDK_WINDOW_HWND (window), name))
1872 WIN32_API_FAILED ("SetWindowText");
1876 gdk_window_set_group (GdkWindow *window,
1879 g_return_if_fail (window != NULL);
1880 g_return_if_fail (GDK_IS_WINDOW (window));
1881 g_return_if_fail (leader != NULL);
1882 g_return_if_fail (GDK_IS_WINDOW (leader));
1884 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1887 g_warning ("gdk_window_set_group not implemented");
1891 gdk_window_set_decorations (GdkWindow *window,
1892 GdkWMDecoration decorations)
1894 LONG style, exstyle;
1896 g_return_if_fail (window != NULL);
1897 g_return_if_fail (GDK_IS_WINDOW (window));
1899 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1900 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1902 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1903 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
1905 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1907 if (decorations & GDK_DECOR_ALL)
1908 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
1909 if (decorations & GDK_DECOR_BORDER)
1910 style |= (WS_BORDER);
1911 if (decorations & GDK_DECOR_RESIZEH)
1912 style |= (WS_THICKFRAME);
1913 if (decorations & GDK_DECOR_TITLE)
1914 style |= (WS_CAPTION);
1915 if (decorations & GDK_DECOR_MENU)
1916 style |= (WS_SYSMENU);
1917 if (decorations & GDK_DECOR_MINIMIZE)
1918 style |= (WS_MINIMIZEBOX);
1919 if (decorations & GDK_DECOR_MAXIMIZE)
1920 style |= (WS_MAXIMIZEBOX);
1922 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1926 gdk_window_set_functions (GdkWindow *window,
1927 GdkWMFunction functions)
1929 LONG style, exstyle;
1931 g_return_if_fail (window != NULL);
1932 g_return_if_fail (GDK_IS_WINDOW (window));
1934 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1935 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1937 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1938 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
1941 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1943 if (functions & GDK_FUNC_ALL)
1944 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
1945 if (functions & GDK_FUNC_RESIZE)
1946 style |= (WS_THICKFRAME);
1947 if (functions & GDK_FUNC_MOVE)
1948 style |= (WS_THICKFRAME);
1949 if (functions & GDK_FUNC_MINIMIZE)
1950 style |= (WS_MINIMIZEBOX);
1951 if (functions & GDK_FUNC_MAXIMIZE)
1952 style |= (WS_MAXIMIZEBOX);
1954 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1958 * propagate the shapes from all child windows of a GDK window to the parent
1959 * window. Shamelessly ripped from Enlightenment's code
1965 QueryTree (HWND hwnd,
1975 child = GetWindow (hwnd, GW_CHILD);
1977 child = GetWindow (child, GW_HWNDNEXT);
1980 } while (child != NULL);
1984 *children = g_new (HWND, n);
1985 for (i = 0; i < n; i++)
1988 child = GetWindow (hwnd, GW_CHILD);
1990 child = GetWindow (child, GW_HWNDNEXT);
1991 *children[i] = child;
1997 gdk_propagate_shapes (HANDLE win,
2001 HRGN region, childRegion;
2006 SetRectEmpty (&emptyRect);
2007 region = CreateRectRgnIndirect (&emptyRect);
2009 GetWindowRgn (win, region);
2011 QueryTree (win, &list, &num);
2014 WINDOWPLACEMENT placement;
2016 placement.length = sizeof (WINDOWPLACEMENT);
2017 /* go through all child windows and combine regions */
2018 for (i = 0; i < num; i++)
2020 GetWindowPlacement (list[i], &placement);
2021 if (placement.showCmd == SW_SHOWNORMAL)
2023 childRegion = CreateRectRgnIndirect (&emptyRect);
2024 GetWindowRgn (list[i], childRegion);
2025 CombineRgn (region, region, childRegion, RGN_OR);
2026 DeleteObject (childRegion);
2029 SetWindowRgn (win, region, TRUE);
2032 DeleteObject (region);
2036 gdk_window_set_child_shapes (GdkWindow *window)
2038 g_return_if_fail (window != NULL);
2039 g_return_if_fail (GDK_IS_WINDOW (window));
2041 if (GDK_WINDOW_DESTROYED (window))
2044 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2048 gdk_window_merge_child_shapes (GdkWindow *window)
2050 g_return_if_fail (window != NULL);
2051 g_return_if_fail (GDK_IS_WINDOW (window));
2053 if (GDK_WINDOW_DESTROYED (window))
2056 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2059 /* Support for windows that can be guffaw-scrolled
2060 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2064 gdk_window_gravity_works (void)
2066 enum { UNKNOWN, NO, YES };
2067 static gint gravity_works = UNKNOWN;
2069 if (gravity_works == UNKNOWN)
2076 attr.window_type = GDK_WINDOW_TEMP;
2077 attr.wclass = GDK_INPUT_OUTPUT;
2082 attr.event_mask = 0;
2084 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2086 attr.window_type = GDK_WINDOW_CHILD;
2087 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2089 gdk_window_set_static_win_gravity (child, TRUE);
2091 gdk_window_resize (parent, 100, 110);
2092 gdk_window_move (parent, 0, -10);
2093 gdk_window_move_resize (parent, 0, 0, 100, 100);
2095 gdk_window_resize (parent, 100, 110);
2096 gdk_window_move (parent, 0, -10);
2097 gdk_window_move_resize (parent, 0, 0, 100, 100);
2099 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2101 gdk_window_destroy (parent);
2102 gdk_window_destroy (child);
2104 gravity_works = ((y == -20) ? YES : NO);
2107 return (gravity_works == YES);
2111 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2113 g_return_if_fail (window != NULL);
2115 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2119 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2121 g_return_if_fail (window != NULL);
2124 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2127 /*************************************************************
2128 * gdk_window_set_static_gravities:
2129 * Set the bit gravity of the given window to static,
2130 * and flag it so all children get static subwindow
2133 * window: window for which to set static gravity
2134 * use_static: Whether to turn static gravity on or off.
2136 * Does the XServer support static gravity?
2137 *************************************************************/
2140 gdk_window_set_static_gravities (GdkWindow *window,
2141 gboolean use_static)
2143 GdkWindowObject *private = (GdkWindowObject *)window;
2146 g_return_val_if_fail (window != NULL, FALSE);
2147 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2149 if (!use_static == !private->guffaw_gravity)
2152 if (use_static && !gdk_window_gravity_works ())
2155 private->guffaw_gravity = use_static;
2157 if (!GDK_WINDOW_DESTROYED (window))
2159 gdk_window_set_static_bit_gravity (window, use_static);
2161 tmp_list = private->children;
2164 gdk_window_set_static_win_gravity (window, use_static);
2166 tmp_list = tmp_list->next;