1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2004 Tor Lillqvist
4 * Copyright (C) 2001-2011 Hans Breuer
5 * Copyright (C) 2007-2009 Cody Russell
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
34 #include "gdkwindowimpl.h"
35 #include "gdkprivate-win32.h"
36 #include "gdkdeviceprivate.h"
37 #include "gdkdevicemanager-win32.h"
38 #include "gdkenumtypes.h"
40 #include "gdkdisplayprivate.h"
41 #include "gdkvisualprivate.h"
42 #include "gdkwin32window.h"
44 #include <cairo-win32.h>
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;
51 static GSList *modal_window_stack = NULL;
53 static const cairo_user_data_key_t gdk_win32_cairo_key;
55 static void update_style_bits (GdkWindow *window);
56 static gboolean _gdk_window_get_functions (GdkWindow *window,
57 GdkWMFunction *functions);
59 #define WINDOW_IS_TOPLEVEL(window) \
60 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
61 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
62 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
65 GDK_WINDOW_SCREEN (GObject *win)
70 struct _GdkWin32Window {
74 struct _GdkWin32WindowClass {
75 GdkWindowClass parent_class;
78 G_DEFINE_TYPE (GdkWin32Window, gdk_win32_window, GDK_TYPE_WINDOW)
81 gdk_win32_window_class_init (GdkWin32WindowClass *window_class)
86 gdk_win32_window_init (GdkWin32Window *window)
91 G_DEFINE_TYPE (GdkWindowImplWin32, gdk_window_impl_win32, GDK_TYPE_WINDOW_IMPL)
94 _gdk_window_impl_win32_get_type (void)
96 static GType object_type = 0;
100 const GTypeInfo object_info =
102 sizeof (GdkWindowImplWin32Class),
103 (GBaseInitFunc) NULL,
104 (GBaseFinalizeFunc) NULL,
105 (GClassInitFunc) gdk_window_impl_win32_class_init,
106 NULL, /* class_finalize */
107 NULL, /* class_data */
108 sizeof (GdkWindowImplWin32),
110 (GInstanceInitFunc) gdk_window_impl_win32_init,
113 object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
114 "GdkWindowImplWin32",
122 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
124 impl->toplevel_window_type = -1;
125 impl->hcursor = NULL;
126 impl->hicon_big = NULL;
127 impl->hicon_small = NULL;
128 impl->hint_flags = 0;
129 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
130 impl->extension_events_selected = FALSE;
131 impl->transient_owner = NULL;
132 impl->transient_children = NULL;
133 impl->num_transients = 0;
134 impl->changing_state = FALSE;
138 gdk_window_impl_win32_finalize (GObject *object)
141 GdkWindowImplWin32 *window_impl;
143 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
145 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
147 wrapper = window_impl->wrapper;
149 if (!GDK_WINDOW_DESTROYED (wrapper))
151 gdk_win32_handle_table_remove (window_impl->handle);
154 if (window_impl->hcursor != NULL)
156 if (GetCursor () == window_impl->hcursor)
159 GDI_CALL (DestroyCursor, (window_impl->hcursor));
160 window_impl->hcursor = NULL;
163 if (window_impl->hicon_big != NULL)
165 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
166 window_impl->hicon_big = NULL;
169 if (window_impl->hicon_small != NULL)
171 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
172 window_impl->hicon_small = NULL;
175 G_OBJECT_CLASS (parent_class)->finalize (object);
179 _gdk_win32_adjust_client_rect (GdkWindow *window,
184 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
185 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
186 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
190 _gdk_root_window_size_init (void)
196 window = GDK_WINDOW (_gdk_root);
197 rect = _gdk_monitors[0].rect;
198 for (i = 1; i < _gdk_num_monitors; i++)
199 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
201 window->width = rect.width;
202 window->height = rect.height;
206 _gdk_windowing_window_init (GdkScreen *screen)
209 GdkWindowImplWin32 *impl_win32;
211 g_assert (_gdk_root == NULL);
213 _gdk_root = _gdk_display_create_window (_gdk_display);
215 window = (GdkWindow *)_gdk_root;
216 window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
217 impl_win32 = GDK_WINDOW_IMPL_WIN32 (window->impl);
218 impl_win32->wrapper = window;
220 window->impl_window = window;
221 window->visual = gdk_screen_get_system_visual (screen);
223 window->window_type = GDK_WINDOW_ROOT;
224 window->depth = gdk_visual_get_system ()->depth;
226 _gdk_root_window_size_init ();
232 /* width and height already initialised in _gdk_root_window_size_init() */
233 window->viewable = TRUE;
235 gdk_win32_handle_table_insert ((HANDLE *) &impl_win32->handle, _gdk_root);
237 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
241 get_default_title (void)
244 title = g_get_application_name ();
246 title = g_get_prgname ();
252 * is a wrapper function for RegisterWindowClassEx.
253 * It creates at least one unique class for every
254 * GdkWindowType. If support for single window-specific icons
255 * is ever needed (e.g Dialog specific), every such window should
259 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
261 static ATOM klassTOPLEVEL = 0;
262 static ATOM klassCHILD = 0;
263 static ATOM klassTEMP = 0;
264 static ATOM klassTEMPSHADOW = 0;
265 static HICON hAppIcon = NULL;
266 static HICON hAppIconSm = NULL;
267 static WNDCLASSEXW wcl;
270 wcl.cbSize = sizeof (WNDCLASSEX);
271 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
272 * on WM_SIZE and WM_MOVE. Flicker, Performance!
274 wcl.lpfnWndProc = _gdk_win32_window_procedure;
277 wcl.hInstance = _gdk_app_hmodule;
281 /* initialize once! */
282 if (0 == hAppIcon && 0 == hAppIconSm)
284 gchar sLoc [MAX_PATH+1];
286 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
288 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
290 if (0 == hAppIcon && 0 == hAppIconSm)
292 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
294 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
299 if (0 == hAppIcon && 0 == hAppIconSm)
301 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
302 GetSystemMetrics (SM_CXICON),
303 GetSystemMetrics (SM_CYICON), 0);
304 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
305 GetSystemMetrics (SM_CXSMICON),
306 GetSystemMetrics (SM_CYSMICON), 0);
311 hAppIcon = hAppIconSm;
312 else if (0 == hAppIconSm)
313 hAppIconSm = hAppIcon;
315 wcl.lpszMenuName = NULL;
317 /* initialize once per class */
319 * HB: Setting the background brush leads to flicker, because we
320 * don't get asked how to clear the background. This is not what
321 * we want, at least not for input_only windows ...
323 #define ONCE_PER_CLASS() \
324 wcl.hIcon = CopyIcon (hAppIcon); \
325 wcl.hIconSm = CopyIcon (hAppIconSm); \
326 wcl.hbrBackground = NULL; \
327 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
331 case GDK_WINDOW_TOPLEVEL:
332 if (0 == klassTOPLEVEL)
334 wcl.lpszClassName = L"gdkWindowToplevel";
337 klassTOPLEVEL = RegisterClassExW (&wcl);
339 klass = klassTOPLEVEL;
342 case GDK_WINDOW_CHILD:
345 wcl.lpszClassName = L"gdkWindowChild";
347 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
349 klassCHILD = RegisterClassExW (&wcl);
354 case GDK_WINDOW_TEMP:
355 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
356 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
357 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
358 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
360 if (klassTEMPSHADOW == 0)
362 wcl.lpszClassName = L"gdkWindowTempShadow";
363 wcl.style |= CS_SAVEBITS;
364 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
365 LOWORD (g_win32_get_windows_version()) == 0x0105)
367 /* Windows XP (5.1) or above */
368 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
371 klassTEMPSHADOW = RegisterClassExW (&wcl);
374 klass = klassTEMPSHADOW;
380 wcl.lpszClassName = L"gdkWindowTemp";
381 wcl.style |= CS_SAVEBITS;
383 klassTEMP = RegisterClassExW (&wcl);
391 g_assert_not_reached ();
397 WIN32_API_FAILED ("RegisterClassExW");
398 g_error ("That is a fatal error");
404 * Create native windows.
406 * With the default Gdk the created windows are mostly toplevel windows.
408 * Placement of the window is derived from the passed in window,
409 * except for toplevel window where OS/Window Manager placement
412 * The visual parameter, is based on GDK_WA_VISUAL if set already.
413 * From attributes the only things used is: colormap, title,
414 * wmclass and type_hint. [1]. We are checking redundant information
415 * and complain if that changes, which would break this implementation
418 * [1] http://mail.gnome.org/archives/gtk-devel-list/2010-August/msg00214.html
421 _gdk_win32_display_create_window_impl (GdkDisplay *display,
423 GdkWindow *real_parent,
425 GdkEventMask event_mask,
426 GdkWindowAttr *attributes,
427 gint attributes_mask)
432 DWORD dwStyle = 0, dwExStyle;
434 GdkWindowImplWin32 *impl;
437 gint window_width, window_height;
438 gint offset_x = 0, offset_y = 0;
440 /* check consistency of redundant information */
441 guint remaining_mask = attributes_mask;
444 g_print ("_gdk_window_impl_new: %s %s\n",
445 (window->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
446 (window->window_type == GDK_WINDOW_CHILD ? "CHILD" :
447 (window->window_type == GDK_WINDOW_TEMP ? "TEMP" :
449 (attributes->wclass == GDK_INPUT_OUTPUT ? "" : "input-only"))
452 /* to ensure to not miss important information some additional check against
453 * attributes which may silently work on X11 */
454 if ((attributes_mask & GDK_WA_X) != 0)
456 g_assert (attributes->x == window->x);
457 remaining_mask &= ~GDK_WA_X;
459 if ((attributes_mask & GDK_WA_Y) != 0)
461 g_assert (attributes->y == window->y);
462 remaining_mask &= ~GDK_WA_Y;
464 if ((attributes_mask & GDK_WA_NOREDIR) != 0)
465 remaining_mask &= ~GDK_WA_NOREDIR;
467 if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0)
468 g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X",
469 remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT));
471 hparent = GDK_WINDOW_HWND (real_parent);
473 impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
474 impl->wrapper = GDK_WINDOW (window);
475 window->impl = GDK_WINDOW_IMPL (impl);
477 if (attributes_mask & GDK_WA_VISUAL)
478 g_assert (gdk_screen_get_system_visual (screen) == attributes->visual);
480 impl->extension_events_selected = FALSE;
482 /* wclass is not any longer set always, but if is ... */
483 if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS)
484 g_assert ((attributes->wclass == GDK_INPUT_OUTPUT) == !window->input_only);
486 if (!window->input_only)
492 /* I very much doubt using WS_EX_TRANSPARENT actually
493 * corresponds to how X11 InputOnly windows work, but it appears
494 * to work well enough for the actual use cases in gtk.
496 dwExStyle = WS_EX_TRANSPARENT;
497 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY\n"));
500 switch (window->window_type)
502 case GDK_WINDOW_TOPLEVEL:
503 if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
505 /* The common code warns for this case. */
506 hparent = GetDesktopWindow ();
508 /* Children of foreign windows aren't toplevel windows */
509 if (GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
511 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
515 if (window->window_type == GDK_WINDOW_TOPLEVEL)
516 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
518 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
520 offset_x = _gdk_offset_x;
521 offset_y = _gdk_offset_y;
525 case GDK_WINDOW_CHILD:
526 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
529 case GDK_WINDOW_TEMP:
530 /* A temp window is not necessarily a top level window */
531 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
532 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
533 dwExStyle |= WS_EX_TOOLWINDOW;
534 offset_x = _gdk_offset_x;
535 offset_y = _gdk_offset_y;
539 g_assert_not_reached ();
542 if (window->window_type != GDK_WINDOW_CHILD)
544 rect.left = window->x;
545 rect.top = window->y;
546 rect.right = window->width;
547 rect.bottom = window->height;
549 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
551 /* non child windows are placed by the OS/window manager */
552 x = y = CW_USEDEFAULT;
554 window_width = rect.right - rect.left;
555 window_height = rect.bottom - rect.top;
559 /* adjust position relative to real_parent */
560 window_width = window->width;
561 window_height = window->height;
562 /* use given position for initial placement, native coordinates */
563 x = window->x + window->parent->abs_x - offset_x;
564 y = window->y + window->parent->abs_y - offset_y;
567 if (attributes_mask & GDK_WA_TITLE)
568 title = attributes->title;
570 title = get_default_title ();
571 if (!title || !*title)
574 impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
576 if (attributes_mask & GDK_WA_TYPE_HINT)
577 gdk_window_set_type_hint (window, attributes->type_hint);
579 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
580 dwExStyle |= WS_EX_TOOLWINDOW;
582 klass = RegisterGdkClass (window->window_type, impl->type_hint);
584 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
586 hwndNew = CreateWindowExW (dwExStyle,
587 MAKEINTRESOURCEW (klass),
592 window_width, window_height,
597 if (GDK_WINDOW_HWND (window) != hwndNew)
599 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
600 GDK_WINDOW_HWND (window),
603 /* HB: IHMO due to a race condition the handle was increased by
604 * one, which causes much trouble. Because I can't find the
605 * real bug, try to workaround it ...
606 * To reproduce: compile with MSVC 5, DEBUG=1
609 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
610 GDK_WINDOW_HWND (window) = hwndNew;
611 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
613 /* the old behaviour, but with warning */
614 impl->handle = hwndNew;
619 g_object_ref (window);
620 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
622 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
624 window_width, window_height,
625 window->x - offset_x,
626 window->y - offset_y,
628 GDK_WINDOW_HWND (window)));
630 /* Add window handle to title */
631 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
635 if (impl->handle == NULL)
637 WIN32_API_FAILED ("CreateWindowExW");
638 g_object_unref (window);
642 // if (!from_set_skip_taskbar_hint && window->window_type == GDK_WINDOW_TEMP)
643 // gdk_window_set_skip_taskbar_hint (window, TRUE);
645 if (attributes_mask & GDK_WA_CURSOR)
646 gdk_window_set_cursor (window, attributes->cursor);
650 gdk_win32_window_foreign_new_for_display (GdkDisplay *display,
654 GdkWindowImplWin32 *impl;
660 g_return_val_if_fail (display == _gdk_display, NULL);
662 if ((window = gdk_win32_window_lookup_for_display (display, anid)) != NULL)
663 return g_object_ref (window);
665 window = _gdk_display_create_window (display);
666 window->visual = gdk_screen_get_system_visual (_gdk_screen);
667 window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
668 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
669 impl->wrapper = window;
670 parent = GetParent (anid);
672 window->parent = gdk_win32_handle_table_lookup (parent);
673 if (!window->parent || GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_FOREIGN)
674 window->parent = _gdk_root;
676 window->parent->children = g_list_prepend (window->parent->children, window);
678 GetClientRect ((HWND) anid, &rect);
680 point.y = rect.right;
681 ClientToScreen ((HWND) anid, &point);
682 if (parent != GetDesktopWindow ())
683 ScreenToClient (parent, &point);
686 window->width = rect.right - rect.left;
687 window->height = rect.bottom - rect.top;
688 window->window_type = GDK_WINDOW_FOREIGN;
689 window->destroyed = FALSE;
690 window->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
691 if (IsWindowVisible ((HWND) anid))
692 window->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
694 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
695 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
696 window->state |= GDK_WINDOW_STATE_ABOVE;
698 window->state &= (~GDK_WINDOW_STATE_ABOVE);
699 window->state &= (~GDK_WINDOW_STATE_BELOW);
700 window->viewable = TRUE;
702 window->depth = gdk_visual_get_system ()->depth;
704 g_object_ref (window);
705 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
707 GDK_NOTE (MISC, g_print ("gdk_win32_window_foreign_new_for_display: %p: %s@%+d%+d\n",
709 _gdk_win32_window_description (window),
710 window->x, window->y));
716 gdk_win32_window_destroy (GdkWindow *window,
718 gboolean foreign_destroy)
720 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
723 g_return_if_fail (GDK_IS_WINDOW (window));
725 GDK_NOTE (MISC, g_print ("gdk_win32_window_destroy: %p\n",
726 GDK_WINDOW_HWND (window)));
728 /* Remove ourself from the modal stack */
729 _gdk_remove_modal_window (window);
731 /* Remove all our transient children */
732 tmp = window_impl->transient_children;
735 GdkWindow *child = tmp->data;
736 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW (child)->impl);
738 child_impl->transient_owner = NULL;
739 tmp = g_slist_next (tmp);
741 g_slist_free (window_impl->transient_children);
742 window_impl->transient_children = NULL;
744 /* Remove ourself from our transient owner */
745 if (window_impl->transient_owner != NULL)
747 gdk_window_set_transient_for (window, NULL);
750 if (!recursing && !foreign_destroy)
752 window->destroyed = TRUE;
753 DestroyWindow (GDK_WINDOW_HWND (window));
756 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
759 static cairo_surface_t *
760 gdk_win32_window_resize_cairo_surface (GdkWindow *window,
761 cairo_surface_t *surface,
765 /* XXX: Make Cairo surface use DC clip */
766 cairo_surface_destroy (surface);
772 gdk_win32_window_destroy_foreign (GdkWindow *window)
774 /* It's somebody else's window, but in our hierarchy, so reparent it
775 * to the desktop, and then try to destroy it.
777 gdk_window_hide (window);
778 gdk_window_reparent (window, NULL, 0, 0);
780 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
783 /* This function is called when the window really gone.
786 gdk_win32_window_destroy_notify (GdkWindow *window)
788 g_return_if_fail (GDK_IS_WINDOW (window));
791 g_print ("gdk_window_destroy_notify: %p%s\n",
792 GDK_WINDOW_HWND (window),
793 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
795 if (!GDK_WINDOW_DESTROYED (window))
797 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
798 g_warning ("window %p unexpectedly destroyed",
799 GDK_WINDOW_HWND (window));
801 _gdk_window_destroy (window, TRUE);
804 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
805 g_object_unref (window);
809 get_outer_rect (GdkWindow *window,
814 rect->left = rect->top = 0;
816 rect->bottom = height;
818 _gdk_win32_adjust_client_rect (window, rect);
822 adjust_for_gravity_hints (GdkWindow *window,
827 GdkWindowImplWin32 *impl;
829 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
831 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
833 gint orig_x = *x, orig_y = *y;
835 switch (impl->hints.win_gravity)
837 case GDK_GRAVITY_NORTH:
838 case GDK_GRAVITY_CENTER:
839 case GDK_GRAVITY_SOUTH:
840 *x -= (outer_rect->right - outer_rect->left) / 2;
841 *x += window->width / 2;
844 case GDK_GRAVITY_SOUTH_EAST:
845 case GDK_GRAVITY_EAST:
846 case GDK_GRAVITY_NORTH_EAST:
847 *x -= outer_rect->right - outer_rect->left;
851 case GDK_GRAVITY_STATIC:
852 *x += outer_rect->left;
859 switch (impl->hints.win_gravity)
861 case GDK_GRAVITY_WEST:
862 case GDK_GRAVITY_CENTER:
863 case GDK_GRAVITY_EAST:
864 *y -= (outer_rect->bottom - outer_rect->top) / 2;
865 *y += window->height / 2;
868 case GDK_GRAVITY_SOUTH_WEST:
869 case GDK_GRAVITY_SOUTH:
870 case GDK_GRAVITY_SOUTH_EAST:
871 *y -= outer_rect->bottom - outer_rect->top;
872 *y += window->height;
875 case GDK_GRAVITY_STATIC:
876 *y += outer_rect->top;
883 (orig_x != *x || orig_y != *y) ?
884 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
885 orig_x, *x, orig_y, *y)
891 show_window_internal (GdkWindow *window,
895 HWND old_active_window;
896 gboolean focus_on_map = TRUE;
900 if (window->destroyed)
903 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
904 GDK_WINDOW_HWND (window),
905 _gdk_win32_window_state_to_string (window->state),
906 (raise ? " raise" : ""),
907 (deiconify ? " deiconify" : "")));
909 /* If asked to show (not deiconify) an withdrawn and iconified
913 !GDK_WINDOW_IS_MAPPED (window) &&
914 (window->state & GDK_WINDOW_STATE_ICONIFIED))
916 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
920 /* If asked to just show an iconified window, do nothing. */
921 if (!deiconify && (window->state & GDK_WINDOW_STATE_ICONIFIED))
924 /* If asked to deiconify an already noniconified window, do
925 * nothing. (Especially, don't cause the window to rise and
926 * activate. There are different calls for that.)
928 if (deiconify && !(window->state & GDK_WINDOW_STATE_ICONIFIED))
931 /* If asked to show (but not raise) a window that is already
932 * visible, do nothing.
934 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
939 if (!GDK_WINDOW_IS_MAPPED (window))
941 gdk_synthesize_window_state (window,
942 GDK_WINDOW_STATE_WITHDRAWN,
944 focus_on_map = window->focus_on_map;
947 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
949 if (window->state & GDK_WINDOW_STATE_BELOW)
950 exstyle &= (~WS_EX_TOPMOST);
952 if (window->state & GDK_WINDOW_STATE_ABOVE)
953 exstyle |= WS_EX_TOPMOST;
955 if (exstyle & WS_EX_TOPMOST)
960 /* Use SetWindowPos to show transparent windows so automatic redraws
961 * in other windows can be suppressed.
963 if (exstyle & WS_EX_TRANSPARENT)
965 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
968 flags |= SWP_NOZORDER;
969 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
970 flags |= SWP_NOACTIVATE;
972 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
977 old_active_window = GetActiveWindow ();
979 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
981 gdk_window_fullscreen (window);
983 else if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
985 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
987 else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
989 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
991 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
993 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
997 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1002 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1003 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1005 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1006 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1008 if (focus_on_map && window->accept_focus)
1010 SetForegroundWindow (GDK_WINDOW_HWND (window));
1011 if (top == HWND_TOPMOST)
1012 SetWindowPos (GDK_WINDOW_HWND (window), top,
1014 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1018 SetWindowPos (GDK_WINDOW_HWND (window), top,
1020 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1025 BringWindowToTop (GDK_WINDOW_HWND (window));
1028 else if (old_active_window != GDK_WINDOW_HWND (window))
1030 SetActiveWindow (old_active_window);
1035 gdk_win32_window_show (GdkWindow *window,
1036 gboolean already_mapped)
1038 show_window_internal (window, FALSE, FALSE);
1042 gdk_win32_window_hide (GdkWindow *window)
1044 if (window->destroyed)
1047 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1048 GDK_WINDOW_HWND (window),
1049 _gdk_win32_window_state_to_string (window->state)));
1051 if (GDK_WINDOW_IS_MAPPED (window))
1052 gdk_synthesize_window_state (window,
1054 GDK_WINDOW_STATE_WITHDRAWN);
1056 _gdk_window_clear_update_area (window);
1058 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1059 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1061 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1063 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1065 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1069 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1074 gdk_win32_window_withdraw (GdkWindow *window)
1076 if (window->destroyed)
1079 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1080 GDK_WINDOW_HWND (window),
1081 _gdk_win32_window_state_to_string (window->state)));
1083 gdk_window_hide (window); /* ??? */
1087 gdk_win32_window_move (GdkWindow *window,
1090 GdkWindowImplWin32 *impl;
1092 g_return_if_fail (GDK_IS_WINDOW (window));
1094 if (GDK_WINDOW_DESTROYED (window))
1097 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1098 GDK_WINDOW_HWND (window), x, y));
1100 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1102 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1105 /* Don't check GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD.
1106 * Foreign windows (another app's windows) might be children of our
1107 * windows! Especially in the case of gtkplug/socket.
1109 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1111 _gdk_window_move_resize_child (window, x, y, window->width, window->height);
1117 get_outer_rect (window, window->width, window->height, &outer_rect);
1119 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1121 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1122 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1123 GDK_WINDOW_HWND (window),
1124 x - _gdk_offset_x, y - _gdk_offset_y));
1126 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1127 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1128 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1133 gdk_win32_window_resize (GdkWindow *window,
1134 gint width, gint height)
1136 GdkWindowImplWin32 *impl;
1138 g_return_if_fail (GDK_IS_WINDOW (window));
1140 if (GDK_WINDOW_DESTROYED (window))
1148 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1149 GDK_WINDOW_HWND (window), width, height));
1151 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1153 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1156 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1158 _gdk_window_move_resize_child (window, window->x, window->y, width, height);
1164 get_outer_rect (window, width, height, &outer_rect);
1166 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1167 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1168 GDK_WINDOW_HWND (window),
1169 outer_rect.right - outer_rect.left,
1170 outer_rect.bottom - outer_rect.top));
1172 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1174 outer_rect.right - outer_rect.left,
1175 outer_rect.bottom - outer_rect.top,
1176 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1177 window->resize_count += 1;
1182 gdk_win32_window_move_resize_internal (GdkWindow *window,
1188 GdkWindowImplWin32 *impl;
1190 g_return_if_fail (GDK_IS_WINDOW (window));
1192 if (GDK_WINDOW_DESTROYED (window))
1200 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1202 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1205 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1206 GDK_WINDOW_HWND (window),
1207 width, height, x, y));
1209 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1211 _gdk_window_move_resize_child (window, x, y, width, height);
1217 get_outer_rect (window, width, height, &outer_rect);
1219 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1221 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1222 "NOACTIVATE|NOZORDER)\n",
1223 GDK_WINDOW_HWND (window),
1224 x - _gdk_offset_x, y - _gdk_offset_y,
1225 outer_rect.right - outer_rect.left,
1226 outer_rect.bottom - outer_rect.top));
1228 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1229 x - _gdk_offset_x, y - _gdk_offset_y,
1230 outer_rect.right - outer_rect.left,
1231 outer_rect.bottom - outer_rect.top,
1232 SWP_NOACTIVATE | SWP_NOZORDER));
1237 gdk_win32_window_move_resize (GdkWindow *window,
1244 if (with_move && (width < 0 && height < 0))
1246 gdk_win32_window_move (window, x, y);
1252 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1256 gdk_win32_window_resize (window, width, height);
1262 gdk_win32_window_reparent (GdkWindow *window,
1263 GdkWindow *new_parent,
1268 GdkWindow *old_parent;
1269 GdkWindowImplWin32 *impl;
1270 gboolean was_toplevel;
1274 new_parent = _gdk_root;
1276 old_parent = window->parent;
1277 parent = new_parent;
1278 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1280 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1281 GDK_WINDOW_HWND (window),
1282 GDK_WINDOW_HWND (new_parent)));
1284 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1286 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1287 if (was_toplevel && new_parent != _gdk_root)
1289 /* Reparenting from top-level (child of desktop). Clear out
1292 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1294 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1296 else if (new_parent == _gdk_root)
1298 /* Reparenting to top-level. Add decorations. */
1299 style &= ~(WS_CHILD);
1300 style |= WS_OVERLAPPEDWINDOW;
1301 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1304 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1305 GDK_WINDOW_HWND (new_parent)));
1307 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1308 x, y, window->width, window->height, TRUE));
1310 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1313 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1314 new_parent = _gdk_root;
1316 window->parent = new_parent;
1318 /* Switch the window type as appropriate */
1320 switch (GDK_WINDOW_TYPE (new_parent))
1322 case GDK_WINDOW_ROOT:
1323 if (impl->toplevel_window_type != -1)
1324 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1325 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1326 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1329 case GDK_WINDOW_TOPLEVEL:
1330 case GDK_WINDOW_CHILD:
1331 case GDK_WINDOW_TEMP:
1332 if (WINDOW_IS_TOPLEVEL (window))
1334 /* Save the original window type so we can restore it if the
1335 * window is reparented back to be a toplevel.
1337 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1338 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1343 old_parent->children =
1344 g_list_remove (old_parent->children, window);
1346 parent->children = g_list_prepend (parent->children, window);
1352 gdk_win32_window_raise (GdkWindow *window)
1354 if (!GDK_WINDOW_DESTROYED (window))
1356 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1357 GDK_WINDOW_HWND (window)));
1359 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1360 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1362 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1363 else if (window->accept_focus)
1364 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1366 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1368 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1373 gdk_win32_window_lower (GdkWindow *window)
1375 if (!GDK_WINDOW_DESTROYED (window))
1377 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1378 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1379 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1380 GDK_WINDOW_HWND (window),
1381 GDK_WINDOW_HWND (window)));
1383 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1385 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1390 gdk_win32_window_set_urgency_hint (GdkWindow *window,
1393 FLASHWINFO flashwinfo;
1394 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1395 PFN_FlashWindowEx flashWindowEx = NULL;
1397 g_return_if_fail (GDK_IS_WINDOW (window));
1398 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1400 if (GDK_WINDOW_DESTROYED (window))
1403 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1407 flashwinfo.cbSize = sizeof (flashwinfo);
1408 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1410 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1412 flashwinfo.dwFlags = FLASHW_STOP;
1413 flashwinfo.uCount = 0;
1414 flashwinfo.dwTimeout = 0;
1416 flashWindowEx (&flashwinfo);
1420 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1425 get_effective_window_decorations (GdkWindow *window,
1426 GdkWMDecoration *decoration)
1428 GdkWindowImplWin32 *impl;
1430 impl = (GdkWindowImplWin32 *)window->impl;
1432 if (gdk_window_get_decorations (window, decoration))
1435 if (window->window_type != GDK_WINDOW_TOPLEVEL)
1440 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1441 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1442 impl->hints.min_width == impl->hints.max_width &&
1443 impl->hints.min_height == impl->hints.max_height)
1445 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1447 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1448 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1449 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1451 *decoration |= GDK_DECOR_MINIMIZE;
1453 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1455 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1460 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1462 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1463 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1464 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1465 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1467 *decoration |= GDK_DECOR_MINIMIZE;
1474 switch (impl->type_hint)
1476 case GDK_WINDOW_TYPE_HINT_DIALOG:
1477 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1480 case GDK_WINDOW_TYPE_HINT_MENU:
1481 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1484 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1485 case GDK_WINDOW_TYPE_HINT_UTILITY:
1486 gdk_window_set_skip_taskbar_hint (window, TRUE);
1487 gdk_window_set_skip_pager_hint (window, TRUE);
1488 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1491 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1492 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1493 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1496 case GDK_WINDOW_TYPE_HINT_DOCK:
1499 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1504 case GDK_WINDOW_TYPE_HINT_NORMAL:
1505 *decoration = GDK_DECOR_ALL;
1514 gdk_win32_window_set_geometry_hints (GdkWindow *window,
1515 const GdkGeometry *geometry,
1516 GdkWindowHints geom_mask)
1518 GdkWindowImplWin32 *impl;
1520 g_return_if_fail (GDK_IS_WINDOW (window));
1522 if (GDK_WINDOW_DESTROYED (window))
1525 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1526 GDK_WINDOW_HWND (window)));
1528 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1530 impl->hint_flags = geom_mask;
1531 impl->hints = *geometry;
1533 if (geom_mask & GDK_HINT_POS)
1534 ; /* even the X11 mplementation doesn't care */
1536 if (geom_mask & GDK_HINT_MIN_SIZE)
1538 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1539 geometry->min_width, geometry->min_height));
1542 if (geom_mask & GDK_HINT_MAX_SIZE)
1544 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1545 geometry->max_width, geometry->max_height));
1548 if (geom_mask & GDK_HINT_BASE_SIZE)
1550 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1551 geometry->base_width, geometry->base_height));
1554 if (geom_mask & GDK_HINT_RESIZE_INC)
1556 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1557 geometry->width_inc, geometry->height_inc));
1560 if (geom_mask & GDK_HINT_ASPECT)
1562 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1563 geometry->min_aspect, geometry->max_aspect));
1566 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1568 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1571 update_style_bits (window);
1575 gdk_win32_window_set_title (GdkWindow *window,
1580 g_return_if_fail (GDK_IS_WINDOW (window));
1581 g_return_if_fail (title != NULL);
1583 if (GDK_WINDOW_DESTROYED (window))
1586 /* Empty window titles not allowed, so set it to just a period. */
1590 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1591 GDK_WINDOW_HWND (window), title));
1593 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1595 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1596 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1599 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1603 gdk_win32_window_set_role (GdkWindow *window,
1606 g_return_if_fail (GDK_IS_WINDOW (window));
1608 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1609 GDK_WINDOW_HWND (window),
1610 (role ? role : "NULL")));
1615 gdk_win32_window_set_transient_for (GdkWindow *window,
1618 HWND window_id, parent_id;
1619 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1620 GdkWindowImplWin32 *parent_impl = NULL;
1623 g_return_if_fail (GDK_IS_WINDOW (window));
1625 window_id = GDK_WINDOW_HWND (window);
1626 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1628 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1630 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1632 if (GDK_WINDOW_DESTROYED (window))
1633 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1635 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1640 if (window->window_type == GDK_WINDOW_CHILD)
1642 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1648 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (window_impl->transient_owner->impl);
1649 if (trans_impl->transient_children != NULL)
1651 item = g_slist_find (trans_impl->transient_children, window);
1653 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1654 trans_impl->num_transients--;
1656 if (!trans_impl->num_transients)
1658 trans_impl->transient_children = NULL;
1661 g_object_unref (G_OBJECT (window_impl->transient_owner));
1662 g_object_unref (G_OBJECT (window));
1664 window_impl->transient_owner = NULL;
1668 parent_impl = GDK_WINDOW_IMPL_WIN32 (parent->impl);
1670 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1671 g_object_ref (G_OBJECT (window));
1672 parent_impl->num_transients++;
1673 window_impl->transient_owner = parent;
1674 g_object_ref (G_OBJECT (parent));
1677 /* This changes the *owner* of the window, despite the misleading
1678 * name. (Owner and parent are unrelated concepts.) At least that's
1679 * what people who seem to know what they talk about say on
1680 * USENET. Search on Google.
1683 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1684 GetLastError () != 0)
1685 WIN32_API_FAILED ("SetWindowLongPtr");
1689 _gdk_push_modal_window (GdkWindow *window)
1691 modal_window_stack = g_slist_prepend (modal_window_stack,
1696 _gdk_remove_modal_window (GdkWindow *window)
1700 g_return_if_fail (window != NULL);
1702 /* It's possible to be NULL here if someone sets the modal hint of the window
1703 * to FALSE before a modal window stack has ever been created. */
1704 if (modal_window_stack == NULL)
1707 /* Find the requested window in the stack and remove it. Yeah, I realize this
1708 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1709 tmp = g_slist_find (modal_window_stack, window);
1712 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1717 _gdk_modal_current (void)
1719 if (modal_window_stack != NULL)
1721 GSList *tmp = modal_window_stack;
1723 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (GDK_WINDOW (tmp->data)))
1725 tmp = g_slist_next (tmp);
1728 return tmp != NULL ? tmp->data : NULL;
1737 gdk_win32_window_set_background (GdkWindow *window,
1738 cairo_pattern_t *pattern)
1743 gdk_win32_window_set_device_cursor (GdkWindow *window,
1747 GdkWindowImplWin32 *impl;
1748 GdkWin32Cursor *cursor_private;
1750 HCURSOR hprevcursor;
1752 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1753 cursor_private = (GdkWin32Cursor*) cursor;
1755 if (GDK_WINDOW_DESTROYED (window))
1761 hcursor = cursor_private->hcursor;
1763 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1764 GDK_WINDOW_HWND (window),
1767 /* First get the old cursor, if any (we wait to free the old one
1768 * since it may be the current cursor set in the Win32 API right
1771 hprevcursor = impl->hcursor;
1773 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
1775 if (hcursor == NULL)
1776 impl->hcursor = NULL;
1779 /* We must copy the cursor as it is OK to destroy the GdkCursor
1780 * while still in use for some window. See for instance
1781 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1782 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1785 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1786 WIN32_API_FAILED ("CopyCursor");
1787 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1788 hcursor, impl->hcursor));
1791 /* Destroy the previous cursor */
1792 if (hprevcursor != NULL)
1794 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1795 API_CALL (DestroyCursor, (hprevcursor));
1800 gdk_win32_window_get_geometry (GdkWindow *window,
1809 if (!GDK_WINDOW_DESTROYED (window))
1813 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1815 if (window != _gdk_root)
1818 GdkWindow *parent = gdk_window_get_parent (window);
1822 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1823 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1829 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1830 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1834 if (parent == _gdk_root)
1836 rect.left += _gdk_offset_x;
1837 rect.top += _gdk_offset_y;
1838 rect.right += _gdk_offset_x;
1839 rect.bottom += _gdk_offset_y;
1848 *width = rect.right - rect.left;
1850 *height = rect.bottom - rect.top;
1852 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
1853 GDK_WINDOW_HWND (window),
1854 rect.right - rect.left, rect.bottom - rect.top,
1855 gdk_window_get_visual (window)->depth,
1856 rect.left, rect.top));
1861 gdk_win32_window_get_root_coords (GdkWindow *window,
1873 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1878 *root_x = tx + _gdk_offset_x;
1880 *root_y = ty + _gdk_offset_y;
1882 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
1883 GDK_WINDOW_HWND (window),
1885 tx + _gdk_offset_x, ty + _gdk_offset_y));
1890 gdk_win32_window_restack_under (GdkWindow *window,
1891 GList *native_siblings)
1897 gdk_win32_window_restack_toplevel (GdkWindow *window,
1905 gdk_win32_window_get_root_origin (GdkWindow *window,
1911 g_return_if_fail (GDK_IS_WINDOW (window));
1913 gdk_window_get_frame_extents (window, &rect);
1921 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
1922 GDK_WINDOW_HWND (window), rect.x, rect.y));
1926 gdk_win32_window_get_frame_extents (GdkWindow *window,
1932 g_return_if_fail (GDK_IS_WINDOW (window));
1933 g_return_if_fail (rect != NULL);
1940 if (GDK_WINDOW_DESTROYED (window))
1943 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
1944 * necessary to walk its parent chain?
1946 while (window->parent && window->parent->parent)
1947 window = window->parent;
1949 hwnd = GDK_WINDOW_HWND (window);
1950 API_CALL (GetWindowRect, (hwnd, &r));
1952 rect->x = r.left + _gdk_offset_x;
1953 rect->y = r.top + _gdk_offset_y;
1954 rect->width = r.right - r.left;
1955 rect->height = r.bottom - r.top;
1957 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
1958 GDK_WINDOW_HWND (window),
1959 r.right - r.left, r.bottom - r.top,
1964 gdk_window_win32_get_device_state (GdkWindow *window,
1968 GdkModifierType *mask)
1972 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
1974 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
1978 return (child != NULL);
1982 _gdk_windowing_get_device_state (GdkDisplay *display,
1987 GdkModifierType *mask)
1989 g_return_if_fail (display == _gdk_display);
1992 *screen = _gdk_screen;
1994 GDK_DEVICE_GET_CLASS (device)->query_state (device,
1995 gdk_screen_get_root_window (_gdk_screen),
2003 gdk_display_warp_device (GdkDisplay *display,
2009 g_return_if_fail (display == _gdk_display);
2010 g_return_if_fail (screen == _gdk_screen);
2011 g_return_if_fail (GDK_IS_DEVICE (device));
2012 g_return_if_fail (display == gdk_device_get_display (device));
2014 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
2018 _gdk_windowing_window_at_device_position (GdkDisplay *display,
2022 GdkModifierType *mask,
2023 gboolean get_toplevel)
2025 return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
2029 gdk_win32_window_get_events (GdkWindow *window)
2031 GdkWindowImplWin32 *impl;
2033 if (GDK_WINDOW_DESTROYED (window))
2036 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2038 return impl->native_event_mask;
2042 gdk_win32_window_set_events (GdkWindow *window,
2043 GdkEventMask event_mask)
2045 GdkWindowImplWin32 *impl;
2047 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2049 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2050 * set it here, too. Not that I know or remember why it is
2051 * necessary, will have to test some day.
2053 impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
2057 do_shape_combine_region (GdkWindow *window,
2063 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2064 _gdk_win32_adjust_client_rect (window, &rect);
2066 OffsetRgn (hrgn, -rect.left, -rect.top);
2067 OffsetRgn (hrgn, x, y);
2069 /* If this is a top-level window, add the title bar to the region */
2070 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2072 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2073 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2077 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2081 gdk_win32_window_set_override_redirect (GdkWindow *window,
2082 gboolean override_redirect)
2084 g_return_if_fail (GDK_IS_WINDOW (window));
2086 g_warning ("gdk_window_set_override_redirect not implemented");
2090 gdk_win32_window_set_accept_focus (GdkWindow *window,
2091 gboolean accept_focus)
2093 g_return_if_fail (GDK_IS_WINDOW (window));
2095 accept_focus = accept_focus != FALSE;
2097 if (window->accept_focus != accept_focus)
2098 window->accept_focus = accept_focus;
2102 gdk_win32_window_set_focus_on_map (GdkWindow *window,
2103 gboolean focus_on_map)
2105 g_return_if_fail (GDK_IS_WINDOW (window));
2107 focus_on_map = focus_on_map != FALSE;
2109 if (window->focus_on_map != focus_on_map)
2110 window->focus_on_map = focus_on_map;
2114 gdk_win32_window_set_icon_list (GdkWindow *window,
2117 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2118 gint big_diff, small_diff;
2119 gint big_w, big_h, small_w, small_h;
2122 HICON small_hicon, big_hicon;
2123 GdkWindowImplWin32 *impl;
2124 gint i, big_i, small_i;
2126 g_return_if_fail (GDK_IS_WINDOW (window));
2128 if (GDK_WINDOW_DESTROYED (window))
2131 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2133 /* ideal sizes for small and large icons */
2134 big_w = GetSystemMetrics (SM_CXICON);
2135 big_h = GetSystemMetrics (SM_CYICON);
2136 small_w = GetSystemMetrics (SM_CXSMICON);
2137 small_h = GetSystemMetrics (SM_CYSMICON);
2139 /* find closest sized icons in the list */
2141 small_pixbuf = NULL;
2147 pixbuf = (GdkPixbuf*) pixbufs->data;
2148 w = gdk_pixbuf_get_width (pixbuf);
2149 h = gdk_pixbuf_get_height (pixbuf);
2151 dw = ABS (w - big_w);
2152 dh = ABS (h - big_h);
2153 diff = dw*dw + dh*dh;
2154 if (big_pixbuf == NULL || diff < big_diff)
2156 big_pixbuf = pixbuf;
2161 dw = ABS (w - small_w);
2162 dh = ABS (h - small_h);
2163 diff = dw*dw + dh*dh;
2164 if (small_pixbuf == NULL || diff < small_diff)
2166 small_pixbuf = pixbuf;
2171 pixbufs = g_list_next (pixbufs);
2175 /* Create the icons */
2176 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2177 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2180 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2182 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2183 (LPARAM)small_hicon);
2185 /* Store the icons, destroying any previous icons */
2186 if (impl->hicon_big)
2187 GDI_CALL (DestroyIcon, (impl->hicon_big));
2188 impl->hicon_big = big_hicon;
2189 if (impl->hicon_small)
2190 GDI_CALL (DestroyIcon, (impl->hicon_small));
2191 impl->hicon_small = small_hicon;
2195 gdk_win32_window_set_icon_name (GdkWindow *window,
2198 /* In case I manage to confuse this again (or somebody else does):
2199 * Please note that "icon name" here really *does* mean the name or
2200 * title of an window minimized as an icon on the desktop, or in the
2201 * taskbar. It has nothing to do with the freedesktop.org icon
2205 g_return_if_fail (GDK_IS_WINDOW (window));
2207 if (GDK_WINDOW_DESTROYED (window))
2211 /* This is not the correct thing to do. We should keep both the
2212 * "normal" window title, and the icon name. When the window is
2213 * minimized, call SetWindowText() with the icon name, and when the
2214 * window is restored, with the normal window title. Also, the name
2215 * is in UTF-8, so we should do the normal conversion to either wide
2216 * chars or system codepage, and use either the W or A version of
2217 * SetWindowText(), depending on Windows version.
2219 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2224 gdk_win32_window_get_group (GdkWindow *window)
2226 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2227 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2229 if (GDK_WINDOW_DESTROYED (window))
2232 g_warning ("gdk_window_get_group not yet implemented");
2238 gdk_win32_window_set_group (GdkWindow *window,
2241 g_return_if_fail (GDK_IS_WINDOW (window));
2242 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2243 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2245 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2248 g_warning ("gdk_window_set_group not implemented");
2252 update_single_bit (LONG *style,
2257 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2258 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2259 * bit indicate whether style_bit is on
2261 if ((!all && gdk_bit) || (all && !gdk_bit))
2262 *style |= style_bit;
2264 *style &= ~style_bit;
2268 update_style_bits (GdkWindow *window)
2270 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
2271 GdkWMDecoration decorations;
2272 LONG old_style, new_style, old_exstyle, new_exstyle;
2274 RECT rect, before, after;
2276 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2277 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2279 GetClientRect (GDK_WINDOW_HWND (window), &before);
2281 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2283 new_style = old_style;
2284 new_exstyle = old_exstyle;
2286 if (window->window_type == GDK_WINDOW_TEMP ||
2287 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2288 new_exstyle |= WS_EX_TOOLWINDOW;
2290 new_exstyle &= ~WS_EX_TOOLWINDOW;
2292 if (get_effective_window_decorations (window, &decorations))
2294 all = (decorations & GDK_DECOR_ALL);
2295 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2296 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2297 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2298 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2299 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2300 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2303 if (old_style == new_style && old_exstyle == new_exstyle )
2305 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2306 GDK_WINDOW_HWND (window)));
2310 if (old_style != new_style)
2312 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2313 GDK_WINDOW_HWND (window),
2314 _gdk_win32_window_style_to_string (old_style),
2315 _gdk_win32_window_style_to_string (new_style)));
2317 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2320 if (old_exstyle != new_exstyle)
2322 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2323 GDK_WINDOW_HWND (window),
2324 _gdk_win32_window_exstyle_to_string (old_exstyle),
2325 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2327 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2330 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2332 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2333 rect.left += after.left - before.left;
2334 rect.top += after.top - before.top;
2335 rect.right += after.right - before.right;
2336 rect.bottom += after.bottom - before.bottom;
2338 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2339 rect.left, rect.top,
2340 rect.right - rect.left, rect.bottom - rect.top,
2341 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2342 SWP_NOREPOSITION | SWP_NOZORDER);
2347 update_single_system_menu_entry (HMENU hmenu,
2352 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2353 * gdk_bit indicates whether menu entry is disabled; if all is
2354 * FALSE, gdk bit indicate whether menu entry is enabled
2356 if ((!all && gdk_bit) || (all && !gdk_bit))
2357 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2359 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2363 update_system_menu (GdkWindow *window)
2365 GdkWMFunction functions;
2368 if (_gdk_window_get_functions (window, &functions))
2370 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2372 all = (functions & GDK_FUNC_ALL);
2373 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2374 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2375 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2376 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2377 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2382 get_decorations_quark ()
2384 static GQuark quark = 0;
2387 quark = g_quark_from_static_string ("gdk-window-decorations");
2393 gdk_win32_window_set_decorations (GdkWindow *window,
2394 GdkWMDecoration decorations)
2396 GdkWMDecoration* decorations_copy;
2398 g_return_if_fail (GDK_IS_WINDOW (window));
2400 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2401 GDK_WINDOW_HWND (window),
2402 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2403 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2404 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2405 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2406 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2407 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2408 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2410 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2411 *decorations_copy = decorations;
2412 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2414 update_style_bits (window);
2418 gdk_win32_window_get_decorations (GdkWindow *window,
2419 GdkWMDecoration *decorations)
2421 GdkWMDecoration* decorations_set;
2423 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2425 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2426 if (decorations_set)
2427 *decorations = *decorations_set;
2429 return (decorations_set != NULL);
2433 get_functions_quark ()
2435 static GQuark quark = 0;
2438 quark = g_quark_from_static_string ("gdk-window-functions");
2444 gdk_win32_window_set_functions (GdkWindow *window,
2445 GdkWMFunction functions)
2447 GdkWMFunction* functions_copy;
2449 g_return_if_fail (GDK_IS_WINDOW (window));
2451 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2452 GDK_WINDOW_HWND (window),
2453 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2454 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2455 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2456 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2457 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2458 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2460 functions_copy = g_malloc (sizeof (GdkWMFunction));
2461 *functions_copy = functions;
2462 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2464 update_system_menu (window);
2468 _gdk_window_get_functions (GdkWindow *window,
2469 GdkWMFunction *functions)
2471 GdkWMDecoration* functions_set;
2473 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2475 *functions = *functions_set;
2477 return (functions_set != NULL);
2481 gdk_win32_window_set_static_gravities (GdkWindow *window,
2482 gboolean use_static)
2484 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2490 gdk_win32_window_begin_resize_drag (GdkWindow *window,
2500 g_return_if_fail (GDK_IS_WINDOW (window));
2502 if (GDK_WINDOW_DESTROYED (window))
2505 /* Tell Windows to start interactively resizing the window by pretending that
2506 * the left pointer button was clicked in the suitable edge or corner. This
2507 * will only work if the button is down when this function is called, and
2508 * will only work with button 1 (left), since Windows only allows window
2509 * dragging using the left mouse button.
2514 /* Must break the automatic grab that occured when the button was
2515 * pressed, otherwise it won't work.
2517 gdk_display_pointer_ungrab (_gdk_display, 0);
2521 case GDK_WINDOW_EDGE_NORTH_WEST:
2522 winedge = HTTOPLEFT;
2525 case GDK_WINDOW_EDGE_NORTH:
2529 case GDK_WINDOW_EDGE_NORTH_EAST:
2530 winedge = HTTOPRIGHT;
2533 case GDK_WINDOW_EDGE_WEST:
2537 case GDK_WINDOW_EDGE_EAST:
2541 case GDK_WINDOW_EDGE_SOUTH_WEST:
2542 winedge = HTBOTTOMLEFT;
2545 case GDK_WINDOW_EDGE_SOUTH:
2549 case GDK_WINDOW_EDGE_SOUTH_EAST:
2551 winedge = HTBOTTOMRIGHT;
2555 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2556 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2560 gdk_win32_window_begin_move_drag (GdkWindow *window,
2567 g_return_if_fail (GDK_IS_WINDOW (window));
2569 if (GDK_WINDOW_DESTROYED (window))
2572 /* Tell Windows to start interactively moving the window by pretending that
2573 * the left pointer button was clicked in the titlebar. This will only work
2574 * if the button is down when this function is called, and will only work
2575 * with button 1 (left), since Windows only allows window dragging using the
2576 * left mouse button.
2581 /* Must break the automatic grab that occured when the button was pressed,
2582 * otherwise it won't work.
2584 gdk_display_pointer_ungrab (_gdk_display, 0);
2586 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2587 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2592 * Setting window states
2595 gdk_win32_window_iconify (GdkWindow *window)
2597 HWND old_active_window;
2599 g_return_if_fail (GDK_IS_WINDOW (window));
2601 if (GDK_WINDOW_DESTROYED (window))
2604 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2605 GDK_WINDOW_HWND (window),
2606 _gdk_win32_window_state_to_string (window->state)));
2608 if (GDK_WINDOW_IS_MAPPED (window))
2610 old_active_window = GetActiveWindow ();
2611 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2612 if (old_active_window != GDK_WINDOW_HWND (window))
2613 SetActiveWindow (old_active_window);
2617 gdk_synthesize_window_state (window,
2619 GDK_WINDOW_STATE_ICONIFIED);
2624 gdk_win32_window_deiconify (GdkWindow *window)
2626 g_return_if_fail (GDK_IS_WINDOW (window));
2628 if (GDK_WINDOW_DESTROYED (window))
2631 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2632 GDK_WINDOW_HWND (window),
2633 _gdk_win32_window_state_to_string (window->state)));
2635 if (GDK_WINDOW_IS_MAPPED (window))
2637 show_window_internal (window, FALSE, TRUE);
2641 gdk_synthesize_window_state (window,
2642 GDK_WINDOW_STATE_ICONIFIED,
2648 gdk_win32_window_stick (GdkWindow *window)
2650 g_return_if_fail (GDK_IS_WINDOW (window));
2652 if (GDK_WINDOW_DESTROYED (window))
2655 /* FIXME: Do something? */
2659 gdk_win32_window_unstick (GdkWindow *window)
2661 g_return_if_fail (GDK_IS_WINDOW (window));
2663 if (GDK_WINDOW_DESTROYED (window))
2666 /* FIXME: Do something? */
2670 gdk_win32_window_maximize (GdkWindow *window)
2672 g_return_if_fail (GDK_IS_WINDOW (window));
2674 if (GDK_WINDOW_DESTROYED (window))
2677 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2678 GDK_WINDOW_HWND (window),
2679 _gdk_win32_window_state_to_string (window->state)));
2681 if (GDK_WINDOW_IS_MAPPED (window))
2682 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2684 gdk_synthesize_window_state (window,
2686 GDK_WINDOW_STATE_MAXIMIZED);
2690 gdk_win32_window_unmaximize (GdkWindow *window)
2692 g_return_if_fail (GDK_IS_WINDOW (window));
2694 if (GDK_WINDOW_DESTROYED (window))
2697 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2698 GDK_WINDOW_HWND (window),
2699 _gdk_win32_window_state_to_string (window->state)));
2701 if (GDK_WINDOW_IS_MAPPED (window))
2702 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2704 gdk_synthesize_window_state (window,
2705 GDK_WINDOW_STATE_MAXIMIZED,
2709 typedef struct _FullscreenInfo FullscreenInfo;
2711 struct _FullscreenInfo
2719 gdk_win32_window_fullscreen (GdkWindow *window)
2721 gint x, y, width, height;
2726 g_return_if_fail (GDK_IS_WINDOW (window));
2728 fi = g_new (FullscreenInfo, 1);
2730 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2734 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2736 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
2737 mi.cbSize = sizeof (mi);
2738 if (monitor && GetMonitorInfo (monitor, &mi))
2740 x = mi.rcMonitor.left;
2741 y = mi.rcMonitor.top;
2742 width = mi.rcMonitor.right - x;
2743 height = mi.rcMonitor.bottom - y;
2748 width = GetSystemMetrics (SM_CXSCREEN);
2749 height = GetSystemMetrics (SM_CYSCREEN);
2752 /* remember for restoring */
2753 fi->hint_flags = impl->hint_flags;
2754 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
2755 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
2756 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2758 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2759 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
2761 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
2762 x, y, width, height,
2763 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2765 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2770 gdk_win32_window_unfullscreen (GdkWindow *window)
2774 g_return_if_fail (GDK_IS_WINDOW (window));
2776 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
2779 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2781 impl->hint_flags = fi->hint_flags;
2782 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
2783 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
2784 fi->r.left, fi->r.top,
2785 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
2786 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2788 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
2791 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2796 gdk_win32_window_set_keep_above (GdkWindow *window,
2799 g_return_if_fail (GDK_IS_WINDOW (window));
2801 if (GDK_WINDOW_DESTROYED (window))
2804 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
2805 GDK_WINDOW_HWND (window),
2806 setting ? "YES" : "NO"));
2808 if (GDK_WINDOW_IS_MAPPED (window))
2810 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2811 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
2813 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2816 gdk_synthesize_window_state (window,
2817 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
2818 setting ? GDK_WINDOW_STATE_ABOVE : 0);
2822 gdk_win32_window_set_keep_below (GdkWindow *window,
2825 g_return_if_fail (GDK_IS_WINDOW (window));
2827 if (GDK_WINDOW_DESTROYED (window))
2830 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
2831 GDK_WINDOW_HWND (window),
2832 setting ? "YES" : "NO"));
2834 if (GDK_WINDOW_IS_MAPPED (window))
2836 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2837 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
2839 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2842 gdk_synthesize_window_state (window,
2843 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
2844 setting ? GDK_WINDOW_STATE_BELOW : 0);
2848 gdk_win32_window_focus (GdkWindow *window,
2851 g_return_if_fail (GDK_IS_WINDOW (window));
2853 if (GDK_WINDOW_DESTROYED (window))
2856 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
2857 GDK_WINDOW_HWND (window),
2858 _gdk_win32_window_state_to_string (window->state)));
2860 if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
2861 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
2863 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2864 SetFocus (GDK_WINDOW_HWND (window));
2868 gdk_win32_window_set_modal_hint (GdkWindow *window,
2871 g_return_if_fail (GDK_IS_WINDOW (window));
2873 if (GDK_WINDOW_DESTROYED (window))
2876 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
2877 GDK_WINDOW_HWND (window),
2878 modal ? "YES" : "NO"));
2880 if (modal == window->modal_hint)
2883 window->modal_hint = modal;
2886 /* Not sure about this one.. -- Cody */
2887 if (GDK_WINDOW_IS_MAPPED (window))
2888 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2889 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
2891 SWP_NOMOVE | SWP_NOSIZE));
2896 _gdk_push_modal_window (window);
2897 gdk_window_raise (window);
2901 _gdk_remove_modal_window (window);
2908 gdk_win32_window_set_skip_taskbar_hint (GdkWindow *window,
2909 gboolean skips_taskbar)
2911 static GdkWindow *owner = NULL;
2914 g_return_if_fail (GDK_IS_WINDOW (window));
2916 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
2917 GDK_WINDOW_HWND (window),
2918 skips_taskbar ? "YES" : "NO"));
2920 // ### TODO: Need to figure out what to do here.
2928 wa.window_type = GDK_WINDOW_TEMP;
2929 wa.wclass = GDK_INPUT_OUTPUT;
2930 wa.width = wa.height = 1;
2932 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
2936 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
2938 #if 0 /* Should we also turn off the minimize and maximize buttons? */
2939 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2940 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
2942 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2944 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2945 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2950 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
2955 gdk_win32_window_set_skip_pager_hint (GdkWindow *window,
2956 gboolean skips_pager)
2958 g_return_if_fail (GDK_IS_WINDOW (window));
2960 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
2961 GDK_WINDOW_HWND (window),
2962 skips_pager ? "YES" : "NO"));
2966 gdk_win32_window_set_type_hint (GdkWindow *window,
2967 GdkWindowTypeHint hint)
2969 g_return_if_fail (GDK_IS_WINDOW (window));
2971 if (GDK_WINDOW_DESTROYED (window))
2976 static GEnumClass *class = NULL;
2978 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
2979 g_print ("gdk_window_set_type_hint: %p: %s\n",
2980 GDK_WINDOW_HWND (window),
2981 g_enum_get_value (class, hint)->value_name);
2984 ((GdkWindowImplWin32 *)window->impl)->type_hint = hint;
2986 update_style_bits (window);
2989 static GdkWindowTypeHint
2990 gdk_win32_window_get_type_hint (GdkWindow *window)
2992 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2994 if (GDK_WINDOW_DESTROYED (window))
2995 return GDK_WINDOW_TYPE_HINT_NORMAL;
2997 return GDK_WINDOW_IMPL_WIN32 (window->impl)->type_hint;
3001 cairo_region_to_hrgn (const cairo_region_t *region,
3008 cairo_rectangle_int_t r;
3009 const int nrects = cairo_region_num_rectangles (region);
3011 sizeof (RGNDATAHEADER) + (sizeof (RECT) * nrects);
3014 rgndata = g_malloc (nbytes);
3015 rgndata->rdh.dwSize = sizeof (RGNDATAHEADER);
3016 rgndata->rdh.iType = RDH_RECTANGLES;
3017 rgndata->rdh.nCount = rgndata->rdh.nRgnSize = 0;
3018 SetRect (&rgndata->rdh.rcBound,
3019 G_MAXLONG, G_MAXLONG, G_MINLONG, G_MINLONG);
3021 for (i = 0; i < nrects; i++)
3023 rect = ((RECT *) rgndata->Buffer) + rgndata->rdh.nCount++;
3025 cairo_region_get_rectangle (region, i, &r);
3026 rect->left = r.x + x_origin;
3027 rect->right = rect->left + r.width;
3028 rect->top = r.y + y_origin;
3029 rect->bottom = rect->top + r.height;
3031 if (rect->left < rgndata->rdh.rcBound.left)
3032 rgndata->rdh.rcBound.left = rect->left;
3033 if (rect->right > rgndata->rdh.rcBound.right)
3034 rgndata->rdh.rcBound.right = rect->right;
3035 if (rect->top < rgndata->rdh.rcBound.top)
3036 rgndata->rdh.rcBound.top = rect->top;
3037 if (rect->bottom > rgndata->rdh.rcBound.bottom)
3038 rgndata->rdh.rcBound.bottom = rect->bottom;
3040 if ((hrgn = ExtCreateRegion (NULL, nbytes, rgndata)) == NULL)
3041 WIN32_API_FAILED ("ExtCreateRegion");
3049 gdk_win32_window_shape_combine_region (GdkWindow *window,
3050 const cairo_region_t *shape_region,
3054 if (GDK_WINDOW_DESTROYED (window))
3059 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3060 GDK_WINDOW_HWND (window)));
3061 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3067 hrgn = cairo_region_to_hrgn (shape_region, 0, 0);
3069 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3070 GDK_WINDOW_HWND (window),
3073 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3078 gdk_win32_window_lookup_for_display (GdkDisplay *display,
3081 g_return_val_if_fail (display == _gdk_display, NULL);
3083 return (GdkWindow*) gdk_win32_handle_table_lookup (anid);
3087 gdk_win32_window_enable_synchronized_configure (GdkWindow *window)
3089 /* nothing - no window manager to cooperate with */
3093 gdk_win32_window_configure_finished (GdkWindow *window)
3095 /* nothing - no window manager to cooperate with */
3099 gdk_win32_window_set_opacity (GdkWindow *window,
3103 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3104 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3106 g_return_if_fail (GDK_IS_WINDOW (window));
3107 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3109 if (GDK_WINDOW_DESTROYED (window))
3114 else if (opacity > 1)
3117 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3119 if (!(exstyle & WS_EX_LAYERED))
3120 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3122 exstyle | WS_EX_LAYERED));
3124 setLayeredWindowAttributes =
3125 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3127 if (setLayeredWindowAttributes)
3129 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3136 static cairo_region_t *
3137 gdk_win32_window_get_shape (GdkWindow *window)
3139 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3140 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3142 if (type == SIMPLEREGION || type == COMPLEXREGION)
3144 cairo_region_t *region = _gdk_win32_hrgn_to_region (hrgn);
3146 DeleteObject (hrgn);
3154 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3155 cairo_region_t *area)
3157 HRGN hrgn = cairo_region_to_hrgn (area, 0, 0);
3159 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3160 GDK_WINDOW_HWND (window),
3161 _gdk_win32_cairo_region_to_string (area)));
3163 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3165 DeleteObject (hrgn);
3170 /* Gets called from gdwindow.c(do_move_region_bits_on_impl)
3171 * and got tested with testgtk::big_window. Given the previous,
3172 * untested implementation this one looks much too simple ;)
3175 _gdk_win32_window_translate (GdkWindow *window,
3176 cairo_region_t *area, /* In impl window coords */
3180 GdkRectangle extents;
3183 cairo_region_get_extents (area, &extents);
3184 rect.left = extents.x - dx;
3185 rect.top = extents.y - dy;
3186 rect.right = rect.left + extents.width;
3187 rect.bottom = rect.top + extents.height;
3189 API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window),
3197 gdk_win32_input_shape_combine_region (GdkWindow *window,
3198 const cairo_region_t *shape_region,
3202 if (GDK_WINDOW_DESTROYED (window))
3204 /* CHECK: are these really supposed to be the same? */
3205 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3209 gdk_win32_window_process_updates_recurse (GdkWindow *window,
3210 cairo_region_t *region)
3212 _gdk_window_process_updates_recurse (window, region);
3216 gdk_win32_window_is_win32 (GdkWindow *window)
3218 return GDK_WINDOW_IS_WIN32 (window);
3222 * _gdk_win32_acquire_dc
3223 * @impl: a Win32 #GdkWindowImplWin32 implementation
3225 * Gets a DC with the given drawable selected into it.
3227 * Return value: The DC, on success. Otherwise
3228 * %NULL. If this function succeeded
3229 * _gdk_win32_impl_release_dc() must be called
3230 * release the DC when you are done using it.
3233 _gdk_win32_impl_acquire_dc (GdkWindowImplWin32 *impl)
3235 if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
3236 GDK_WINDOW_DESTROYED (impl->wrapper))
3241 impl->hdc = GetDC (impl->handle);
3243 WIN32_GDI_FAILED ("GetDC");
3258 * _gdk_win32_impl_release_dc
3259 * @impl: a Win32 #GdkWindowImplWin32 implementation
3261 * Releases the reference count for the DC
3262 * from _gdk_win32_impl_acquire_dc()
3265 _gdk_win32_impl_release_dc (GdkWindowImplWin32 *impl)
3267 g_return_if_fail (impl->hdc_count > 0);
3270 if (impl->hdc_count == 0)
3272 if (impl->saved_dc_bitmap)
3274 GDI_CALL (SelectObject, (impl->hdc, impl->saved_dc_bitmap));
3275 impl->saved_dc_bitmap = NULL;
3280 GDI_CALL (ReleaseDC, (impl->handle, impl->hdc));
3287 gdk_win32_cairo_surface_destroy (void *data)
3289 GdkWindowImplWin32 *impl = data;
3291 _gdk_win32_impl_release_dc (impl);
3292 impl->cairo_surface = NULL;
3295 static cairo_surface_t *
3296 gdk_win32_ref_cairo_surface (GdkWindow *window)
3298 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
3300 if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
3301 GDK_WINDOW_DESTROYED (impl->wrapper))
3304 if (!impl->cairo_surface)
3306 HDC hdc = _gdk_win32_impl_acquire_dc (impl);
3310 impl->cairo_surface = cairo_win32_surface_create (hdc);
3312 cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
3313 impl, gdk_win32_cairo_surface_destroy);
3316 cairo_surface_reference (impl->cairo_surface);
3318 return impl->cairo_surface;
3322 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
3324 GObjectClass *object_class = G_OBJECT_CLASS (klass);
3325 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
3327 parent_class = g_type_class_peek_parent (klass);
3329 object_class->finalize = gdk_window_impl_win32_finalize;
3331 impl_class->ref_cairo_surface = gdk_win32_ref_cairo_surface;
3333 impl_class->show = gdk_win32_window_show;
3334 impl_class->hide = gdk_win32_window_hide;
3335 impl_class->withdraw = gdk_win32_window_withdraw;
3336 impl_class->set_events = gdk_win32_window_set_events;
3337 impl_class->get_events = gdk_win32_window_get_events;
3338 impl_class->raise = gdk_win32_window_raise;
3339 impl_class->lower = gdk_win32_window_lower;
3340 impl_class->restack_under = gdk_win32_window_restack_under;
3341 impl_class->restack_toplevel = gdk_win32_window_restack_toplevel;
3342 impl_class->move_resize = gdk_win32_window_move_resize;
3343 impl_class->set_background = gdk_win32_window_set_background;
3344 impl_class->reparent = gdk_win32_window_reparent;
3345 impl_class->set_device_cursor = gdk_win32_window_set_device_cursor;
3346 impl_class->get_geometry = gdk_win32_window_get_geometry;
3347 impl_class->get_device_state = gdk_window_win32_get_device_state;
3348 impl_class->get_root_coords = gdk_win32_window_get_root_coords;
3350 impl_class->shape_combine_region = gdk_win32_window_shape_combine_region;
3351 impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3352 impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
3353 impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3354 impl_class->translate = _gdk_win32_window_translate;
3355 impl_class->destroy = gdk_win32_window_destroy;
3356 impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
3357 impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
3358 impl_class->get_shape = gdk_win32_window_get_shape;
3359 //FIXME?: impl_class->get_input_shape = gdk_win32_window_get_input_shape;
3361 //impl_class->beep = gdk_x11_window_beep;
3363 impl_class->focus = gdk_win32_window_focus;
3364 impl_class->set_type_hint = gdk_win32_window_set_type_hint;
3365 impl_class->get_type_hint = gdk_win32_window_get_type_hint;
3366 impl_class->set_modal_hint = gdk_win32_window_set_modal_hint;
3367 impl_class->set_skip_taskbar_hint = gdk_win32_window_set_skip_taskbar_hint;
3368 impl_class->set_skip_pager_hint = gdk_win32_window_set_skip_pager_hint;
3369 impl_class->set_urgency_hint = gdk_win32_window_set_urgency_hint;
3370 impl_class->set_geometry_hints = gdk_win32_window_set_geometry_hints;
3371 impl_class->set_title = gdk_win32_window_set_title;
3372 impl_class->set_role = gdk_win32_window_set_role;
3373 //impl_class->set_startup_id = gdk_x11_window_set_startup_id;
3374 impl_class->set_transient_for = gdk_win32_window_set_transient_for;
3375 impl_class->get_root_origin = gdk_win32_window_get_root_origin;
3376 impl_class->get_frame_extents = gdk_win32_window_get_frame_extents;
3377 impl_class->set_override_redirect = gdk_win32_window_set_override_redirect;
3378 impl_class->set_accept_focus = gdk_win32_window_set_accept_focus;
3379 impl_class->set_focus_on_map = gdk_win32_window_set_focus_on_map;
3380 impl_class->set_icon_list = gdk_win32_window_set_icon_list;
3381 impl_class->set_icon_name = gdk_win32_window_set_icon_name;
3382 impl_class->iconify = gdk_win32_window_iconify;
3383 impl_class->deiconify = gdk_win32_window_deiconify;
3384 impl_class->stick = gdk_win32_window_stick;
3385 impl_class->unstick = gdk_win32_window_unstick;
3386 impl_class->maximize = gdk_win32_window_maximize;
3387 impl_class->unmaximize = gdk_win32_window_unmaximize;
3388 impl_class->fullscreen = gdk_win32_window_fullscreen;
3389 impl_class->unfullscreen = gdk_win32_window_unfullscreen;
3390 impl_class->set_keep_above = gdk_win32_window_set_keep_above;
3391 impl_class->set_keep_below = gdk_win32_window_set_keep_below;
3392 impl_class->get_group = gdk_win32_window_get_group;
3393 impl_class->set_group = gdk_win32_window_set_group;
3394 impl_class->set_decorations = gdk_win32_window_set_decorations;
3395 impl_class->get_decorations = gdk_win32_window_get_decorations;
3396 impl_class->set_functions = gdk_win32_window_set_functions;
3398 impl_class->begin_resize_drag = gdk_win32_window_begin_resize_drag;
3399 impl_class->begin_move_drag = gdk_win32_window_begin_move_drag;
3400 impl_class->enable_synchronized_configure = gdk_win32_window_enable_synchronized_configure;
3401 impl_class->configure_finished = gdk_win32_window_configure_finished;
3402 impl_class->set_opacity = gdk_win32_window_set_opacity;
3403 //impl_class->set_composited = gdk_win32_window_set_composited;
3404 impl_class->destroy_notify = gdk_win32_window_destroy_notify;
3405 impl_class->get_drag_protocol = _gdk_win32_window_get_drag_protocol;
3406 impl_class->register_dnd = _gdk_win32_window_register_dnd;
3407 impl_class->drag_begin = _gdk_win32_window_drag_begin;
3408 impl_class->process_updates_recurse = gdk_win32_window_process_updates_recurse;
3409 //? impl_class->sync_rendering = _gdk_win32_window_sync_rendering;
3410 impl_class->simulate_key = _gdk_win32_window_simulate_key;
3411 impl_class->simulate_button = _gdk_win32_window_simulate_button;
3412 impl_class->get_property = _gdk_win32_window_get_property;
3413 impl_class->change_property = _gdk_win32_window_change_property;
3414 impl_class->delete_property = _gdk_win32_window_delete_property;
3418 gdk_win32_window_get_handle (GdkWindow *window)
3420 /* Try to ensure the window has a native window */
3421 if (!_gdk_window_has_impl (window))
3422 gdk_window_ensure_native (window);
3424 if (!GDK_WINDOW_IS_WIN32 (window))
3426 g_warning (G_STRLOC " window is not a native Win32 window");
3430 return GDK_WINDOW_HWND (window);