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;
54 typedef struct _FullscreenInfo FullscreenInfo;
56 struct _FullscreenInfo
63 static void update_style_bits (GdkWindow *window);
64 static gboolean _gdk_window_get_functions (GdkWindow *window,
65 GdkWMFunction *functions);
67 #define WINDOW_IS_TOPLEVEL(window) \
68 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
69 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
70 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
73 GDK_WINDOW_SCREEN (GObject *win)
78 struct _GdkWin32Window {
82 struct _GdkWin32WindowClass {
83 GdkWindowClass parent_class;
86 G_DEFINE_TYPE (GdkWin32Window, gdk_win32_window, GDK_TYPE_WINDOW)
89 gdk_win32_window_class_init (GdkWin32WindowClass *window_class)
94 gdk_win32_window_init (GdkWin32Window *window)
99 G_DEFINE_TYPE (GdkWindowImplWin32, gdk_window_impl_win32, GDK_TYPE_WINDOW_IMPL)
102 _gdk_window_impl_win32_get_type (void)
104 static GType object_type = 0;
108 const GTypeInfo object_info =
110 sizeof (GdkWindowImplWin32Class),
111 (GBaseInitFunc) NULL,
112 (GBaseFinalizeFunc) NULL,
113 (GClassInitFunc) gdk_window_impl_win32_class_init,
114 NULL, /* class_finalize */
115 NULL, /* class_data */
116 sizeof (GdkWindowImplWin32),
118 (GInstanceInitFunc) gdk_window_impl_win32_init,
121 object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
122 "GdkWindowImplWin32",
130 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
132 impl->toplevel_window_type = -1;
133 impl->hcursor = NULL;
134 impl->hicon_big = NULL;
135 impl->hicon_small = NULL;
136 impl->hint_flags = 0;
137 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
138 impl->extension_events_selected = FALSE;
139 impl->transient_owner = NULL;
140 impl->transient_children = NULL;
141 impl->num_transients = 0;
142 impl->changing_state = FALSE;
146 gdk_window_impl_win32_finalize (GObject *object)
149 GdkWindowImplWin32 *window_impl;
151 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
153 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
155 wrapper = window_impl->wrapper;
157 if (!GDK_WINDOW_DESTROYED (wrapper))
159 gdk_win32_handle_table_remove (window_impl->handle);
162 if (window_impl->hcursor != NULL)
164 if (GetCursor () == window_impl->hcursor)
167 GDI_CALL (DestroyCursor, (window_impl->hcursor));
168 window_impl->hcursor = NULL;
171 if (window_impl->hicon_big != NULL)
173 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
174 window_impl->hicon_big = NULL;
177 if (window_impl->hicon_small != NULL)
179 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
180 window_impl->hicon_small = NULL;
183 G_OBJECT_CLASS (parent_class)->finalize (object);
187 _gdk_win32_adjust_client_rect (GdkWindow *window,
192 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
193 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
194 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
198 _gdk_root_window_size_init (void)
204 window = GDK_WINDOW (_gdk_root);
205 rect = _gdk_monitors[0].rect;
206 for (i = 1; i < _gdk_num_monitors; i++)
207 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
209 window->width = rect.width;
210 window->height = rect.height;
214 _gdk_windowing_window_init (GdkScreen *screen)
217 GdkWindowImplWin32 *impl_win32;
219 g_assert (_gdk_root == NULL);
221 _gdk_root = _gdk_display_create_window (_gdk_display);
223 window = (GdkWindow *)_gdk_root;
224 window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
225 impl_win32 = GDK_WINDOW_IMPL_WIN32 (window->impl);
226 impl_win32->wrapper = window;
228 window->impl_window = window;
229 window->visual = gdk_screen_get_system_visual (screen);
231 window->window_type = GDK_WINDOW_ROOT;
232 window->depth = gdk_visual_get_system ()->depth;
234 _gdk_root_window_size_init ();
240 /* width and height already initialised in _gdk_root_window_size_init() */
241 window->viewable = TRUE;
243 gdk_win32_handle_table_insert ((HANDLE *) &impl_win32->handle, _gdk_root);
245 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
249 get_default_title (void)
252 title = g_get_application_name ();
254 title = g_get_prgname ();
260 * is a wrapper function for RegisterWindowClassEx.
261 * It creates at least one unique class for every
262 * GdkWindowType. If support for single window-specific icons
263 * is ever needed (e.g Dialog specific), every such window should
267 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
269 static ATOM klassTOPLEVEL = 0;
270 static ATOM klassCHILD = 0;
271 static ATOM klassTEMP = 0;
272 static ATOM klassTEMPSHADOW = 0;
273 static HICON hAppIcon = NULL;
274 static HICON hAppIconSm = NULL;
275 static WNDCLASSEXW wcl;
278 wcl.cbSize = sizeof (WNDCLASSEX);
279 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
280 * on WM_SIZE and WM_MOVE. Flicker, Performance!
282 wcl.lpfnWndProc = _gdk_win32_window_procedure;
285 wcl.hInstance = _gdk_app_hmodule;
289 /* initialize once! */
290 if (0 == hAppIcon && 0 == hAppIconSm)
292 gchar sLoc [MAX_PATH+1];
294 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
296 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
298 if (0 == hAppIcon && 0 == hAppIconSm)
300 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
302 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
307 if (0 == hAppIcon && 0 == hAppIconSm)
309 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
310 GetSystemMetrics (SM_CXICON),
311 GetSystemMetrics (SM_CYICON), 0);
312 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
313 GetSystemMetrics (SM_CXSMICON),
314 GetSystemMetrics (SM_CYSMICON), 0);
319 hAppIcon = hAppIconSm;
320 else if (0 == hAppIconSm)
321 hAppIconSm = hAppIcon;
323 wcl.lpszMenuName = NULL;
325 /* initialize once per class */
327 * HB: Setting the background brush leads to flicker, because we
328 * don't get asked how to clear the background. This is not what
329 * we want, at least not for input_only windows ...
331 #define ONCE_PER_CLASS() \
332 wcl.hIcon = CopyIcon (hAppIcon); \
333 wcl.hIconSm = CopyIcon (hAppIconSm); \
334 wcl.hbrBackground = NULL; \
335 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
339 case GDK_WINDOW_TOPLEVEL:
340 if (0 == klassTOPLEVEL)
342 wcl.lpszClassName = L"gdkWindowToplevel";
345 klassTOPLEVEL = RegisterClassExW (&wcl);
347 klass = klassTOPLEVEL;
350 case GDK_WINDOW_CHILD:
353 wcl.lpszClassName = L"gdkWindowChild";
355 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
357 klassCHILD = RegisterClassExW (&wcl);
362 case GDK_WINDOW_TEMP:
363 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
364 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
365 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
366 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
368 if (klassTEMPSHADOW == 0)
370 wcl.lpszClassName = L"gdkWindowTempShadow";
371 wcl.style |= CS_SAVEBITS;
372 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
373 LOWORD (g_win32_get_windows_version()) == 0x0105)
375 /* Windows XP (5.1) or above */
376 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
379 klassTEMPSHADOW = RegisterClassExW (&wcl);
382 klass = klassTEMPSHADOW;
388 wcl.lpszClassName = L"gdkWindowTemp";
389 wcl.style |= CS_SAVEBITS;
391 klassTEMP = RegisterClassExW (&wcl);
399 g_assert_not_reached ();
405 WIN32_API_FAILED ("RegisterClassExW");
406 g_error ("That is a fatal error");
412 * Create native windows.
414 * With the default Gdk the created windows are mostly toplevel windows.
416 * Placement of the window is derived from the passed in window,
417 * except for toplevel window where OS/Window Manager placement
420 * The visual parameter, is based on GDK_WA_VISUAL if set already.
421 * From attributes the only things used is: colormap, title,
422 * wmclass and type_hint. [1]. We are checking redundant information
423 * and complain if that changes, which would break this implementation
426 * [1] http://mail.gnome.org/archives/gtk-devel-list/2010-August/msg00214.html
429 _gdk_win32_display_create_window_impl (GdkDisplay *display,
431 GdkWindow *real_parent,
433 GdkEventMask event_mask,
434 GdkWindowAttr *attributes,
435 gint attributes_mask)
440 DWORD dwStyle = 0, dwExStyle;
442 GdkWindowImplWin32 *impl;
445 gboolean override_redirect;
446 gint window_width, window_height;
447 gint offset_x = 0, offset_y = 0;
448 gint x, y, real_x = 0, real_y = 0;
449 /* check consistency of redundant information */
450 guint remaining_mask = attributes_mask;
453 g_print ("_gdk_window_impl_new: %s %s\n",
454 (window->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
455 (window->window_type == GDK_WINDOW_CHILD ? "CHILD" :
456 (window->window_type == GDK_WINDOW_TEMP ? "TEMP" :
458 (attributes->wclass == GDK_INPUT_OUTPUT ? "" : "input-only"))
461 /* to ensure to not miss important information some additional check against
462 * attributes which may silently work on X11 */
463 if ((attributes_mask & GDK_WA_X) != 0)
465 g_assert (attributes->x == window->x);
466 remaining_mask &= ~GDK_WA_X;
468 if ((attributes_mask & GDK_WA_Y) != 0)
470 g_assert (attributes->y == window->y);
471 remaining_mask &= ~GDK_WA_Y;
473 override_redirect = FALSE;
474 if ((attributes_mask & GDK_WA_NOREDIR) != 0)
476 override_redirect = !!attributes->override_redirect;
477 remaining_mask &= ~GDK_WA_NOREDIR;
480 if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0)
481 g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X",
482 remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT));
484 hparent = GDK_WINDOW_HWND (real_parent);
486 impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
487 impl->wrapper = GDK_WINDOW (window);
488 window->impl = GDK_WINDOW_IMPL (impl);
490 if (attributes_mask & GDK_WA_VISUAL)
491 g_assert (gdk_screen_get_system_visual (screen) == attributes->visual);
493 impl->extension_events_selected = FALSE;
494 impl->override_redirect = override_redirect;
496 /* wclass is not any longer set always, but if is ... */
497 if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS)
498 g_assert ((attributes->wclass == GDK_INPUT_OUTPUT) == !window->input_only);
500 if (!window->input_only)
506 /* I very much doubt using WS_EX_TRANSPARENT actually
507 * corresponds to how X11 InputOnly windows work, but it appears
508 * to work well enough for the actual use cases in gtk.
510 dwExStyle = WS_EX_TRANSPARENT;
511 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY\n"));
514 switch (window->window_type)
516 case GDK_WINDOW_TOPLEVEL:
517 if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
519 /* The common code warns for this case. */
520 hparent = GetDesktopWindow ();
522 /* Children of foreign windows aren't toplevel windows */
523 if (GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
525 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
529 if (window->window_type == GDK_WINDOW_TOPLEVEL)
530 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
532 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
534 offset_x = _gdk_offset_x;
535 offset_y = _gdk_offset_y;
539 case GDK_WINDOW_CHILD:
540 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
543 case GDK_WINDOW_TEMP:
544 /* A temp window is not necessarily a top level window */
545 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
546 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
547 dwExStyle |= WS_EX_TOOLWINDOW;
548 offset_x = _gdk_offset_x;
549 offset_y = _gdk_offset_y;
553 g_assert_not_reached ();
556 if (window->window_type != GDK_WINDOW_CHILD)
558 rect.left = window->x;
559 rect.top = window->y;
560 rect.right = window->width;
561 rect.bottom = window->height;
563 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
565 real_x = window->x - offset_x;
566 real_y = window->y - offset_y;
568 if (window->window_type == GDK_WINDOW_TOPLEVEL)
570 /* We initially place it at default so that we can get the
571 default window positioning if we want */
572 x = y = CW_USEDEFAULT;
576 /* TEMP, FOREIGN: Put these where requested */
581 window_width = rect.right - rect.left;
582 window_height = rect.bottom - rect.top;
586 /* adjust position relative to real_parent */
587 window_width = window->width;
588 window_height = window->height;
589 /* use given position for initial placement, native coordinates */
590 x = window->x + window->parent->abs_x - offset_x;
591 y = window->y + window->parent->abs_y - offset_y;
594 if (attributes_mask & GDK_WA_TITLE)
595 title = attributes->title;
597 title = get_default_title ();
598 if (!title || !*title)
601 impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
603 if (attributes_mask & GDK_WA_TYPE_HINT)
604 gdk_window_set_type_hint (window, attributes->type_hint);
606 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
607 dwExStyle |= WS_EX_TOOLWINDOW;
609 klass = RegisterGdkClass (window->window_type, impl->type_hint);
611 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
613 hwndNew = CreateWindowExW (dwExStyle,
614 MAKEINTRESOURCEW (klass),
619 window_width, window_height,
624 if (GDK_WINDOW_HWND (window) != hwndNew)
626 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
627 GDK_WINDOW_HWND (window),
630 /* HB: IHMO due to a race condition the handle was increased by
631 * one, which causes much trouble. Because I can't find the
632 * real bug, try to workaround it ...
633 * To reproduce: compile with MSVC 5, DEBUG=1
636 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
637 GDK_WINDOW_HWND (window) = hwndNew;
638 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
640 /* the old behaviour, but with warning */
641 impl->handle = hwndNew;
646 if (window->window_type != GDK_WINDOW_CHILD)
648 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
649 impl->initial_x = rect.left;
650 impl->initial_y = rect.top;
652 /* Now we know the initial position, move to actually specified position */
653 if (real_x != x || real_y != y)
655 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
656 real_x, real_y, 0, 0,
657 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
661 g_object_ref (window);
662 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
664 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
666 window_width, window_height,
667 window->x - offset_x,
668 window->y - offset_y,
670 GDK_WINDOW_HWND (window)));
672 /* Add window handle to title */
673 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
677 if (impl->handle == NULL)
679 WIN32_API_FAILED ("CreateWindowExW");
680 g_object_unref (window);
684 // if (!from_set_skip_taskbar_hint && window->window_type == GDK_WINDOW_TEMP)
685 // gdk_window_set_skip_taskbar_hint (window, TRUE);
687 if (attributes_mask & GDK_WA_CURSOR)
688 gdk_window_set_cursor (window, attributes->cursor);
692 gdk_win32_window_foreign_new_for_display (GdkDisplay *display,
696 GdkWindowImplWin32 *impl;
702 g_return_val_if_fail (display == _gdk_display, NULL);
704 if ((window = gdk_win32_window_lookup_for_display (display, anid)) != NULL)
705 return g_object_ref (window);
707 window = _gdk_display_create_window (display);
708 window->visual = gdk_screen_get_system_visual (_gdk_screen);
709 window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
710 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
711 impl->wrapper = window;
712 parent = GetParent (anid);
714 window->parent = gdk_win32_handle_table_lookup (parent);
715 if (!window->parent || GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_FOREIGN)
716 window->parent = _gdk_root;
718 window->parent->children = g_list_prepend (window->parent->children, window);
720 GetClientRect ((HWND) anid, &rect);
722 point.y = rect.right;
723 ClientToScreen ((HWND) anid, &point);
724 if (parent != GetDesktopWindow ())
725 ScreenToClient (parent, &point);
728 window->width = rect.right - rect.left;
729 window->height = rect.bottom - rect.top;
730 window->window_type = GDK_WINDOW_FOREIGN;
731 window->destroyed = FALSE;
732 window->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
733 if (IsWindowVisible ((HWND) anid))
734 window->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
736 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
737 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
738 window->state |= GDK_WINDOW_STATE_ABOVE;
740 window->state &= (~GDK_WINDOW_STATE_ABOVE);
741 window->state &= (~GDK_WINDOW_STATE_BELOW);
742 window->viewable = TRUE;
744 window->depth = gdk_visual_get_system ()->depth;
746 g_object_ref (window);
747 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
749 GDK_NOTE (MISC, g_print ("gdk_win32_window_foreign_new_for_display: %p: %s@%+d%+d\n",
751 _gdk_win32_window_description (window),
752 window->x, window->y));
758 gdk_win32_window_destroy (GdkWindow *window,
760 gboolean foreign_destroy)
762 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
765 g_return_if_fail (GDK_IS_WINDOW (window));
767 GDK_NOTE (MISC, g_print ("gdk_win32_window_destroy: %p\n",
768 GDK_WINDOW_HWND (window)));
770 /* Remove ourself from the modal stack */
771 _gdk_remove_modal_window (window);
773 /* Remove all our transient children */
774 tmp = window_impl->transient_children;
777 GdkWindow *child = tmp->data;
778 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW (child)->impl);
780 child_impl->transient_owner = NULL;
781 tmp = g_slist_next (tmp);
783 g_slist_free (window_impl->transient_children);
784 window_impl->transient_children = NULL;
786 /* Remove ourself from our transient owner */
787 if (window_impl->transient_owner != NULL)
789 gdk_window_set_transient_for (window, NULL);
792 if (!recursing && !foreign_destroy)
794 window->destroyed = TRUE;
795 DestroyWindow (GDK_WINDOW_HWND (window));
799 static cairo_surface_t *
800 gdk_win32_window_resize_cairo_surface (GdkWindow *window,
801 cairo_surface_t *surface,
805 /* XXX: Make Cairo surface use DC clip */
806 cairo_surface_destroy (surface);
812 gdk_win32_window_destroy_foreign (GdkWindow *window)
814 /* It's somebody else's window, but in our hierarchy, so reparent it
815 * to the desktop, and then try to destroy it.
817 gdk_window_hide (window);
818 gdk_window_reparent (window, NULL, 0, 0);
820 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
823 /* This function is called when the window really gone.
826 gdk_win32_window_destroy_notify (GdkWindow *window)
828 g_return_if_fail (GDK_IS_WINDOW (window));
831 g_print ("gdk_window_destroy_notify: %p%s\n",
832 GDK_WINDOW_HWND (window),
833 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
835 if (!GDK_WINDOW_DESTROYED (window))
837 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
838 g_warning ("window %p unexpectedly destroyed",
839 GDK_WINDOW_HWND (window));
841 _gdk_window_destroy (window, TRUE);
844 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
845 g_object_unref (window);
849 get_outer_rect (GdkWindow *window,
854 rect->left = rect->top = 0;
856 rect->bottom = height;
858 _gdk_win32_adjust_client_rect (window, rect);
862 adjust_for_gravity_hints (GdkWindow *window,
867 GdkWindowImplWin32 *impl;
869 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
871 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
873 gint orig_x = *x, orig_y = *y;
875 switch (impl->hints.win_gravity)
877 case GDK_GRAVITY_NORTH:
878 case GDK_GRAVITY_CENTER:
879 case GDK_GRAVITY_SOUTH:
880 *x -= (outer_rect->right - outer_rect->left) / 2;
881 *x += window->width / 2;
884 case GDK_GRAVITY_SOUTH_EAST:
885 case GDK_GRAVITY_EAST:
886 case GDK_GRAVITY_NORTH_EAST:
887 *x -= outer_rect->right - outer_rect->left;
891 case GDK_GRAVITY_STATIC:
892 *x += outer_rect->left;
899 switch (impl->hints.win_gravity)
901 case GDK_GRAVITY_WEST:
902 case GDK_GRAVITY_CENTER:
903 case GDK_GRAVITY_EAST:
904 *y -= (outer_rect->bottom - outer_rect->top) / 2;
905 *y += window->height / 2;
908 case GDK_GRAVITY_SOUTH_WEST:
909 case GDK_GRAVITY_SOUTH:
910 case GDK_GRAVITY_SOUTH_EAST:
911 *y -= outer_rect->bottom - outer_rect->top;
912 *y += window->height;
915 case GDK_GRAVITY_STATIC:
916 *y += outer_rect->top;
923 (orig_x != *x || orig_y != *y) ?
924 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
925 orig_x, *x, orig_y, *y)
931 show_window_internal (GdkWindow *window,
932 gboolean already_mapped,
935 GdkWindowImplWin32 *window_impl;
936 HWND old_active_window;
937 gboolean focus_on_map = FALSE;
940 if (window->destroyed)
943 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s\n",
944 GDK_WINDOW_HWND (window),
945 _gdk_win32_window_state_to_string (window->state),
946 (deiconify ? " deiconify" : "")));
948 /* If asked to show (not deiconify) an withdrawn and iconified
953 (window->state & GDK_WINDOW_STATE_ICONIFIED))
955 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
959 /* If asked to just show an iconified window, do nothing. */
960 if (!deiconify && (window->state & GDK_WINDOW_STATE_ICONIFIED))
963 /* If asked to deiconify an already noniconified window, do
964 * nothing. (Especially, don't cause the window to rise and
965 * activate. There are different calls for that.)
967 if (deiconify && !(window->state & GDK_WINDOW_STATE_ICONIFIED))
970 /* If asked to show (but not raise) a window that is already
971 * visible, do nothing.
973 if (!deiconify && !already_mapped && IsWindowVisible (GDK_WINDOW_HWND (window)))
979 focus_on_map = window->focus_on_map;
981 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
983 /* Use SetWindowPos to show transparent windows so automatic redraws
984 * in other windows can be suppressed.
986 if (exstyle & WS_EX_TRANSPARENT)
988 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
990 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
991 flags |= SWP_NOACTIVATE;
993 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
998 /* For initial map of "normal" windows we want to emulate WM window
999 * positioning behaviour, which means:
1000 * + Use user specified position if GDK_HINT_POS or GDK_HINT_USER_POS
1002 * + default to the initial CW_USEDEFAULT placement,
1003 * no matter if the user moved the window before showing it.
1004 * + Certain window types and hints have more elaborate positioning
1007 window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1008 if (!already_mapped &&
1009 GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL &&
1010 (window_impl->hint_flags & (GDK_HINT_POS | GDK_HINT_USER_POS)) == 0 &&
1011 !window_impl->override_redirect)
1013 gboolean center = FALSE;
1014 RECT window_rect, center_on_rect;
1017 x = window_impl->initial_x;
1018 y = window_impl->initial_y;
1020 if (window_impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1025 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
1026 mi.cbSize = sizeof (mi);
1027 if (monitor && GetMonitorInfo (monitor, &mi))
1028 center_on_rect = mi.rcMonitor;
1031 center_on_rect.left = 0;
1032 center_on_rect.right = 0;
1033 center_on_rect.right = GetSystemMetrics (SM_CXSCREEN);
1034 center_on_rect.bottom = GetSystemMetrics (SM_CYSCREEN);
1038 else if (window_impl->transient_owner != NULL &&
1039 GDK_WINDOW_IS_MAPPED (window_impl->transient_owner))
1041 GdkWindow *owner = window_impl->transient_owner;
1042 /* Center on transient parent */
1043 center_on_rect.left = owner->x;
1044 center_on_rect.top = owner->y;
1045 center_on_rect.right = center_on_rect.left + owner->width;
1046 center_on_rect.bottom = center_on_rect.top + owner->height;
1047 _gdk_win32_adjust_client_rect (GDK_WINDOW (owner), ¢er_on_rect);
1053 window_rect.left = 0;
1054 window_rect.top = 0;
1055 window_rect.right = window->width;
1056 window_rect.bottom = window->height;
1057 _gdk_win32_adjust_client_rect (window, &window_rect);
1059 x = center_on_rect.left + ((center_on_rect.right - center_on_rect.left) - (window_rect.right - window_rect.left)) / 2;
1060 y = center_on_rect.top + ((center_on_rect.bottom - center_on_rect.top) - (window_rect.bottom - window_rect.top)) / 2;
1063 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1065 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1068 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1070 gdk_window_fullscreen (window);
1072 else if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
1074 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1076 else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
1079 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1081 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1083 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1085 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1089 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1092 /* Sync STATE_ABOVE to TOPMOST */
1093 if (((window->state & GDK_WINDOW_STATE_ABOVE) &&
1094 !(exstyle & WS_EX_TOPMOST)) ||
1095 (!(window->state & GDK_WINDOW_STATE_ABOVE) &&
1096 (exstyle & WS_EX_TOPMOST)))
1098 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
1099 (window->state & GDK_WINDOW_STATE_ABOVE)?HWND_TOPMOST:HWND_NOTOPMOST,
1101 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
1106 gdk_win32_window_show (GdkWindow *window,
1107 gboolean already_mapped)
1109 show_window_internal (window, FALSE, FALSE);
1113 gdk_win32_window_hide (GdkWindow *window)
1115 if (window->destroyed)
1118 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1119 GDK_WINDOW_HWND (window),
1120 _gdk_win32_window_state_to_string (window->state)));
1122 if (GDK_WINDOW_IS_MAPPED (window))
1123 gdk_synthesize_window_state (window,
1125 GDK_WINDOW_STATE_WITHDRAWN);
1127 _gdk_window_clear_update_area (window);
1129 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1130 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1132 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1134 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1136 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1140 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1145 gdk_win32_window_withdraw (GdkWindow *window)
1147 if (window->destroyed)
1150 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1151 GDK_WINDOW_HWND (window),
1152 _gdk_win32_window_state_to_string (window->state)));
1154 gdk_window_hide (window); /* ??? */
1158 gdk_win32_window_move (GdkWindow *window,
1161 GdkWindowImplWin32 *impl;
1163 g_return_if_fail (GDK_IS_WINDOW (window));
1165 if (GDK_WINDOW_DESTROYED (window))
1168 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1169 GDK_WINDOW_HWND (window), x, y));
1171 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1173 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1176 /* Don't check GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD.
1177 * Foreign windows (another app's windows) might be children of our
1178 * windows! Especially in the case of gtkplug/socket.
1180 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1182 _gdk_window_move_resize_child (window, x, y, window->width, window->height);
1188 get_outer_rect (window, window->width, window->height, &outer_rect);
1190 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1192 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1193 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1194 GDK_WINDOW_HWND (window),
1195 x - _gdk_offset_x, y - _gdk_offset_y));
1197 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1198 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1199 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1204 gdk_win32_window_resize (GdkWindow *window,
1205 gint width, gint height)
1207 GdkWindowImplWin32 *impl;
1209 g_return_if_fail (GDK_IS_WINDOW (window));
1211 if (GDK_WINDOW_DESTROYED (window))
1219 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1220 GDK_WINDOW_HWND (window), width, height));
1222 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1224 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1227 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1229 _gdk_window_move_resize_child (window, window->x, window->y, width, height);
1235 get_outer_rect (window, width, height, &outer_rect);
1237 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1238 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1239 GDK_WINDOW_HWND (window),
1240 outer_rect.right - outer_rect.left,
1241 outer_rect.bottom - outer_rect.top));
1243 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1245 outer_rect.right - outer_rect.left,
1246 outer_rect.bottom - outer_rect.top,
1247 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1248 window->resize_count += 1;
1253 gdk_win32_window_move_resize_internal (GdkWindow *window,
1259 GdkWindowImplWin32 *impl;
1261 g_return_if_fail (GDK_IS_WINDOW (window));
1263 if (GDK_WINDOW_DESTROYED (window))
1271 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1273 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1276 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1277 GDK_WINDOW_HWND (window),
1278 width, height, x, y));
1280 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1282 _gdk_window_move_resize_child (window, x, y, width, height);
1288 get_outer_rect (window, width, height, &outer_rect);
1290 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1292 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1293 "NOACTIVATE|NOZORDER)\n",
1294 GDK_WINDOW_HWND (window),
1295 x - _gdk_offset_x, y - _gdk_offset_y,
1296 outer_rect.right - outer_rect.left,
1297 outer_rect.bottom - outer_rect.top));
1299 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1300 x - _gdk_offset_x, y - _gdk_offset_y,
1301 outer_rect.right - outer_rect.left,
1302 outer_rect.bottom - outer_rect.top,
1303 SWP_NOACTIVATE | SWP_NOZORDER));
1308 gdk_win32_window_move_resize (GdkWindow *window,
1315 GdkWindowImplWin32 *window_impl;
1317 window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1318 window_impl->inhibit_configure = TRUE;
1320 /* We ignore changes to the window being moved or resized by the
1321 user, as we don't want to fight the user */
1322 if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
1325 if (with_move && (width < 0 && height < 0))
1327 gdk_win32_window_move (window, x, y);
1333 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1337 gdk_win32_window_resize (window, width, height);
1342 window_impl->inhibit_configure = FALSE;
1344 if (WINDOW_IS_TOPLEVEL (window))
1345 _gdk_win32_emit_configure_event (window);
1349 gdk_win32_window_reparent (GdkWindow *window,
1350 GdkWindow *new_parent,
1355 GdkWindow *old_parent;
1356 GdkWindowImplWin32 *impl;
1357 gboolean was_toplevel;
1361 new_parent = _gdk_root;
1363 old_parent = window->parent;
1364 parent = new_parent;
1365 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1367 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1368 GDK_WINDOW_HWND (window),
1369 GDK_WINDOW_HWND (new_parent)));
1371 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1373 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1374 if (was_toplevel && new_parent != _gdk_root)
1376 /* Reparenting from top-level (child of desktop). Clear out
1379 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1381 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1383 else if (new_parent == _gdk_root)
1385 /* Reparenting to top-level. Add decorations. */
1386 style &= ~(WS_CHILD);
1387 style |= WS_OVERLAPPEDWINDOW;
1388 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1391 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1392 GDK_WINDOW_HWND (new_parent)));
1394 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1395 x, y, window->width, window->height, TRUE));
1397 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1400 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1401 new_parent = _gdk_root;
1403 window->parent = new_parent;
1405 /* Switch the window type as appropriate */
1407 switch (GDK_WINDOW_TYPE (new_parent))
1409 case GDK_WINDOW_ROOT:
1410 if (impl->toplevel_window_type != -1)
1411 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1412 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1413 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1416 case GDK_WINDOW_TOPLEVEL:
1417 case GDK_WINDOW_CHILD:
1418 case GDK_WINDOW_TEMP:
1419 if (WINDOW_IS_TOPLEVEL (window))
1421 /* Save the original window type so we can restore it if the
1422 * window is reparented back to be a toplevel.
1424 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1425 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1430 old_parent->children =
1431 g_list_remove (old_parent->children, window);
1433 parent->children = g_list_prepend (parent->children, window);
1439 gdk_win32_window_raise (GdkWindow *window)
1441 if (!GDK_WINDOW_DESTROYED (window))
1443 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1444 GDK_WINDOW_HWND (window)));
1446 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1447 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1449 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1450 else if (window->accept_focus)
1451 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1453 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1455 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1460 gdk_win32_window_lower (GdkWindow *window)
1462 if (!GDK_WINDOW_DESTROYED (window))
1464 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1465 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1466 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1467 GDK_WINDOW_HWND (window),
1468 GDK_WINDOW_HWND (window)));
1470 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1472 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1477 gdk_win32_window_set_urgency_hint (GdkWindow *window,
1480 FLASHWINFO flashwinfo;
1481 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1482 PFN_FlashWindowEx flashWindowEx = NULL;
1484 g_return_if_fail (GDK_IS_WINDOW (window));
1485 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1487 if (GDK_WINDOW_DESTROYED (window))
1490 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1494 flashwinfo.cbSize = sizeof (flashwinfo);
1495 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1497 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1499 flashwinfo.dwFlags = FLASHW_STOP;
1500 flashwinfo.uCount = 0;
1501 flashwinfo.dwTimeout = 0;
1503 flashWindowEx (&flashwinfo);
1507 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1512 get_effective_window_decorations (GdkWindow *window,
1513 GdkWMDecoration *decoration)
1515 GdkWindowImplWin32 *impl;
1517 impl = (GdkWindowImplWin32 *)window->impl;
1519 if (gdk_window_get_decorations (window, decoration))
1522 if (window->window_type != GDK_WINDOW_TOPLEVEL)
1527 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1528 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1529 impl->hints.min_width == impl->hints.max_width &&
1530 impl->hints.min_height == impl->hints.max_height)
1532 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1534 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1535 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1536 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1538 *decoration |= GDK_DECOR_MINIMIZE;
1540 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1542 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1547 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1549 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1550 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1551 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1552 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1554 *decoration |= GDK_DECOR_MINIMIZE;
1561 switch (impl->type_hint)
1563 case GDK_WINDOW_TYPE_HINT_DIALOG:
1564 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1567 case GDK_WINDOW_TYPE_HINT_MENU:
1568 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1571 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1572 case GDK_WINDOW_TYPE_HINT_UTILITY:
1573 gdk_window_set_skip_taskbar_hint (window, TRUE);
1574 gdk_window_set_skip_pager_hint (window, TRUE);
1575 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1578 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1579 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1580 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1583 case GDK_WINDOW_TYPE_HINT_DOCK:
1586 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1591 case GDK_WINDOW_TYPE_HINT_NORMAL:
1592 *decoration = GDK_DECOR_ALL;
1601 gdk_win32_window_set_geometry_hints (GdkWindow *window,
1602 const GdkGeometry *geometry,
1603 GdkWindowHints geom_mask)
1605 GdkWindowImplWin32 *impl;
1608 g_return_if_fail (GDK_IS_WINDOW (window));
1610 if (GDK_WINDOW_DESTROYED (window))
1613 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1614 GDK_WINDOW_HWND (window)));
1616 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1618 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
1620 fi->hint_flags = geom_mask;
1622 impl->hint_flags = geom_mask;
1623 impl->hints = *geometry;
1625 if (geom_mask & GDK_HINT_POS)
1626 ; /* even the X11 mplementation doesn't care */
1628 if (geom_mask & GDK_HINT_MIN_SIZE)
1630 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1631 geometry->min_width, geometry->min_height));
1634 if (geom_mask & GDK_HINT_MAX_SIZE)
1636 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1637 geometry->max_width, geometry->max_height));
1640 if (geom_mask & GDK_HINT_BASE_SIZE)
1642 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1643 geometry->base_width, geometry->base_height));
1646 if (geom_mask & GDK_HINT_RESIZE_INC)
1648 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1649 geometry->width_inc, geometry->height_inc));
1652 if (geom_mask & GDK_HINT_ASPECT)
1654 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1655 geometry->min_aspect, geometry->max_aspect));
1658 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1660 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1663 update_style_bits (window);
1667 gdk_win32_window_set_title (GdkWindow *window,
1672 g_return_if_fail (GDK_IS_WINDOW (window));
1673 g_return_if_fail (title != NULL);
1675 if (GDK_WINDOW_DESTROYED (window))
1678 /* Empty window titles not allowed, so set it to just a period. */
1682 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1683 GDK_WINDOW_HWND (window), title));
1685 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1687 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1688 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1691 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1695 gdk_win32_window_set_role (GdkWindow *window,
1698 g_return_if_fail (GDK_IS_WINDOW (window));
1700 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1701 GDK_WINDOW_HWND (window),
1702 (role ? role : "NULL")));
1707 gdk_win32_window_set_transient_for (GdkWindow *window,
1710 HWND window_id, parent_id;
1711 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1712 GdkWindowImplWin32 *parent_impl = NULL;
1715 g_return_if_fail (GDK_IS_WINDOW (window));
1717 window_id = GDK_WINDOW_HWND (window);
1718 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1720 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1722 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1724 if (GDK_WINDOW_DESTROYED (window))
1725 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1727 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1732 if (window->window_type == GDK_WINDOW_CHILD)
1734 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1740 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (window_impl->transient_owner->impl);
1741 if (trans_impl->transient_children != NULL)
1743 item = g_slist_find (trans_impl->transient_children, window);
1745 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1746 trans_impl->num_transients--;
1748 if (!trans_impl->num_transients)
1750 trans_impl->transient_children = NULL;
1753 g_object_unref (G_OBJECT (window_impl->transient_owner));
1754 g_object_unref (G_OBJECT (window));
1756 window_impl->transient_owner = NULL;
1760 parent_impl = GDK_WINDOW_IMPL_WIN32 (parent->impl);
1762 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1763 g_object_ref (G_OBJECT (window));
1764 parent_impl->num_transients++;
1765 window_impl->transient_owner = parent;
1766 g_object_ref (G_OBJECT (parent));
1769 /* This changes the *owner* of the window, despite the misleading
1770 * name. (Owner and parent are unrelated concepts.) At least that's
1771 * what people who seem to know what they talk about say on
1772 * USENET. Search on Google.
1775 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1776 GetLastError () != 0)
1777 WIN32_API_FAILED ("SetWindowLongPtr");
1781 _gdk_push_modal_window (GdkWindow *window)
1783 modal_window_stack = g_slist_prepend (modal_window_stack,
1788 _gdk_remove_modal_window (GdkWindow *window)
1792 g_return_if_fail (window != NULL);
1794 /* It's possible to be NULL here if someone sets the modal hint of the window
1795 * to FALSE before a modal window stack has ever been created. */
1796 if (modal_window_stack == NULL)
1799 /* Find the requested window in the stack and remove it. Yeah, I realize this
1800 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1801 tmp = g_slist_find (modal_window_stack, window);
1804 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1809 _gdk_modal_blocked (GdkWindow *window)
1812 gboolean found_any = FALSE;
1814 for (l = modal_window_stack; l != NULL; l = l->next)
1816 GdkWindow *modal = l->data;
1818 if (modal == window)
1821 if (GDK_WINDOW_IS_MAPPED (modal))
1829 _gdk_modal_current (void)
1833 for (l = modal_window_stack; l != NULL; l = l->next)
1835 GdkWindow *modal = l->data;
1837 if (GDK_WINDOW_IS_MAPPED (modal))
1845 gdk_win32_window_set_background (GdkWindow *window,
1846 cairo_pattern_t *pattern)
1851 gdk_win32_window_set_device_cursor (GdkWindow *window,
1855 GdkWindowImplWin32 *impl;
1856 GdkWin32Cursor *cursor_private;
1858 HCURSOR hprevcursor;
1860 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
1861 cursor_private = (GdkWin32Cursor*) cursor;
1863 if (GDK_WINDOW_DESTROYED (window))
1869 hcursor = cursor_private->hcursor;
1871 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1872 GDK_WINDOW_HWND (window),
1875 /* First get the old cursor, if any (we wait to free the old one
1876 * since it may be the current cursor set in the Win32 API right
1879 hprevcursor = impl->hcursor;
1881 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
1883 if (hcursor == NULL)
1884 impl->hcursor = NULL;
1887 /* We must copy the cursor as it is OK to destroy the GdkCursor
1888 * while still in use for some window. See for instance
1889 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1890 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1893 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1894 WIN32_API_FAILED ("CopyCursor");
1895 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1896 hcursor, impl->hcursor));
1899 /* Destroy the previous cursor */
1900 if (hprevcursor != NULL)
1902 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1903 API_CALL (DestroyCursor, (hprevcursor));
1908 gdk_win32_window_get_geometry (GdkWindow *window,
1917 if (!GDK_WINDOW_DESTROYED (window))
1921 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1923 if (window != _gdk_root)
1926 GdkWindow *parent = gdk_window_get_parent (window);
1930 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1931 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1937 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1938 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1942 if (parent == _gdk_root)
1944 rect.left += _gdk_offset_x;
1945 rect.top += _gdk_offset_y;
1946 rect.right += _gdk_offset_x;
1947 rect.bottom += _gdk_offset_y;
1956 *width = rect.right - rect.left;
1958 *height = rect.bottom - rect.top;
1960 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
1961 GDK_WINDOW_HWND (window),
1962 rect.right - rect.left, rect.bottom - rect.top,
1963 gdk_window_get_visual (window)->depth,
1964 rect.left, rect.top));
1969 gdk_win32_window_get_root_coords (GdkWindow *window,
1981 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1986 *root_x = tx + _gdk_offset_x;
1988 *root_y = ty + _gdk_offset_y;
1990 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
1991 GDK_WINDOW_HWND (window),
1993 tx + _gdk_offset_x, ty + _gdk_offset_y));
1998 gdk_win32_window_restack_under (GdkWindow *window,
1999 GList *native_siblings)
2005 gdk_win32_window_restack_toplevel (GdkWindow *window,
2013 gdk_win32_window_get_root_origin (GdkWindow *window,
2019 g_return_if_fail (GDK_IS_WINDOW (window));
2021 gdk_window_get_frame_extents (window, &rect);
2029 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2030 GDK_WINDOW_HWND (window), rect.x, rect.y));
2034 gdk_win32_window_get_frame_extents (GdkWindow *window,
2040 g_return_if_fail (GDK_IS_WINDOW (window));
2041 g_return_if_fail (rect != NULL);
2048 if (GDK_WINDOW_DESTROYED (window))
2051 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2052 * necessary to walk its parent chain?
2054 while (window->parent && window->parent->parent)
2055 window = window->parent;
2057 hwnd = GDK_WINDOW_HWND (window);
2058 API_CALL (GetWindowRect, (hwnd, &r));
2060 rect->x = r.left + _gdk_offset_x;
2061 rect->y = r.top + _gdk_offset_y;
2062 rect->width = r.right - r.left;
2063 rect->height = r.bottom - r.top;
2065 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2066 GDK_WINDOW_HWND (window),
2067 r.right - r.left, r.bottom - r.top,
2072 gdk_window_win32_get_device_state (GdkWindow *window,
2076 GdkModifierType *mask)
2080 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2082 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
2086 return (child != NULL);
2090 _gdk_windowing_get_device_state (GdkDisplay *display,
2095 GdkModifierType *mask)
2097 g_return_if_fail (display == _gdk_display);
2100 *screen = _gdk_screen;
2102 GDK_DEVICE_GET_CLASS (device)->query_state (device,
2103 gdk_screen_get_root_window (_gdk_screen),
2111 gdk_display_warp_device (GdkDisplay *display,
2117 g_return_if_fail (display == _gdk_display);
2118 g_return_if_fail (screen == _gdk_screen);
2119 g_return_if_fail (GDK_IS_DEVICE (device));
2120 g_return_if_fail (display == gdk_device_get_display (device));
2122 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
2126 _gdk_windowing_window_at_device_position (GdkDisplay *display,
2130 GdkModifierType *mask,
2131 gboolean get_toplevel)
2133 return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
2137 gdk_win32_window_get_events (GdkWindow *window)
2139 GdkWindowImplWin32 *impl;
2141 if (GDK_WINDOW_DESTROYED (window))
2144 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2146 return impl->native_event_mask;
2150 gdk_win32_window_set_events (GdkWindow *window,
2151 GdkEventMask event_mask)
2153 GdkWindowImplWin32 *impl;
2155 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2157 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2158 * set it here, too. Not that I know or remember why it is
2159 * necessary, will have to test some day.
2161 impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
2165 do_shape_combine_region (GdkWindow *window,
2171 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2172 _gdk_win32_adjust_client_rect (window, &rect);
2174 OffsetRgn (hrgn, -rect.left, -rect.top);
2175 OffsetRgn (hrgn, x, y);
2177 /* If this is a top-level window, add the title bar to the region */
2178 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2180 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2181 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2185 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2189 gdk_win32_window_set_override_redirect (GdkWindow *window,
2190 gboolean override_redirect)
2192 GdkWindowImplWin32 *window_impl;
2194 g_return_if_fail (GDK_IS_WINDOW (window));
2196 window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2198 window_impl->override_redirect = !!override_redirect;
2202 gdk_win32_window_set_accept_focus (GdkWindow *window,
2203 gboolean accept_focus)
2205 g_return_if_fail (GDK_IS_WINDOW (window));
2207 accept_focus = accept_focus != FALSE;
2209 if (window->accept_focus != accept_focus)
2210 window->accept_focus = accept_focus;
2214 gdk_win32_window_set_focus_on_map (GdkWindow *window,
2215 gboolean focus_on_map)
2217 g_return_if_fail (GDK_IS_WINDOW (window));
2219 focus_on_map = focus_on_map != FALSE;
2221 if (window->focus_on_map != focus_on_map)
2222 window->focus_on_map = focus_on_map;
2226 gdk_win32_window_set_icon_list (GdkWindow *window,
2229 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2230 gint big_diff, small_diff;
2231 gint big_w, big_h, small_w, small_h;
2234 HICON small_hicon, big_hicon;
2235 GdkWindowImplWin32 *impl;
2236 gint i, big_i, small_i;
2238 g_return_if_fail (GDK_IS_WINDOW (window));
2240 if (GDK_WINDOW_DESTROYED (window))
2243 impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2245 /* ideal sizes for small and large icons */
2246 big_w = GetSystemMetrics (SM_CXICON);
2247 big_h = GetSystemMetrics (SM_CYICON);
2248 small_w = GetSystemMetrics (SM_CXSMICON);
2249 small_h = GetSystemMetrics (SM_CYSMICON);
2251 /* find closest sized icons in the list */
2253 small_pixbuf = NULL;
2259 pixbuf = (GdkPixbuf*) pixbufs->data;
2260 w = gdk_pixbuf_get_width (pixbuf);
2261 h = gdk_pixbuf_get_height (pixbuf);
2263 dw = ABS (w - big_w);
2264 dh = ABS (h - big_h);
2265 diff = dw*dw + dh*dh;
2266 if (big_pixbuf == NULL || diff < big_diff)
2268 big_pixbuf = pixbuf;
2273 dw = ABS (w - small_w);
2274 dh = ABS (h - small_h);
2275 diff = dw*dw + dh*dh;
2276 if (small_pixbuf == NULL || diff < small_diff)
2278 small_pixbuf = pixbuf;
2283 pixbufs = g_list_next (pixbufs);
2287 /* Create the icons */
2288 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2289 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2292 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2294 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2295 (LPARAM)small_hicon);
2297 /* Store the icons, destroying any previous icons */
2298 if (impl->hicon_big)
2299 GDI_CALL (DestroyIcon, (impl->hicon_big));
2300 impl->hicon_big = big_hicon;
2301 if (impl->hicon_small)
2302 GDI_CALL (DestroyIcon, (impl->hicon_small));
2303 impl->hicon_small = small_hicon;
2307 gdk_win32_window_set_icon_name (GdkWindow *window,
2310 /* In case I manage to confuse this again (or somebody else does):
2311 * Please note that "icon name" here really *does* mean the name or
2312 * title of an window minimized as an icon on the desktop, or in the
2313 * taskbar. It has nothing to do with the freedesktop.org icon
2317 g_return_if_fail (GDK_IS_WINDOW (window));
2319 if (GDK_WINDOW_DESTROYED (window))
2323 /* This is not the correct thing to do. We should keep both the
2324 * "normal" window title, and the icon name. When the window is
2325 * minimized, call SetWindowText() with the icon name, and when the
2326 * window is restored, with the normal window title. Also, the name
2327 * is in UTF-8, so we should do the normal conversion to either wide
2328 * chars or system codepage, and use either the W or A version of
2329 * SetWindowText(), depending on Windows version.
2331 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2336 gdk_win32_window_get_group (GdkWindow *window)
2338 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2339 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2341 if (GDK_WINDOW_DESTROYED (window))
2344 g_warning ("gdk_window_get_group not yet implemented");
2350 gdk_win32_window_set_group (GdkWindow *window,
2353 g_return_if_fail (GDK_IS_WINDOW (window));
2354 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2355 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2357 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2360 g_warning ("gdk_window_set_group not implemented");
2364 update_single_bit (LONG *style,
2369 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2370 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2371 * bit indicate whether style_bit is on
2373 if ((!all && gdk_bit) || (all && !gdk_bit))
2374 *style |= style_bit;
2376 *style &= ~style_bit;
2380 update_style_bits (GdkWindow *window)
2382 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
2383 GdkWMDecoration decorations;
2384 LONG old_style, new_style, old_exstyle, new_exstyle;
2386 RECT rect, before, after;
2388 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
2391 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2392 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2394 GetClientRect (GDK_WINDOW_HWND (window), &before);
2396 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2398 new_style = old_style;
2399 new_exstyle = old_exstyle;
2401 if (window->window_type == GDK_WINDOW_TEMP ||
2402 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2403 new_exstyle |= WS_EX_TOOLWINDOW;
2405 new_exstyle &= ~WS_EX_TOOLWINDOW;
2407 if (get_effective_window_decorations (window, &decorations))
2409 all = (decorations & GDK_DECOR_ALL);
2410 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2411 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2412 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2413 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2414 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2415 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2418 if (old_style == new_style && old_exstyle == new_exstyle )
2420 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2421 GDK_WINDOW_HWND (window)));
2425 if (old_style != new_style)
2427 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2428 GDK_WINDOW_HWND (window),
2429 _gdk_win32_window_style_to_string (old_style),
2430 _gdk_win32_window_style_to_string (new_style)));
2432 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2435 if (old_exstyle != new_exstyle)
2437 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2438 GDK_WINDOW_HWND (window),
2439 _gdk_win32_window_exstyle_to_string (old_exstyle),
2440 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2442 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2445 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2447 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2448 rect.left += after.left - before.left;
2449 rect.top += after.top - before.top;
2450 rect.right += after.right - before.right;
2451 rect.bottom += after.bottom - before.bottom;
2453 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2454 rect.left, rect.top,
2455 rect.right - rect.left, rect.bottom - rect.top,
2456 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2457 SWP_NOREPOSITION | SWP_NOZORDER);
2462 update_single_system_menu_entry (HMENU hmenu,
2467 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2468 * gdk_bit indicates whether menu entry is disabled; if all is
2469 * FALSE, gdk bit indicate whether menu entry is enabled
2471 if ((!all && gdk_bit) || (all && !gdk_bit))
2472 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2474 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2478 update_system_menu (GdkWindow *window)
2480 GdkWMFunction functions;
2483 if (_gdk_window_get_functions (window, &functions))
2485 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2487 all = (functions & GDK_FUNC_ALL);
2488 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2489 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2490 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2491 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2492 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2497 get_decorations_quark ()
2499 static GQuark quark = 0;
2502 quark = g_quark_from_static_string ("gdk-window-decorations");
2508 gdk_win32_window_set_decorations (GdkWindow *window,
2509 GdkWMDecoration decorations)
2511 GdkWMDecoration* decorations_copy;
2513 g_return_if_fail (GDK_IS_WINDOW (window));
2515 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2516 GDK_WINDOW_HWND (window),
2517 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2518 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2519 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2520 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2521 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2522 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2523 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2525 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2526 *decorations_copy = decorations;
2527 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2529 update_style_bits (window);
2533 gdk_win32_window_get_decorations (GdkWindow *window,
2534 GdkWMDecoration *decorations)
2536 GdkWMDecoration* decorations_set;
2538 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2540 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2541 if (decorations_set)
2542 *decorations = *decorations_set;
2544 return (decorations_set != NULL);
2548 get_functions_quark ()
2550 static GQuark quark = 0;
2553 quark = g_quark_from_static_string ("gdk-window-functions");
2559 gdk_win32_window_set_functions (GdkWindow *window,
2560 GdkWMFunction functions)
2562 GdkWMFunction* functions_copy;
2564 g_return_if_fail (GDK_IS_WINDOW (window));
2566 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2567 GDK_WINDOW_HWND (window),
2568 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2569 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2570 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2571 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2572 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2573 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2575 functions_copy = g_malloc (sizeof (GdkWMFunction));
2576 *functions_copy = functions;
2577 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2579 update_system_menu (window);
2583 _gdk_window_get_functions (GdkWindow *window,
2584 GdkWMFunction *functions)
2586 GdkWMFunction* functions_set;
2588 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2590 *functions = *functions_set;
2592 return (functions_set != NULL);
2596 gdk_win32_window_set_static_gravities (GdkWindow *window,
2597 gboolean use_static)
2599 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2605 gdk_win32_window_begin_resize_drag (GdkWindow *window,
2615 g_return_if_fail (GDK_IS_WINDOW (window));
2617 if (GDK_WINDOW_DESTROYED (window))
2620 /* Tell Windows to start interactively resizing the window by pretending that
2621 * the left pointer button was clicked in the suitable edge or corner. This
2622 * will only work if the button is down when this function is called, and
2623 * will only work with button 1 (left), since Windows only allows window
2624 * dragging using the left mouse button.
2629 /* Must break the automatic grab that occured when the button was
2630 * pressed, otherwise it won't work.
2632 gdk_display_pointer_ungrab (_gdk_display, 0);
2636 case GDK_WINDOW_EDGE_NORTH_WEST:
2637 winedge = HTTOPLEFT;
2640 case GDK_WINDOW_EDGE_NORTH:
2644 case GDK_WINDOW_EDGE_NORTH_EAST:
2645 winedge = HTTOPRIGHT;
2648 case GDK_WINDOW_EDGE_WEST:
2652 case GDK_WINDOW_EDGE_EAST:
2656 case GDK_WINDOW_EDGE_SOUTH_WEST:
2657 winedge = HTBOTTOMLEFT;
2660 case GDK_WINDOW_EDGE_SOUTH:
2664 case GDK_WINDOW_EDGE_SOUTH_EAST:
2666 winedge = HTBOTTOMRIGHT;
2670 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2671 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2675 gdk_win32_window_begin_move_drag (GdkWindow *window,
2682 g_return_if_fail (GDK_IS_WINDOW (window));
2684 if (GDK_WINDOW_DESTROYED (window))
2687 /* Tell Windows to start interactively moving the window by pretending that
2688 * the left pointer button was clicked in the titlebar. This will only work
2689 * if the button is down when this function is called, and will only work
2690 * with button 1 (left), since Windows only allows window dragging using the
2691 * left mouse button.
2696 /* Must break the automatic grab that occured when the button was pressed,
2697 * otherwise it won't work.
2699 gdk_display_pointer_ungrab (_gdk_display, 0);
2701 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2702 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2707 * Setting window states
2710 gdk_win32_window_iconify (GdkWindow *window)
2712 HWND old_active_window;
2714 g_return_if_fail (GDK_IS_WINDOW (window));
2716 if (GDK_WINDOW_DESTROYED (window))
2719 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2720 GDK_WINDOW_HWND (window),
2721 _gdk_win32_window_state_to_string (window->state)));
2723 if (GDK_WINDOW_IS_MAPPED (window))
2725 old_active_window = GetActiveWindow ();
2726 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2727 if (old_active_window != GDK_WINDOW_HWND (window))
2728 SetActiveWindow (old_active_window);
2732 gdk_synthesize_window_state (window,
2734 GDK_WINDOW_STATE_ICONIFIED);
2739 gdk_win32_window_deiconify (GdkWindow *window)
2741 g_return_if_fail (GDK_IS_WINDOW (window));
2743 if (GDK_WINDOW_DESTROYED (window))
2746 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2747 GDK_WINDOW_HWND (window),
2748 _gdk_win32_window_state_to_string (window->state)));
2750 if (GDK_WINDOW_IS_MAPPED (window))
2752 show_window_internal (window, GDK_WINDOW_IS_MAPPED (window), TRUE);
2756 gdk_synthesize_window_state (window,
2757 GDK_WINDOW_STATE_ICONIFIED,
2763 gdk_win32_window_stick (GdkWindow *window)
2765 g_return_if_fail (GDK_IS_WINDOW (window));
2767 if (GDK_WINDOW_DESTROYED (window))
2770 /* FIXME: Do something? */
2774 gdk_win32_window_unstick (GdkWindow *window)
2776 g_return_if_fail (GDK_IS_WINDOW (window));
2778 if (GDK_WINDOW_DESTROYED (window))
2781 /* FIXME: Do something? */
2785 gdk_win32_window_maximize (GdkWindow *window)
2787 g_return_if_fail (GDK_IS_WINDOW (window));
2789 if (GDK_WINDOW_DESTROYED (window))
2792 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2793 GDK_WINDOW_HWND (window),
2794 _gdk_win32_window_state_to_string (window->state)));
2796 if (GDK_WINDOW_IS_MAPPED (window))
2797 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2799 gdk_synthesize_window_state (window,
2801 GDK_WINDOW_STATE_MAXIMIZED);
2805 gdk_win32_window_unmaximize (GdkWindow *window)
2807 g_return_if_fail (GDK_IS_WINDOW (window));
2809 if (GDK_WINDOW_DESTROYED (window))
2812 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2813 GDK_WINDOW_HWND (window),
2814 _gdk_win32_window_state_to_string (window->state)));
2816 if (GDK_WINDOW_IS_MAPPED (window))
2817 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2819 gdk_synthesize_window_state (window,
2820 GDK_WINDOW_STATE_MAXIMIZED,
2825 gdk_win32_window_fullscreen (GdkWindow *window)
2827 gint x, y, width, height;
2832 g_return_if_fail (GDK_IS_WINDOW (window));
2834 fi = g_new (FullscreenInfo, 1);
2836 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2840 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2842 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
2843 mi.cbSize = sizeof (mi);
2844 if (monitor && GetMonitorInfo (monitor, &mi))
2846 x = mi.rcMonitor.left;
2847 y = mi.rcMonitor.top;
2848 width = mi.rcMonitor.right - x;
2849 height = mi.rcMonitor.bottom - y;
2854 width = GetSystemMetrics (SM_CXSCREEN);
2855 height = GetSystemMetrics (SM_CYSCREEN);
2858 /* remember for restoring */
2859 fi->hint_flags = impl->hint_flags;
2860 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
2861 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
2862 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2864 /* Send state change before configure event */
2865 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2867 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2868 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
2870 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
2871 x, y, width, height,
2872 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2877 gdk_win32_window_unfullscreen (GdkWindow *window)
2881 g_return_if_fail (GDK_IS_WINDOW (window));
2883 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
2886 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
2888 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2890 impl->hint_flags = fi->hint_flags;
2891 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
2892 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
2893 fi->r.left, fi->r.top,
2894 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
2895 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2897 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
2899 update_style_bits (window);
2904 gdk_win32_window_set_keep_above (GdkWindow *window,
2907 g_return_if_fail (GDK_IS_WINDOW (window));
2909 if (GDK_WINDOW_DESTROYED (window))
2912 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
2913 GDK_WINDOW_HWND (window),
2914 setting ? "YES" : "NO"));
2916 if (GDK_WINDOW_IS_MAPPED (window))
2918 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2919 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
2921 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2924 gdk_synthesize_window_state (window,
2925 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
2926 setting ? GDK_WINDOW_STATE_ABOVE : 0);
2930 gdk_win32_window_set_keep_below (GdkWindow *window,
2933 g_return_if_fail (GDK_IS_WINDOW (window));
2935 if (GDK_WINDOW_DESTROYED (window))
2938 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
2939 GDK_WINDOW_HWND (window),
2940 setting ? "YES" : "NO"));
2942 if (GDK_WINDOW_IS_MAPPED (window))
2944 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2945 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
2947 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2950 gdk_synthesize_window_state (window,
2951 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
2952 setting ? GDK_WINDOW_STATE_BELOW : 0);
2956 gdk_win32_window_focus (GdkWindow *window,
2959 g_return_if_fail (GDK_IS_WINDOW (window));
2961 if (GDK_WINDOW_DESTROYED (window))
2964 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
2965 GDK_WINDOW_HWND (window),
2966 _gdk_win32_window_state_to_string (window->state)));
2968 if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
2969 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
2971 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2972 SetFocus (GDK_WINDOW_HWND (window));
2976 gdk_win32_window_set_modal_hint (GdkWindow *window,
2979 g_return_if_fail (GDK_IS_WINDOW (window));
2981 if (GDK_WINDOW_DESTROYED (window))
2984 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
2985 GDK_WINDOW_HWND (window),
2986 modal ? "YES" : "NO"));
2988 if (modal == window->modal_hint)
2991 window->modal_hint = modal;
2994 /* Not sure about this one.. -- Cody */
2995 if (GDK_WINDOW_IS_MAPPED (window))
2996 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2997 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
2999 SWP_NOMOVE | SWP_NOSIZE));
3004 _gdk_push_modal_window (window);
3005 gdk_window_raise (window);
3009 _gdk_remove_modal_window (window);
3016 gdk_win32_window_set_skip_taskbar_hint (GdkWindow *window,
3017 gboolean skips_taskbar)
3019 static GdkWindow *owner = NULL;
3022 g_return_if_fail (GDK_IS_WINDOW (window));
3024 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3025 GDK_WINDOW_HWND (window),
3026 skips_taskbar ? "YES" : "NO"));
3028 // ### TODO: Need to figure out what to do here.
3036 wa.window_type = GDK_WINDOW_TEMP;
3037 wa.wclass = GDK_INPUT_OUTPUT;
3038 wa.width = wa.height = 1;
3040 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3044 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3046 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3047 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3048 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3050 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3052 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3053 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3058 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3063 gdk_win32_window_set_skip_pager_hint (GdkWindow *window,
3064 gboolean skips_pager)
3066 g_return_if_fail (GDK_IS_WINDOW (window));
3068 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3069 GDK_WINDOW_HWND (window),
3070 skips_pager ? "YES" : "NO"));
3074 gdk_win32_window_set_type_hint (GdkWindow *window,
3075 GdkWindowTypeHint hint)
3077 g_return_if_fail (GDK_IS_WINDOW (window));
3079 if (GDK_WINDOW_DESTROYED (window))
3084 static GEnumClass *class = NULL;
3086 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3087 g_print ("gdk_window_set_type_hint: %p: %s\n",
3088 GDK_WINDOW_HWND (window),
3089 g_enum_get_value (class, hint)->value_name);
3092 ((GdkWindowImplWin32 *)window->impl)->type_hint = hint;
3094 update_style_bits (window);
3097 static GdkWindowTypeHint
3098 gdk_win32_window_get_type_hint (GdkWindow *window)
3100 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3102 if (GDK_WINDOW_DESTROYED (window))
3103 return GDK_WINDOW_TYPE_HINT_NORMAL;
3105 return GDK_WINDOW_IMPL_WIN32 (window->impl)->type_hint;
3109 cairo_region_to_hrgn (const cairo_region_t *region,
3116 cairo_rectangle_int_t r;
3117 const int nrects = cairo_region_num_rectangles (region);
3119 sizeof (RGNDATAHEADER) + (sizeof (RECT) * nrects);
3122 rgndata = g_malloc (nbytes);
3123 rgndata->rdh.dwSize = sizeof (RGNDATAHEADER);
3124 rgndata->rdh.iType = RDH_RECTANGLES;
3125 rgndata->rdh.nCount = rgndata->rdh.nRgnSize = 0;
3126 SetRect (&rgndata->rdh.rcBound,
3127 G_MAXLONG, G_MAXLONG, G_MINLONG, G_MINLONG);
3129 for (i = 0; i < nrects; i++)
3131 rect = ((RECT *) rgndata->Buffer) + rgndata->rdh.nCount++;
3133 cairo_region_get_rectangle (region, i, &r);
3134 rect->left = r.x + x_origin;
3135 rect->right = rect->left + r.width;
3136 rect->top = r.y + y_origin;
3137 rect->bottom = rect->top + r.height;
3139 if (rect->left < rgndata->rdh.rcBound.left)
3140 rgndata->rdh.rcBound.left = rect->left;
3141 if (rect->right > rgndata->rdh.rcBound.right)
3142 rgndata->rdh.rcBound.right = rect->right;
3143 if (rect->top < rgndata->rdh.rcBound.top)
3144 rgndata->rdh.rcBound.top = rect->top;
3145 if (rect->bottom > rgndata->rdh.rcBound.bottom)
3146 rgndata->rdh.rcBound.bottom = rect->bottom;
3148 if ((hrgn = ExtCreateRegion (NULL, nbytes, rgndata)) == NULL)
3149 WIN32_API_FAILED ("ExtCreateRegion");
3157 gdk_win32_window_shape_combine_region (GdkWindow *window,
3158 const cairo_region_t *shape_region,
3162 if (GDK_WINDOW_DESTROYED (window))
3167 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3168 GDK_WINDOW_HWND (window)));
3169 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3175 hrgn = cairo_region_to_hrgn (shape_region, 0, 0);
3177 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3178 GDK_WINDOW_HWND (window),
3181 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3186 gdk_win32_window_lookup_for_display (GdkDisplay *display,
3189 g_return_val_if_fail (display == _gdk_display, NULL);
3191 return (GdkWindow*) gdk_win32_handle_table_lookup (anid);
3195 gdk_win32_window_enable_synchronized_configure (GdkWindow *window)
3197 /* nothing - no window manager to cooperate with */
3201 gdk_win32_window_configure_finished (GdkWindow *window)
3203 /* nothing - no window manager to cooperate with */
3207 gdk_win32_window_set_opacity (GdkWindow *window,
3211 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3212 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3214 g_return_if_fail (GDK_IS_WINDOW (window));
3215 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3217 if (GDK_WINDOW_DESTROYED (window))
3222 else if (opacity > 1)
3225 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3227 if (!(exstyle & WS_EX_LAYERED))
3228 SetWindowLong (GDK_WINDOW_HWND (window),
3230 exstyle | WS_EX_LAYERED);
3232 setLayeredWindowAttributes =
3233 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3235 if (setLayeredWindowAttributes)
3237 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3244 static cairo_region_t *
3245 gdk_win32_window_get_shape (GdkWindow *window)
3247 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3248 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3250 if (type == SIMPLEREGION || type == COMPLEXREGION)
3252 cairo_region_t *region = _gdk_win32_hrgn_to_region (hrgn);
3254 DeleteObject (hrgn);
3262 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3263 cairo_region_t *area)
3265 HRGN hrgn = cairo_region_to_hrgn (area, 0, 0);
3267 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3268 GDK_WINDOW_HWND (window),
3269 _gdk_win32_cairo_region_to_string (area)));
3271 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3273 DeleteObject (hrgn);
3278 /* Gets called from gdwindow.c(do_move_region_bits_on_impl)
3279 * and got tested with testgtk::big_window. Given the previous,
3280 * untested implementation this one looks much too simple ;)
3283 _gdk_win32_window_translate (GdkWindow *window,
3284 cairo_region_t *area, /* In impl window coords */
3288 GdkRectangle extents;
3291 cairo_region_get_extents (area, &extents);
3292 rect.left = extents.x - dx;
3293 rect.top = extents.y - dy;
3294 rect.right = rect.left + extents.width;
3295 rect.bottom = rect.top + extents.height;
3297 API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window),
3305 gdk_win32_input_shape_combine_region (GdkWindow *window,
3306 const cairo_region_t *shape_region,
3310 if (GDK_WINDOW_DESTROYED (window))
3312 /* CHECK: are these really supposed to be the same? */
3313 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3317 gdk_win32_window_process_updates_recurse (GdkWindow *window,
3318 cairo_region_t *region)
3320 _gdk_window_process_updates_recurse (window, region);
3324 gdk_win32_window_is_win32 (GdkWindow *window)
3326 return GDK_WINDOW_IS_WIN32 (window);
3330 * _gdk_win32_acquire_dc
3331 * @impl: a Win32 #GdkWindowImplWin32 implementation
3333 * Gets a DC with the given drawable selected into it.
3335 * Return value: The DC, on success. Otherwise
3336 * %NULL. If this function succeeded
3337 * _gdk_win32_impl_release_dc() must be called
3338 * release the DC when you are done using it.
3341 _gdk_win32_impl_acquire_dc (GdkWindowImplWin32 *impl)
3343 if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
3344 GDK_WINDOW_DESTROYED (impl->wrapper))
3349 impl->hdc = GetDC (impl->handle);
3351 WIN32_GDI_FAILED ("GetDC");
3366 * _gdk_win32_impl_release_dc
3367 * @impl: a Win32 #GdkWindowImplWin32 implementation
3369 * Releases the reference count for the DC
3370 * from _gdk_win32_impl_acquire_dc()
3373 _gdk_win32_impl_release_dc (GdkWindowImplWin32 *impl)
3375 g_return_if_fail (impl->hdc_count > 0);
3378 if (impl->hdc_count == 0)
3380 if (impl->saved_dc_bitmap)
3382 GDI_CALL (SelectObject, (impl->hdc, impl->saved_dc_bitmap));
3383 impl->saved_dc_bitmap = NULL;
3388 GDI_CALL (ReleaseDC, (impl->handle, impl->hdc));
3395 gdk_win32_window_get_impl_hwnd (GdkWindow *window)
3397 if (GDK_WINDOW_IS_WIN32 (window))
3398 return GDK_WINDOW_HWND (window);
3403 gdk_win32_cairo_surface_destroy (void *data)
3405 GdkWindowImplWin32 *impl = data;
3407 _gdk_win32_impl_release_dc (impl);
3408 impl->cairo_surface = NULL;
3411 static cairo_surface_t *
3412 gdk_win32_ref_cairo_surface (GdkWindow *window)
3414 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
3416 if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
3417 GDK_WINDOW_DESTROYED (impl->wrapper))
3420 if (!impl->cairo_surface)
3422 HDC hdc = _gdk_win32_impl_acquire_dc (impl);
3426 impl->cairo_surface = cairo_win32_surface_create (hdc);
3428 cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
3429 impl, gdk_win32_cairo_surface_destroy);
3432 cairo_surface_reference (impl->cairo_surface);
3434 return impl->cairo_surface;
3438 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
3440 GObjectClass *object_class = G_OBJECT_CLASS (klass);
3441 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
3443 parent_class = g_type_class_peek_parent (klass);
3445 object_class->finalize = gdk_window_impl_win32_finalize;
3447 impl_class->ref_cairo_surface = gdk_win32_ref_cairo_surface;
3449 impl_class->show = gdk_win32_window_show;
3450 impl_class->hide = gdk_win32_window_hide;
3451 impl_class->withdraw = gdk_win32_window_withdraw;
3452 impl_class->set_events = gdk_win32_window_set_events;
3453 impl_class->get_events = gdk_win32_window_get_events;
3454 impl_class->raise = gdk_win32_window_raise;
3455 impl_class->lower = gdk_win32_window_lower;
3456 impl_class->restack_under = gdk_win32_window_restack_under;
3457 impl_class->restack_toplevel = gdk_win32_window_restack_toplevel;
3458 impl_class->move_resize = gdk_win32_window_move_resize;
3459 impl_class->set_background = gdk_win32_window_set_background;
3460 impl_class->reparent = gdk_win32_window_reparent;
3461 impl_class->set_device_cursor = gdk_win32_window_set_device_cursor;
3462 impl_class->get_geometry = gdk_win32_window_get_geometry;
3463 impl_class->get_device_state = gdk_window_win32_get_device_state;
3464 impl_class->get_root_coords = gdk_win32_window_get_root_coords;
3466 impl_class->shape_combine_region = gdk_win32_window_shape_combine_region;
3467 impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3468 impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
3469 impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3470 impl_class->translate = _gdk_win32_window_translate;
3471 impl_class->destroy = gdk_win32_window_destroy;
3472 impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
3473 impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
3474 impl_class->get_shape = gdk_win32_window_get_shape;
3475 //FIXME?: impl_class->get_input_shape = gdk_win32_window_get_input_shape;
3477 //impl_class->beep = gdk_x11_window_beep;
3479 impl_class->focus = gdk_win32_window_focus;
3480 impl_class->set_type_hint = gdk_win32_window_set_type_hint;
3481 impl_class->get_type_hint = gdk_win32_window_get_type_hint;
3482 impl_class->set_modal_hint = gdk_win32_window_set_modal_hint;
3483 impl_class->set_skip_taskbar_hint = gdk_win32_window_set_skip_taskbar_hint;
3484 impl_class->set_skip_pager_hint = gdk_win32_window_set_skip_pager_hint;
3485 impl_class->set_urgency_hint = gdk_win32_window_set_urgency_hint;
3486 impl_class->set_geometry_hints = gdk_win32_window_set_geometry_hints;
3487 impl_class->set_title = gdk_win32_window_set_title;
3488 impl_class->set_role = gdk_win32_window_set_role;
3489 //impl_class->set_startup_id = gdk_x11_window_set_startup_id;
3490 impl_class->set_transient_for = gdk_win32_window_set_transient_for;
3491 impl_class->get_root_origin = gdk_win32_window_get_root_origin;
3492 impl_class->get_frame_extents = gdk_win32_window_get_frame_extents;
3493 impl_class->set_override_redirect = gdk_win32_window_set_override_redirect;
3494 impl_class->set_accept_focus = gdk_win32_window_set_accept_focus;
3495 impl_class->set_focus_on_map = gdk_win32_window_set_focus_on_map;
3496 impl_class->set_icon_list = gdk_win32_window_set_icon_list;
3497 impl_class->set_icon_name = gdk_win32_window_set_icon_name;
3498 impl_class->iconify = gdk_win32_window_iconify;
3499 impl_class->deiconify = gdk_win32_window_deiconify;
3500 impl_class->stick = gdk_win32_window_stick;
3501 impl_class->unstick = gdk_win32_window_unstick;
3502 impl_class->maximize = gdk_win32_window_maximize;
3503 impl_class->unmaximize = gdk_win32_window_unmaximize;
3504 impl_class->fullscreen = gdk_win32_window_fullscreen;
3505 impl_class->unfullscreen = gdk_win32_window_unfullscreen;
3506 impl_class->set_keep_above = gdk_win32_window_set_keep_above;
3507 impl_class->set_keep_below = gdk_win32_window_set_keep_below;
3508 impl_class->get_group = gdk_win32_window_get_group;
3509 impl_class->set_group = gdk_win32_window_set_group;
3510 impl_class->set_decorations = gdk_win32_window_set_decorations;
3511 impl_class->get_decorations = gdk_win32_window_get_decorations;
3512 impl_class->set_functions = gdk_win32_window_set_functions;
3514 impl_class->begin_resize_drag = gdk_win32_window_begin_resize_drag;
3515 impl_class->begin_move_drag = gdk_win32_window_begin_move_drag;
3516 impl_class->enable_synchronized_configure = gdk_win32_window_enable_synchronized_configure;
3517 impl_class->configure_finished = gdk_win32_window_configure_finished;
3518 impl_class->set_opacity = gdk_win32_window_set_opacity;
3519 //impl_class->set_composited = gdk_win32_window_set_composited;
3520 impl_class->destroy_notify = gdk_win32_window_destroy_notify;
3521 impl_class->get_drag_protocol = _gdk_win32_window_get_drag_protocol;
3522 impl_class->register_dnd = _gdk_win32_window_register_dnd;
3523 impl_class->drag_begin = _gdk_win32_window_drag_begin;
3524 impl_class->process_updates_recurse = gdk_win32_window_process_updates_recurse;
3525 //? impl_class->sync_rendering = _gdk_win32_window_sync_rendering;
3526 impl_class->simulate_key = _gdk_win32_window_simulate_key;
3527 impl_class->simulate_button = _gdk_win32_window_simulate_button;
3528 impl_class->get_property = _gdk_win32_window_get_property;
3529 impl_class->change_property = _gdk_win32_window_change_property;
3530 impl_class->delete_property = _gdk_win32_window_delete_property;
3534 gdk_win32_window_get_handle (GdkWindow *window)
3536 /* Try to ensure the window has a native window */
3537 if (!_gdk_window_has_impl (window))
3538 gdk_window_ensure_native (window);
3540 if (!GDK_WINDOW_IS_WIN32 (window))
3542 g_warning (G_STRLOC " window is not a native Win32 window");
3546 return GDK_WINDOW_HWND (window);