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-2009 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 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
41 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
42 static void gdk_window_impl_win32_finalize (GObject *object);
44 static gpointer parent_class = NULL;
45 static GSList *modal_window_stack = NULL;
47 static void update_style_bits (GdkWindow *window);
48 static gboolean _gdk_window_get_functions (GdkWindow *window,
49 GdkWMFunction *functions);
51 #define WINDOW_IS_TOPLEVEL(window) \
52 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
53 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
54 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
56 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
59 GDK_WINDOW_SCREEN (GObject *win)
65 _gdk_window_impl_win32_get_type (void)
67 static GType object_type = 0;
71 const GTypeInfo object_info =
73 sizeof (GdkWindowImplWin32Class),
75 (GBaseFinalizeFunc) NULL,
76 (GClassInitFunc) gdk_window_impl_win32_class_init,
77 NULL, /* class_finalize */
78 NULL, /* class_data */
79 sizeof (GdkWindowImplWin32),
81 (GInstanceInitFunc) gdk_window_impl_win32_init,
84 const GInterfaceInfo window_impl_info =
86 (GInterfaceInitFunc) gdk_window_impl_iface_init,
91 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
94 g_type_add_interface_static (object_type,
103 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
105 impl->toplevel_window_type = -1;
106 impl->hcursor = NULL;
107 impl->hicon_big = NULL;
108 impl->hicon_small = NULL;
109 impl->hint_flags = 0;
110 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
111 impl->extension_events_selected = FALSE;
112 impl->transient_owner = NULL;
113 impl->transient_children = NULL;
114 impl->num_transients = 0;
115 impl->changing_state = FALSE;
119 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
121 GObjectClass *object_class = G_OBJECT_CLASS (klass);
123 parent_class = g_type_class_peek_parent (klass);
125 object_class->finalize = gdk_window_impl_win32_finalize;
129 gdk_window_impl_win32_finalize (GObject *object)
131 GdkWindowObject *wrapper;
132 GdkDrawableImplWin32 *draw_impl;
133 GdkWindowImplWin32 *window_impl;
135 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
137 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
138 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
140 wrapper = (GdkWindowObject*) draw_impl->wrapper;
142 if (!GDK_WINDOW_DESTROYED (wrapper))
144 gdk_win32_handle_table_remove (draw_impl->handle);
147 if (window_impl->hcursor != NULL)
149 if (GetCursor () == window_impl->hcursor)
152 GDI_CALL (DestroyCursor, (window_impl->hcursor));
153 window_impl->hcursor = NULL;
156 if (window_impl->hicon_big != NULL)
158 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
159 window_impl->hicon_big = NULL;
162 if (window_impl->hicon_small != NULL)
164 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
165 window_impl->hicon_small = NULL;
168 G_OBJECT_CLASS (parent_class)->finalize (object);
172 _gdk_win32_adjust_client_rect (GdkWindow *window,
177 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
178 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
179 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
183 _gdk_root_window_size_init (void)
185 GdkWindowObject *window_object;
189 window_object = GDK_WINDOW_OBJECT (_gdk_root);
190 rect = _gdk_monitors[0].rect;
191 for (i = 1; i < _gdk_num_monitors; i++)
192 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
194 window_object->width = rect.width;
195 window_object->height = rect.height;
199 _gdk_windowing_window_init (GdkScreen *screen)
201 GdkWindowObject *private;
202 GdkDrawableImplWin32 *draw_impl;
204 g_assert (_gdk_root == NULL);
206 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
207 private = (GdkWindowObject *)_gdk_root;
208 private->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
209 private->impl_window = private;
210 private->visual = gdk_screen_get_system_visual (screen);
212 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
214 draw_impl->handle = GetDesktopWindow ();
215 draw_impl->wrapper = GDK_DRAWABLE (private);
217 private->window_type = GDK_WINDOW_ROOT;
218 private->depth = gdk_visual_get_system ()->depth;
220 _gdk_root_window_size_init ();
226 /* width and height already initialised in _gdk_root_window_size_init() */
227 private->viewable = TRUE;
229 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
231 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
235 get_default_title (void)
238 title = g_get_application_name ();
240 title = g_get_prgname ();
246 * is a wrapper function for RegisterWindowClassEx.
247 * It creates at least one unique class for every
248 * GdkWindowType. If support for single window-specific icons
249 * is ever needed (e.g Dialog specific), every such window should
253 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
255 static ATOM klassTOPLEVEL = 0;
256 static ATOM klassCHILD = 0;
257 static ATOM klassTEMP = 0;
258 static ATOM klassTEMPSHADOW = 0;
259 static HICON hAppIcon = NULL;
260 static HICON hAppIconSm = NULL;
261 static WNDCLASSEXW wcl;
264 wcl.cbSize = sizeof (WNDCLASSEX);
265 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
266 * on WM_SIZE and WM_MOVE. Flicker, Performance!
268 wcl.lpfnWndProc = _gdk_win32_window_procedure;
271 wcl.hInstance = _gdk_app_hmodule;
275 /* initialize once! */
276 if (0 == hAppIcon && 0 == hAppIconSm)
278 gchar sLoc [MAX_PATH+1];
280 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
282 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
284 if (0 == hAppIcon && 0 == hAppIconSm)
286 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
288 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
293 if (0 == hAppIcon && 0 == hAppIconSm)
295 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
296 GetSystemMetrics (SM_CXICON),
297 GetSystemMetrics (SM_CYICON), 0);
298 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
299 GetSystemMetrics (SM_CXSMICON),
300 GetSystemMetrics (SM_CYSMICON), 0);
305 hAppIcon = hAppIconSm;
306 else if (0 == hAppIconSm)
307 hAppIconSm = hAppIcon;
309 wcl.lpszMenuName = NULL;
311 /* initialize once per class */
313 * HB: Setting the background brush leads to flicker, because we
314 * don't get asked how to clear the background. This is not what
315 * we want, at least not for input_only windows ...
317 #define ONCE_PER_CLASS() \
318 wcl.hIcon = CopyIcon (hAppIcon); \
319 wcl.hIconSm = CopyIcon (hAppIconSm); \
320 wcl.hbrBackground = NULL; \
321 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
325 case GDK_WINDOW_TOPLEVEL:
326 if (0 == klassTOPLEVEL)
328 wcl.lpszClassName = L"gdkWindowToplevel";
331 klassTOPLEVEL = RegisterClassExW (&wcl);
333 klass = klassTOPLEVEL;
336 case GDK_WINDOW_CHILD:
339 wcl.lpszClassName = L"gdkWindowChild";
341 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
343 klassCHILD = RegisterClassExW (&wcl);
348 case GDK_WINDOW_TEMP:
349 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
350 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
351 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
352 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
354 if (klassTEMPSHADOW == 0)
356 wcl.lpszClassName = L"gdkWindowTempShadow";
357 wcl.style |= CS_SAVEBITS;
358 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
359 LOWORD (g_win32_get_windows_version()) == 0x0105)
361 /* Windows XP (5.1) or above */
362 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
365 klassTEMPSHADOW = RegisterClassExW (&wcl);
368 klass = klassTEMPSHADOW;
374 wcl.lpszClassName = L"gdkWindowTemp";
375 wcl.style |= CS_SAVEBITS;
377 klassTEMP = RegisterClassExW (&wcl);
385 g_assert_not_reached ();
391 WIN32_API_FAILED ("RegisterClassExW");
392 g_error ("That is a fatal error");
398 _gdk_window_impl_new (GdkWindow *window,
399 GdkWindow *real_parent,
401 GdkEventMask event_mask,
402 GdkWindowAttr *attributes,
403 gint attributes_mask)
408 DWORD dwStyle = 0, dwExStyle;
410 GdkWindow *orig_parent;
411 GdkWindowObject *private;
412 GdkWindowImplWin32 *impl;
413 GdkDrawableImplWin32 *draw_impl;
416 gint window_width, window_height;
417 gint offset_x = 0, offset_y = 0;
419 private = (GdkWindowObject *)window;
421 orig_parent = real_parent;
424 g_print ("_gdk_window_impl_new: %s\n",
425 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
426 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
427 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
430 hparent = GDK_WINDOW_HWND (real_parent);
432 impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
433 private->impl = (GdkDrawable *)impl;
434 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
435 draw_impl->wrapper = GDK_DRAWABLE (window);
437 // XXX: xattributes_mask = 0
440 if (attributes_mask & GDK_WA_VISUAL)
441 visual = attributes->visual;
443 visual = gdk_visual_get_system ();
447 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
448 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
450 impl->extension_events_selected = FALSE;
453 if (attributes->wclass == GDK_INPUT_OUTPUT)
457 private->input_only = FALSE;
461 /* I very much doubt using WS_EX_TRANSPARENT actually
462 * corresponds to how X11 InputOnly windows work, but it appears
463 * to work well enough for the actual use cases in gtk.
465 dwExStyle = WS_EX_TRANSPARENT;
467 private->input_only = TRUE;
468 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY\n"));
471 switch (private->window_type)
473 case GDK_WINDOW_TOPLEVEL:
474 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
476 /* The common code warns for this case. */
477 hparent = GetDesktopWindow ();
479 /* Children of foreign windows aren't toplevel windows */
480 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
482 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
486 if (private->window_type == GDK_WINDOW_TOPLEVEL)
487 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
489 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
491 offset_x = _gdk_offset_x;
492 offset_y = _gdk_offset_y;
496 case GDK_WINDOW_CHILD:
497 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
500 case GDK_WINDOW_TEMP:
501 /* A temp window is not necessarily a top level window */
502 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
503 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
504 dwExStyle |= WS_EX_TOOLWINDOW;
505 offset_x = _gdk_offset_x;
506 offset_y = _gdk_offset_y;
510 g_assert_not_reached ();
513 if (private->window_type != GDK_WINDOW_CHILD)
515 rect.left = rect.top = 0;
516 rect.right = private->width;
517 rect.bottom = private->height;
519 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
521 window_width = rect.right - rect.left;
522 window_height = rect.bottom - rect.top;
526 window_width = private->width;
527 window_height = private->height;
530 if (attributes_mask & GDK_WA_TITLE)
531 title = attributes->title;
533 title = get_default_title ();
534 if (!title || !*title)
537 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
539 if (attributes_mask & GDK_WA_TYPE_HINT)
540 impl->type_hint = attributes->type_hint;
542 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
544 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
545 dwExStyle |= WS_EX_TOOLWINDOW;
548 private->parent->children = g_list_prepend (private->parent->children, window);
550 klass = RegisterGdkClass (private->window_type, impl->type_hint);
552 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
554 hwndNew = CreateWindowExW (dwExStyle,
555 MAKEINTRESOURCEW (klass),
558 ((attributes_mask & GDK_WA_X) ?
559 private->x - offset_x : CW_USEDEFAULT),
560 private->y - offset_y,
561 window_width, window_height,
566 if (GDK_WINDOW_HWND (window) != hwndNew)
568 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
569 GDK_WINDOW_HWND (window),
572 /* HB: IHMO due to a race condition the handle was increased by
573 * one, which causes much trouble. Because I can't find the
574 * real bug, try to workaround it ...
575 * To reproduce: compile with MSVC 5, DEBUG=1
578 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
579 GDK_WINDOW_HWND (window) = hwndNew;
580 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
582 /* the old behaviour, but with warning */
583 draw_impl->handle = hwndNew;
588 g_object_ref (window);
589 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
591 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
593 window_width, window_height,
594 ((attributes_mask & GDK_WA_X) ?
595 private->x - offset_x: CW_USEDEFAULT),
596 private->y - offset_y,
598 GDK_WINDOW_HWND (window)));
600 /* Add window handle to title */
601 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
605 if (draw_impl->handle == NULL)
607 WIN32_API_FAILED ("CreateWindowExW");
608 g_object_unref (window);
612 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
613 // gdk_window_set_skip_taskbar_hint (window, TRUE);
615 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
616 (attributes->cursor) :
621 gdk_window_foreign_new_for_display (GdkDisplay *display,
622 GdkNativeWindow anid)
625 GdkWindowObject *private;
626 GdkWindowImplWin32 *impl;
627 GdkDrawableImplWin32 *draw_impl;
633 g_return_val_if_fail (display == _gdk_display, NULL);
635 window = g_object_new (GDK_TYPE_WINDOW, NULL);
636 private = (GdkWindowObject *)window;
637 private->visual = gdk_screen_get_system_visual (_gdk_screen);
638 private->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
639 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
640 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
641 draw_impl->wrapper = GDK_DRAWABLE (window);
642 parent = GetParent ((HWND)anid);
644 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
645 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
646 private->parent = (GdkWindowObject *)_gdk_root;
648 private->parent->children = g_list_prepend (private->parent->children, window);
650 draw_impl->handle = (HWND) anid;
651 GetClientRect ((HWND) anid, &rect);
653 point.y = rect.right;
654 ClientToScreen ((HWND) anid, &point);
655 if (parent != GetDesktopWindow ())
656 ScreenToClient (parent, &point);
657 private->x = point.x;
658 private->y = point.y;
659 private->width = rect.right - rect.left;
660 private->height = rect.bottom - rect.top;
661 private->window_type = GDK_WINDOW_FOREIGN;
662 private->destroyed = FALSE;
663 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
664 if (IsWindowVisible ((HWND) anid))
665 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
667 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
668 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
669 private->state |= GDK_WINDOW_STATE_ABOVE;
671 private->state &= (~GDK_WINDOW_STATE_ABOVE);
672 private->state &= (~GDK_WINDOW_STATE_BELOW);
673 private->viewable = TRUE;
675 private->depth = gdk_visual_get_system ()->depth;
677 g_object_ref (window);
678 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
680 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
682 _gdk_win32_drawable_description (window),
683 private->x, private->y));
689 gdk_win32_window_destroy (GdkWindow *window,
691 gboolean foreign_destroy)
693 GdkWindowObject *private = (GdkWindowObject *)window;
694 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
697 g_return_if_fail (GDK_IS_WINDOW (window));
699 GDK_NOTE (MISC, g_print ("gdk_win32_window_destroy: %p\n",
700 GDK_WINDOW_HWND (window)));
702 /* Remove ourself from the modal stack */
703 _gdk_remove_modal_window (window);
705 /* Remove all our transient children */
706 tmp = window_impl->transient_children;
709 GdkWindow *child = tmp->data;
710 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
712 child_impl->transient_owner = NULL;
713 tmp = g_slist_next (tmp);
715 g_slist_free (window_impl->transient_children);
716 window_impl->transient_children = NULL;
718 /* Remove ourself from our transient owner */
719 if (window_impl->transient_owner != NULL)
721 gdk_window_set_transient_for (window, NULL);
724 if (!recursing && !foreign_destroy)
726 _gdk_win32_drawable_finish (private->impl);
728 private->destroyed = TRUE;
729 DestroyWindow (GDK_WINDOW_HWND (window));
732 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
735 static cairo_surface_t *
736 gdk_win32_window_resize_cairo_surface (GdkWindow *window,
737 cairo_surface_t *surface,
741 /* XXX: Make Cairo surface use DC clip */
742 cairo_surface_destroy (surface);
748 gdk_win32_window_destroy_foreign (GdkWindow *window)
750 /* It's somebody else's window, but in our hierarchy, so reparent it
751 * to the desktop, and then try to destroy it.
753 gdk_window_hide (window);
754 gdk_window_reparent (window, NULL, 0, 0);
756 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
759 /* This function is called when the window really gone.
762 gdk_window_destroy_notify (GdkWindow *window)
764 g_return_if_fail (GDK_IS_WINDOW (window));
767 g_print ("gdk_window_destroy_notify: %p%s\n",
768 GDK_WINDOW_HWND (window),
769 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
771 if (!GDK_WINDOW_DESTROYED (window))
773 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
774 g_warning ("window %p unexpectedly destroyed",
775 GDK_WINDOW_HWND (window));
777 _gdk_window_destroy (window, TRUE);
780 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
781 g_object_unref (window);
785 get_outer_rect (GdkWindow *window,
790 rect->left = rect->top = 0;
792 rect->bottom = height;
794 _gdk_win32_adjust_client_rect (window, rect);
798 adjust_for_gravity_hints (GdkWindow *window,
803 GdkWindowObject *obj;
804 GdkWindowImplWin32 *impl;
806 obj = GDK_WINDOW_OBJECT (window);
807 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
809 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
811 gint orig_x = *x, orig_y = *y;
813 switch (impl->hints.win_gravity)
815 case GDK_GRAVITY_NORTH:
816 case GDK_GRAVITY_CENTER:
817 case GDK_GRAVITY_SOUTH:
818 *x -= (outer_rect->right - outer_rect->left) / 2;
819 *x += obj->width / 2;
822 case GDK_GRAVITY_SOUTH_EAST:
823 case GDK_GRAVITY_EAST:
824 case GDK_GRAVITY_NORTH_EAST:
825 *x -= outer_rect->right - outer_rect->left;
829 case GDK_GRAVITY_STATIC:
830 *x += outer_rect->left;
837 switch (impl->hints.win_gravity)
839 case GDK_GRAVITY_WEST:
840 case GDK_GRAVITY_CENTER:
841 case GDK_GRAVITY_EAST:
842 *y -= (outer_rect->bottom - outer_rect->top) / 2;
843 *y += obj->height / 2;
846 case GDK_GRAVITY_SOUTH_WEST:
847 case GDK_GRAVITY_SOUTH:
848 case GDK_GRAVITY_SOUTH_EAST:
849 *y -= outer_rect->bottom - outer_rect->top;
853 case GDK_GRAVITY_STATIC:
854 *y += outer_rect->top;
861 (orig_x != *x || orig_y != *y) ?
862 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
863 orig_x, *x, orig_y, *y)
869 show_window_internal (GdkWindow *window,
873 GdkWindowObject *private;
874 HWND old_active_window;
875 gboolean focus_on_map = TRUE;
879 private = (GdkWindowObject *) window;
881 if (private->destroyed)
884 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
885 GDK_WINDOW_HWND (window),
886 _gdk_win32_window_state_to_string (private->state),
887 (raise ? " raise" : ""),
888 (deiconify ? " deiconify" : "")));
890 /* If asked to show (not deiconify) an withdrawn and iconified
894 !GDK_WINDOW_IS_MAPPED (window) &&
895 (private->state & GDK_WINDOW_STATE_ICONIFIED))
897 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
901 /* If asked to just show an iconified window, do nothing. */
902 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
905 /* If asked to deiconify an already noniconified window, do
906 * nothing. (Especially, don't cause the window to rise and
907 * activate. There are different calls for that.)
909 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
912 /* If asked to show (but not raise) a window that is already
913 * visible, do nothing.
915 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
920 if (!GDK_WINDOW_IS_MAPPED (window))
922 gdk_synthesize_window_state (window,
923 GDK_WINDOW_STATE_WITHDRAWN,
925 focus_on_map = private->focus_on_map;
928 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
930 if (private->state & GDK_WINDOW_STATE_BELOW)
931 exstyle &= (~WS_EX_TOPMOST);
933 if (private->state & GDK_WINDOW_STATE_ABOVE)
934 exstyle |= WS_EX_TOPMOST;
936 if (exstyle & WS_EX_TOPMOST)
941 /* Use SetWindowPos to show transparent windows so automatic redraws
942 * in other windows can be suppressed.
944 if (exstyle & WS_EX_TRANSPARENT)
946 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
949 flags |= SWP_NOZORDER;
950 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
951 flags |= SWP_NOACTIVATE;
953 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
958 old_active_window = GetActiveWindow ();
960 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
962 gdk_window_fullscreen (window);
964 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
966 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
968 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
970 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
972 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
974 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
978 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
983 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
984 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
986 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
987 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
989 if (focus_on_map && private->accept_focus)
991 SetForegroundWindow (GDK_WINDOW_HWND (window));
992 if (top == HWND_TOPMOST)
993 SetWindowPos (GDK_WINDOW_HWND (window), top,
995 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
999 SetWindowPos (GDK_WINDOW_HWND (window), top,
1001 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1006 BringWindowToTop (GDK_WINDOW_HWND (window));
1009 else if (old_active_window != GDK_WINDOW_HWND (window))
1011 SetActiveWindow (old_active_window);
1016 gdk_win32_window_show (GdkWindow *window,
1017 gboolean already_mapped)
1019 show_window_internal (window, FALSE, FALSE);
1023 gdk_win32_window_hide (GdkWindow *window)
1025 GdkWindowObject *private;
1027 private = (GdkWindowObject*) window;
1028 if (private->destroyed)
1031 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1032 GDK_WINDOW_HWND (window),
1033 _gdk_win32_window_state_to_string (private->state)));
1035 if (GDK_WINDOW_IS_MAPPED (window))
1036 gdk_synthesize_window_state (window,
1038 GDK_WINDOW_STATE_WITHDRAWN);
1040 _gdk_window_clear_update_area (window);
1042 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1043 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1045 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1047 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1049 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1053 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1058 gdk_win32_window_withdraw (GdkWindow *window)
1060 GdkWindowObject *private;
1062 private = (GdkWindowObject*) window;
1063 if (private->destroyed)
1066 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1067 GDK_WINDOW_HWND (window),
1068 _gdk_win32_window_state_to_string (private->state)));
1070 gdk_window_hide (window); /* ??? */
1074 gdk_win32_window_move (GdkWindow *window,
1077 GdkWindowObject *private = (GdkWindowObject *)window;
1078 GdkWindowImplWin32 *impl;
1080 g_return_if_fail (GDK_IS_WINDOW (window));
1082 if (GDK_WINDOW_DESTROYED (window))
1085 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1086 GDK_WINDOW_HWND (window), x, y));
1088 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1090 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1093 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1094 * Foreign windows (another app's windows) might be children of our
1095 * windows! Especially in the case of gtkplug/socket.
1097 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1099 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1105 get_outer_rect (window, private->width, private->height, &outer_rect);
1107 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1109 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1110 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1111 GDK_WINDOW_HWND (window),
1112 x - _gdk_offset_x, y - _gdk_offset_y));
1114 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1115 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1116 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1121 gdk_win32_window_resize (GdkWindow *window,
1122 gint width, gint height)
1124 GdkWindowObject *private = (GdkWindowObject*) window;
1125 GdkWindowImplWin32 *impl;
1127 g_return_if_fail (GDK_IS_WINDOW (window));
1129 if (GDK_WINDOW_DESTROYED (window))
1137 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1138 GDK_WINDOW_HWND (window), width, height));
1140 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1142 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1145 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1147 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1153 get_outer_rect (window, width, height, &outer_rect);
1155 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1156 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1157 GDK_WINDOW_HWND (window),
1158 outer_rect.right - outer_rect.left,
1159 outer_rect.bottom - outer_rect.top));
1161 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1163 outer_rect.right - outer_rect.left,
1164 outer_rect.bottom - outer_rect.top,
1165 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1166 private->resize_count += 1;
1171 gdk_win32_window_move_resize_internal (GdkWindow *window,
1177 GdkWindowObject *private;
1178 GdkWindowImplWin32 *impl;
1180 g_return_if_fail (GDK_IS_WINDOW (window));
1182 if (GDK_WINDOW_DESTROYED (window))
1190 private = GDK_WINDOW_OBJECT (window);
1191 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1193 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1196 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1197 GDK_WINDOW_HWND (window),
1198 width, height, x, y));
1200 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1202 _gdk_window_move_resize_child (window, x, y, width, height);
1208 get_outer_rect (window, width, height, &outer_rect);
1210 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1212 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1213 "NOACTIVATE|NOZORDER)\n",
1214 GDK_WINDOW_HWND (window),
1215 x - _gdk_offset_x, y - _gdk_offset_y,
1216 outer_rect.right - outer_rect.left,
1217 outer_rect.bottom - outer_rect.top));
1219 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1220 x - _gdk_offset_x, y - _gdk_offset_y,
1221 outer_rect.right - outer_rect.left,
1222 outer_rect.bottom - outer_rect.top,
1223 SWP_NOACTIVATE | SWP_NOZORDER));
1228 gdk_win32_window_move_resize (GdkWindow *window,
1235 if (with_move && (width < 0 && height < 0))
1237 gdk_win32_window_move (window, x, y);
1243 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1247 gdk_win32_window_resize (window, width, height);
1253 gdk_win32_window_reparent (GdkWindow *window,
1254 GdkWindow *new_parent,
1258 GdkWindowObject *window_private;
1259 GdkWindowObject *parent_private;
1260 GdkWindowObject *old_parent_private;
1261 GdkWindowImplWin32 *impl;
1262 gboolean was_toplevel;
1266 new_parent = _gdk_root;
1268 window_private = (GdkWindowObject*) window;
1269 old_parent_private = (GdkWindowObject *) window_private->parent;
1270 parent_private = (GdkWindowObject*) new_parent;
1271 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1273 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1274 GDK_WINDOW_HWND (window),
1275 GDK_WINDOW_HWND (new_parent)));
1277 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1279 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1280 if (was_toplevel && new_parent != _gdk_root)
1282 /* Reparenting from top-level (child of desktop). Clear out
1285 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1287 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1289 else if (new_parent == _gdk_root)
1291 /* Reparenting to top-level. Add decorations. */
1292 style &= ~(WS_CHILD);
1293 style |= WS_OVERLAPPEDWINDOW;
1294 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1297 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1298 GDK_WINDOW_HWND (new_parent)));
1300 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1301 x, y, window_private->width, window_private->height, TRUE));
1303 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1306 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1307 new_parent = _gdk_root;
1309 window_private->parent = (GdkWindowObject *)new_parent;
1311 /* Switch the window type as appropriate */
1313 switch (GDK_WINDOW_TYPE (new_parent))
1315 case GDK_WINDOW_ROOT:
1316 if (impl->toplevel_window_type != -1)
1317 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1318 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1319 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1322 case GDK_WINDOW_TOPLEVEL:
1323 case GDK_WINDOW_CHILD:
1324 case GDK_WINDOW_TEMP:
1325 if (WINDOW_IS_TOPLEVEL (window))
1327 /* Save the original window type so we can restore it if the
1328 * window is reparented back to be a toplevel.
1330 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1331 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1335 if (old_parent_private)
1336 old_parent_private->children =
1337 g_list_remove (old_parent_private->children, window);
1339 parent_private->children = g_list_prepend (parent_private->children, window);
1345 gdk_win32_window_raise (GdkWindow *window)
1347 if (!GDK_WINDOW_DESTROYED (window))
1349 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1350 GDK_WINDOW_HWND (window)));
1352 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1353 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1355 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1356 else if (((GdkWindowObject *)window)->accept_focus)
1357 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1359 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1361 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1366 gdk_win32_window_lower (GdkWindow *window)
1368 if (!GDK_WINDOW_DESTROYED (window))
1370 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1371 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1372 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1373 GDK_WINDOW_HWND (window),
1374 GDK_WINDOW_HWND (window)));
1376 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1378 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1383 gdk_window_set_urgency_hint (GdkWindow *window,
1386 FLASHWINFO flashwinfo;
1387 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1388 PFN_FlashWindowEx flashWindowEx = NULL;
1390 g_return_if_fail (GDK_IS_WINDOW (window));
1391 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1393 if (GDK_WINDOW_DESTROYED (window))
1396 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1400 flashwinfo.cbSize = sizeof (flashwinfo);
1401 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1403 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1405 flashwinfo.dwFlags = FLASHW_STOP;
1406 flashwinfo.uCount = 0;
1407 flashwinfo.dwTimeout = 0;
1409 flashWindowEx (&flashwinfo);
1413 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1418 get_effective_window_decorations (GdkWindow *window,
1419 GdkWMDecoration *decoration)
1421 GdkWindowImplWin32 *impl;
1423 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1425 if (gdk_window_get_decorations (window, decoration))
1428 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL)
1433 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1434 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1435 impl->hints.min_width == impl->hints.max_width &&
1436 impl->hints.min_height == impl->hints.max_height)
1438 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1440 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1441 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1442 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1444 *decoration |= GDK_DECOR_MINIMIZE;
1446 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1448 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1453 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1455 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1456 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1457 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1458 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1460 *decoration |= GDK_DECOR_MINIMIZE;
1467 switch (impl->type_hint)
1469 case GDK_WINDOW_TYPE_HINT_DIALOG:
1470 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1473 case GDK_WINDOW_TYPE_HINT_MENU:
1474 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1477 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1478 case GDK_WINDOW_TYPE_HINT_UTILITY:
1479 gdk_window_set_skip_taskbar_hint (window, TRUE);
1480 gdk_window_set_skip_pager_hint (window, TRUE);
1481 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1484 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1485 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1486 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1489 case GDK_WINDOW_TYPE_HINT_DOCK:
1492 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1497 case GDK_WINDOW_TYPE_HINT_NORMAL:
1498 *decoration = GDK_DECOR_ALL;
1507 gdk_window_set_geometry_hints (GdkWindow *window,
1508 const GdkGeometry *geometry,
1509 GdkWindowHints geom_mask)
1511 GdkWindowImplWin32 *impl;
1513 g_return_if_fail (GDK_IS_WINDOW (window));
1515 if (GDK_WINDOW_DESTROYED (window))
1518 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1519 GDK_WINDOW_HWND (window)));
1521 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1523 impl->hint_flags = geom_mask;
1524 impl->hints = *geometry;
1526 if (geom_mask & GDK_HINT_POS)
1527 ; /* even the X11 mplementation doesn't care */
1529 if (geom_mask & GDK_HINT_MIN_SIZE)
1531 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1532 geometry->min_width, geometry->min_height));
1535 if (geom_mask & GDK_HINT_MAX_SIZE)
1537 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1538 geometry->max_width, geometry->max_height));
1541 if (geom_mask & GDK_HINT_BASE_SIZE)
1543 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1544 geometry->base_width, geometry->base_height));
1547 if (geom_mask & GDK_HINT_RESIZE_INC)
1549 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1550 geometry->width_inc, geometry->height_inc));
1553 if (geom_mask & GDK_HINT_ASPECT)
1555 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1556 geometry->min_aspect, geometry->max_aspect));
1559 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1561 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1564 update_style_bits (window);
1568 gdk_window_set_title (GdkWindow *window,
1573 g_return_if_fail (GDK_IS_WINDOW (window));
1574 g_return_if_fail (title != NULL);
1576 if (GDK_WINDOW_DESTROYED (window))
1579 /* Empty window titles not allowed, so set it to just a period. */
1583 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1584 GDK_WINDOW_HWND (window), title));
1586 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1588 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1589 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1592 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1596 gdk_window_set_role (GdkWindow *window,
1599 g_return_if_fail (GDK_IS_WINDOW (window));
1601 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1602 GDK_WINDOW_HWND (window),
1603 (role ? role : "NULL")));
1608 gdk_window_set_transient_for (GdkWindow *window,
1611 HWND window_id, parent_id;
1612 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1613 GdkWindowImplWin32 *parent_impl = NULL;
1616 g_return_if_fail (GDK_IS_WINDOW (window));
1618 window_id = GDK_WINDOW_HWND (window);
1619 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1621 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1623 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1625 if (GDK_WINDOW_DESTROYED (window))
1626 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1628 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1633 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1635 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1641 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1642 if (trans_impl->transient_children != NULL)
1644 item = g_slist_find (trans_impl->transient_children, window);
1646 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1647 trans_impl->num_transients--;
1649 if (!trans_impl->num_transients)
1651 trans_impl->transient_children = NULL;
1654 g_object_unref (G_OBJECT (window_impl->transient_owner));
1655 g_object_unref (G_OBJECT (window));
1657 window_impl->transient_owner = NULL;
1661 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1663 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1664 g_object_ref (G_OBJECT (window));
1665 parent_impl->num_transients++;
1666 window_impl->transient_owner = parent;
1667 g_object_ref (G_OBJECT (parent));
1670 /* This changes the *owner* of the window, despite the misleading
1671 * name. (Owner and parent are unrelated concepts.) At least that's
1672 * what people who seem to know what they talk about say on
1673 * USENET. Search on Google.
1676 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1677 GetLastError () != 0)
1678 WIN32_API_FAILED ("SetWindowLongPtr");
1682 _gdk_push_modal_window (GdkWindow *window)
1684 modal_window_stack = g_slist_prepend (modal_window_stack,
1689 _gdk_remove_modal_window (GdkWindow *window)
1693 g_return_if_fail (window != NULL);
1695 /* It's possible to be NULL here if someone sets the modal hint of the window
1696 * to FALSE before a modal window stack has ever been created. */
1697 if (modal_window_stack == NULL)
1700 /* Find the requested window in the stack and remove it. Yeah, I realize this
1701 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1702 tmp = g_slist_find (modal_window_stack, window);
1705 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1710 _gdk_modal_current (void)
1712 if (modal_window_stack != NULL)
1714 GSList *tmp = modal_window_stack;
1716 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1718 tmp = g_slist_next (tmp);
1721 return tmp != NULL ? tmp->data : NULL;
1730 gdk_win32_window_set_background (GdkWindow *window,
1731 cairo_pattern_t *pattern)
1736 gdk_win32_window_set_device_cursor (GdkWindow *window,
1740 GdkWindowImplWin32 *impl;
1741 GdkCursorPrivate *cursor_private;
1743 HCURSOR hprevcursor;
1745 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1746 cursor_private = (GdkCursorPrivate*) cursor;
1748 if (GDK_WINDOW_DESTROYED (window))
1754 hcursor = cursor_private->hcursor;
1756 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1757 GDK_WINDOW_HWND (window),
1760 /* First get the old cursor, if any (we wait to free the old one
1761 * since it may be the current cursor set in the Win32 API right
1764 hprevcursor = impl->hcursor;
1766 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
1768 if (hcursor == NULL)
1769 impl->hcursor = NULL;
1772 /* We must copy the cursor as it is OK to destroy the GdkCursor
1773 * while still in use for some window. See for instance
1774 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1775 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1778 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1779 WIN32_API_FAILED ("CopyCursor");
1780 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1781 hcursor, impl->hcursor));
1784 /* Destroy the previous cursor */
1785 if (hprevcursor != NULL)
1787 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1788 API_CALL (DestroyCursor, (hprevcursor));
1793 gdk_win32_window_get_geometry (GdkWindow *window,
1802 if (!GDK_WINDOW_DESTROYED (window))
1806 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1808 if (window != _gdk_root)
1811 GdkWindow *parent = gdk_window_get_parent (window);
1815 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1816 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1822 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1823 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1827 if (parent == _gdk_root)
1829 rect.left += _gdk_offset_x;
1830 rect.top += _gdk_offset_y;
1831 rect.right += _gdk_offset_x;
1832 rect.bottom += _gdk_offset_y;
1841 *width = rect.right - rect.left;
1843 *height = rect.bottom - rect.top;
1845 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
1846 GDK_WINDOW_HWND (window),
1847 rect.right - rect.left, rect.bottom - rect.top,
1848 gdk_window_get_visual (window)->depth,
1849 rect.left, rect.top));
1854 gdk_win32_window_get_root_coords (GdkWindow *window,
1866 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1871 *root_x = tx + _gdk_offset_x;
1873 *root_y = ty + _gdk_offset_y;
1875 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
1876 GDK_WINDOW_HWND (window),
1878 tx + _gdk_offset_x, ty + _gdk_offset_y));
1883 gdk_win32_window_restack_under (GdkWindow *window,
1884 GList *native_siblings)
1890 gdk_win32_window_restack_toplevel (GdkWindow *window,
1898 gdk_window_get_root_origin (GdkWindow *window,
1904 g_return_if_fail (GDK_IS_WINDOW (window));
1906 gdk_window_get_frame_extents (window, &rect);
1914 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
1915 GDK_WINDOW_HWND (window), rect.x, rect.y));
1919 gdk_window_get_frame_extents (GdkWindow *window,
1922 GdkWindowObject *private;
1926 g_return_if_fail (GDK_IS_WINDOW (window));
1927 g_return_if_fail (rect != NULL);
1929 private = GDK_WINDOW_OBJECT (window);
1936 if (GDK_WINDOW_DESTROYED (window))
1939 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
1940 * necessary to walk its parent chain?
1942 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1943 private = (GdkWindowObject*) private->parent;
1945 hwnd = GDK_WINDOW_HWND (window);
1946 API_CALL (GetWindowRect, (hwnd, &r));
1948 rect->x = r.left + _gdk_offset_x;
1949 rect->y = r.top + _gdk_offset_y;
1950 rect->width = r.right - r.left;
1951 rect->height = r.bottom - r.top;
1953 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
1954 GDK_WINDOW_HWND (window),
1955 r.right - r.left, r.bottom - r.top,
1960 gdk_window_win32_get_device_state (GdkWindow *window,
1964 GdkModifierType *mask)
1968 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
1970 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
1974 return (child != NULL);
1978 _gdk_windowing_get_device_state (GdkDisplay *display,
1983 GdkModifierType *mask)
1985 g_return_if_fail (display == _gdk_display);
1988 *screen = _gdk_screen;
1990 GDK_DEVICE_GET_CLASS (device)->query_state (device,
1991 gdk_screen_get_root_window (_gdk_screen),
1999 gdk_display_warp_pointer (GdkDisplay *display,
2004 GdkDeviceManagerWin32 *device_manager;
2006 g_return_if_fail (display == _gdk_display);
2007 g_return_if_fail (screen == _gdk_screen);
2009 device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
2010 GDK_DEVICE_GET_CLASS (device_manager->core_pointer)->warp (device_manager->core_pointer,
2015 gdk_display_warp_device (GdkDisplay *display,
2021 g_return_if_fail (display == _gdk_display);
2022 g_return_if_fail (screen == _gdk_screen);
2023 g_return_if_fail (GDK_IS_DEVICE (device));
2024 g_return_if_fail (display == gdk_device_get_display (device));
2026 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
2030 _gdk_windowing_window_at_device_position (GdkDisplay *display,
2034 GdkModifierType *mask,
2035 gboolean get_toplevel)
2037 return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
2041 gdk_win32_window_get_events (GdkWindow *window)
2043 if (GDK_WINDOW_DESTROYED (window))
2046 return GDK_WINDOW_OBJECT (window)->event_mask;
2050 gdk_win32_window_set_events (GdkWindow *window,
2051 GdkEventMask event_mask)
2053 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2054 * set it here, too. Not that I know or remember why it is
2055 * necessary, will have to test some day.
2057 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2061 do_shape_combine_region (GdkWindow *window,
2067 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2068 _gdk_win32_adjust_client_rect (window, &rect);
2070 OffsetRgn (hrgn, -rect.left, -rect.top);
2071 OffsetRgn (hrgn, x, y);
2073 /* If this is a top-level window, add the title bar to the region */
2074 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2076 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2077 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2081 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2085 gdk_window_set_override_redirect (GdkWindow *window,
2086 gboolean override_redirect)
2088 g_return_if_fail (GDK_IS_WINDOW (window));
2090 g_warning ("gdk_window_set_override_redirect not implemented");
2094 gdk_window_set_accept_focus (GdkWindow *window,
2095 gboolean accept_focus)
2097 GdkWindowObject *private;
2099 g_return_if_fail (GDK_IS_WINDOW (window));
2101 private = (GdkWindowObject *)window;
2103 accept_focus = accept_focus != FALSE;
2105 if (private->accept_focus != accept_focus)
2106 private->accept_focus = accept_focus;
2110 gdk_window_set_focus_on_map (GdkWindow *window,
2111 gboolean focus_on_map)
2113 GdkWindowObject *private;
2115 g_return_if_fail (GDK_IS_WINDOW (window));
2117 private = (GdkWindowObject *)window;
2119 focus_on_map = focus_on_map != FALSE;
2121 if (private->focus_on_map != focus_on_map)
2122 private->focus_on_map = focus_on_map;
2126 gdk_window_set_icon_list (GdkWindow *window,
2129 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2130 gint big_diff, small_diff;
2131 gint big_w, big_h, small_w, small_h;
2134 HICON small_hicon, big_hicon;
2135 GdkWindowImplWin32 *impl;
2136 gint i, big_i, small_i;
2138 g_return_if_fail (GDK_IS_WINDOW (window));
2140 if (GDK_WINDOW_DESTROYED (window))
2143 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2145 /* ideal sizes for small and large icons */
2146 big_w = GetSystemMetrics (SM_CXICON);
2147 big_h = GetSystemMetrics (SM_CYICON);
2148 small_w = GetSystemMetrics (SM_CXSMICON);
2149 small_h = GetSystemMetrics (SM_CYSMICON);
2151 /* find closest sized icons in the list */
2153 small_pixbuf = NULL;
2159 pixbuf = (GdkPixbuf*) pixbufs->data;
2160 w = gdk_pixbuf_get_width (pixbuf);
2161 h = gdk_pixbuf_get_height (pixbuf);
2163 dw = ABS (w - big_w);
2164 dh = ABS (h - big_h);
2165 diff = dw*dw + dh*dh;
2166 if (big_pixbuf == NULL || diff < big_diff)
2168 big_pixbuf = pixbuf;
2173 dw = ABS (w - small_w);
2174 dh = ABS (h - small_h);
2175 diff = dw*dw + dh*dh;
2176 if (small_pixbuf == NULL || diff < small_diff)
2178 small_pixbuf = pixbuf;
2183 pixbufs = g_list_next (pixbufs);
2187 /* Create the icons */
2188 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2189 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2192 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2194 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2195 (LPARAM)small_hicon);
2197 /* Store the icons, destroying any previous icons */
2198 if (impl->hicon_big)
2199 GDI_CALL (DestroyIcon, (impl->hicon_big));
2200 impl->hicon_big = big_hicon;
2201 if (impl->hicon_small)
2202 GDI_CALL (DestroyIcon, (impl->hicon_small));
2203 impl->hicon_small = small_hicon;
2207 gdk_window_set_icon_name (GdkWindow *window,
2210 /* In case I manage to confuse this again (or somebody else does):
2211 * Please note that "icon name" here really *does* mean the name or
2212 * title of an window minimized as an icon on the desktop, or in the
2213 * taskbar. It has nothing to do with the freedesktop.org icon
2217 g_return_if_fail (GDK_IS_WINDOW (window));
2219 if (GDK_WINDOW_DESTROYED (window))
2223 /* This is not the correct thing to do. We should keep both the
2224 * "normal" window title, and the icon name. When the window is
2225 * minimized, call SetWindowText() with the icon name, and when the
2226 * window is restored, with the normal window title. Also, the name
2227 * is in UTF-8, so we should do the normal conversion to either wide
2228 * chars or system codepage, and use either the W or A version of
2229 * SetWindowText(), depending on Windows version.
2231 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2236 gdk_window_get_group (GdkWindow *window)
2238 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2239 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2241 if (GDK_WINDOW_DESTROYED (window))
2244 g_warning ("gdk_window_get_group not yet implemented");
2250 gdk_window_set_group (GdkWindow *window,
2253 g_return_if_fail (GDK_IS_WINDOW (window));
2254 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2255 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2257 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2260 g_warning ("gdk_window_set_group not implemented");
2264 update_single_bit (LONG *style,
2269 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2270 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2271 * bit indicate whether style_bit is on
2273 if ((!all && gdk_bit) || (all && !gdk_bit))
2274 *style |= style_bit;
2276 *style &= ~style_bit;
2280 update_style_bits (GdkWindow *window)
2282 GdkWindowObject *private = (GdkWindowObject *)window;
2283 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2284 GdkWMDecoration decorations;
2285 LONG old_style, new_style, old_exstyle, new_exstyle;
2287 RECT rect, before, after;
2289 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2290 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2292 GetClientRect (GDK_WINDOW_HWND (window), &before);
2294 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2296 new_style = old_style;
2297 new_exstyle = old_exstyle;
2299 if (private->window_type == GDK_WINDOW_TEMP ||
2300 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2301 new_exstyle |= WS_EX_TOOLWINDOW;
2303 new_exstyle &= ~WS_EX_TOOLWINDOW;
2305 if (get_effective_window_decorations (window, &decorations))
2307 all = (decorations & GDK_DECOR_ALL);
2308 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2309 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2310 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2311 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2312 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2313 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2316 if (old_style == new_style && old_exstyle == new_exstyle )
2318 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2319 GDK_WINDOW_HWND (window)));
2323 if (old_style != new_style)
2325 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2326 GDK_WINDOW_HWND (window),
2327 _gdk_win32_window_style_to_string (old_style),
2328 _gdk_win32_window_style_to_string (new_style)));
2330 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2333 if (old_exstyle != new_exstyle)
2335 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2336 GDK_WINDOW_HWND (window),
2337 _gdk_win32_window_exstyle_to_string (old_exstyle),
2338 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2340 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2343 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2345 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2346 rect.left += after.left - before.left;
2347 rect.top += after.top - before.top;
2348 rect.right += after.right - before.right;
2349 rect.bottom += after.bottom - before.bottom;
2351 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2352 rect.left, rect.top,
2353 rect.right - rect.left, rect.bottom - rect.top,
2354 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2355 SWP_NOREPOSITION | SWP_NOZORDER);
2360 update_single_system_menu_entry (HMENU hmenu,
2365 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2366 * gdk_bit indicates whether menu entry is disabled; if all is
2367 * FALSE, gdk bit indicate whether menu entry is enabled
2369 if ((!all && gdk_bit) || (all && !gdk_bit))
2370 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2372 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2376 update_system_menu (GdkWindow *window)
2378 GdkWMFunction functions;
2381 if (_gdk_window_get_functions (window, &functions))
2383 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2385 all = (functions & GDK_FUNC_ALL);
2386 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2387 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2388 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2389 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2390 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2395 get_decorations_quark ()
2397 static GQuark quark = 0;
2400 quark = g_quark_from_static_string ("gdk-window-decorations");
2406 gdk_window_set_decorations (GdkWindow *window,
2407 GdkWMDecoration decorations)
2409 GdkWMDecoration* decorations_copy;
2411 g_return_if_fail (GDK_IS_WINDOW (window));
2413 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2414 GDK_WINDOW_HWND (window),
2415 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2416 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2417 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2418 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2419 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2420 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2421 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2423 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2424 *decorations_copy = decorations;
2425 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2427 update_style_bits (window);
2431 gdk_window_get_decorations (GdkWindow *window,
2432 GdkWMDecoration *decorations)
2434 GdkWMDecoration* decorations_set;
2436 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2438 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2439 if (decorations_set)
2440 *decorations = *decorations_set;
2442 return (decorations_set != NULL);
2446 get_functions_quark ()
2448 static GQuark quark = 0;
2451 quark = g_quark_from_static_string ("gdk-window-functions");
2457 gdk_window_set_functions (GdkWindow *window,
2458 GdkWMFunction functions)
2460 GdkWMFunction* functions_copy;
2462 g_return_if_fail (GDK_IS_WINDOW (window));
2464 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2465 GDK_WINDOW_HWND (window),
2466 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2467 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2468 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2469 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2470 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2471 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2473 functions_copy = g_malloc (sizeof (GdkWMFunction));
2474 *functions_copy = functions;
2475 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2477 update_system_menu (window);
2481 _gdk_window_get_functions (GdkWindow *window,
2482 GdkWMFunction *functions)
2484 GdkWMDecoration* functions_set;
2486 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2488 *functions = *functions_set;
2490 return (functions_set != NULL);
2494 gdk_win32_window_set_static_gravities (GdkWindow *window,
2495 gboolean use_static)
2497 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2503 gdk_window_begin_resize_drag (GdkWindow *window,
2512 g_return_if_fail (GDK_IS_WINDOW (window));
2514 if (GDK_WINDOW_DESTROYED (window))
2517 /* Tell Windows to start interactively resizing the window by pretending that
2518 * the left pointer button was clicked in the suitable edge or corner. This
2519 * will only work if the button is down when this function is called, and
2520 * will only work with button 1 (left), since Windows only allows window
2521 * dragging using the left mouse button.
2526 /* Must break the automatic grab that occured when the button was
2527 * pressed, otherwise it won't work.
2529 gdk_display_pointer_ungrab (_gdk_display, 0);
2533 case GDK_WINDOW_EDGE_NORTH_WEST:
2534 winedge = HTTOPLEFT;
2537 case GDK_WINDOW_EDGE_NORTH:
2541 case GDK_WINDOW_EDGE_NORTH_EAST:
2542 winedge = HTTOPRIGHT;
2545 case GDK_WINDOW_EDGE_WEST:
2549 case GDK_WINDOW_EDGE_EAST:
2553 case GDK_WINDOW_EDGE_SOUTH_WEST:
2554 winedge = HTBOTTOMLEFT;
2557 case GDK_WINDOW_EDGE_SOUTH:
2561 case GDK_WINDOW_EDGE_SOUTH_EAST:
2563 winedge = HTBOTTOMRIGHT;
2567 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2568 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2572 gdk_window_begin_move_drag (GdkWindow *window,
2578 g_return_if_fail (GDK_IS_WINDOW (window));
2580 if (GDK_WINDOW_DESTROYED (window))
2583 /* Tell Windows to start interactively moving the window by pretending that
2584 * the left pointer button was clicked in the titlebar. This will only work
2585 * if the button is down when this function is called, and will only work
2586 * with button 1 (left), since Windows only allows window dragging using the
2587 * left mouse button.
2592 /* Must break the automatic grab that occured when the button was pressed,
2593 * otherwise it won't work.
2595 gdk_display_pointer_ungrab (_gdk_display, 0);
2597 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2598 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2603 * Setting window states
2606 gdk_window_iconify (GdkWindow *window)
2608 HWND old_active_window;
2610 g_return_if_fail (GDK_IS_WINDOW (window));
2612 if (GDK_WINDOW_DESTROYED (window))
2615 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2616 GDK_WINDOW_HWND (window),
2617 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2619 if (GDK_WINDOW_IS_MAPPED (window))
2621 old_active_window = GetActiveWindow ();
2622 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2623 if (old_active_window != GDK_WINDOW_HWND (window))
2624 SetActiveWindow (old_active_window);
2628 gdk_synthesize_window_state (window,
2630 GDK_WINDOW_STATE_ICONIFIED);
2635 gdk_window_deiconify (GdkWindow *window)
2637 g_return_if_fail (GDK_IS_WINDOW (window));
2639 if (GDK_WINDOW_DESTROYED (window))
2642 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2643 GDK_WINDOW_HWND (window),
2644 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2646 if (GDK_WINDOW_IS_MAPPED (window))
2648 show_window_internal (window, FALSE, TRUE);
2652 gdk_synthesize_window_state (window,
2653 GDK_WINDOW_STATE_ICONIFIED,
2659 gdk_window_stick (GdkWindow *window)
2661 g_return_if_fail (GDK_IS_WINDOW (window));
2663 if (GDK_WINDOW_DESTROYED (window))
2666 /* FIXME: Do something? */
2670 gdk_window_unstick (GdkWindow *window)
2672 g_return_if_fail (GDK_IS_WINDOW (window));
2674 if (GDK_WINDOW_DESTROYED (window))
2677 /* FIXME: Do something? */
2681 gdk_window_maximize (GdkWindow *window)
2683 g_return_if_fail (GDK_IS_WINDOW (window));
2685 if (GDK_WINDOW_DESTROYED (window))
2688 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2689 GDK_WINDOW_HWND (window),
2690 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2692 if (GDK_WINDOW_IS_MAPPED (window))
2693 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2695 gdk_synthesize_window_state (window,
2697 GDK_WINDOW_STATE_MAXIMIZED);
2701 gdk_window_unmaximize (GdkWindow *window)
2703 g_return_if_fail (GDK_IS_WINDOW (window));
2705 if (GDK_WINDOW_DESTROYED (window))
2708 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2709 GDK_WINDOW_HWND (window),
2710 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2712 if (GDK_WINDOW_IS_MAPPED (window))
2713 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2715 gdk_synthesize_window_state (window,
2716 GDK_WINDOW_STATE_MAXIMIZED,
2720 typedef struct _FullscreenInfo FullscreenInfo;
2722 struct _FullscreenInfo
2730 gdk_window_fullscreen (GdkWindow *window)
2732 gint x, y, width, height;
2734 GdkWindowObject *private = (GdkWindowObject *) window;
2738 g_return_if_fail (GDK_IS_WINDOW (window));
2740 fi = g_new (FullscreenInfo, 1);
2742 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2746 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2748 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
2749 mi.cbSize = sizeof (mi);
2750 if (monitor && GetMonitorInfo (monitor, &mi))
2752 x = mi.rcMonitor.left;
2753 y = mi.rcMonitor.top;
2754 width = mi.rcMonitor.right - x;
2755 height = mi.rcMonitor.bottom - y;
2760 width = GetSystemMetrics (SM_CXSCREEN);
2761 height = GetSystemMetrics (SM_CYSCREEN);
2764 /* remember for restoring */
2765 fi->hint_flags = impl->hint_flags;
2766 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
2767 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
2768 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2770 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2771 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
2773 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
2774 x, y, width, height,
2775 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2777 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2782 gdk_window_unfullscreen (GdkWindow *window)
2785 GdkWindowObject *private = (GdkWindowObject *) window;
2787 g_return_if_fail (GDK_IS_WINDOW (window));
2789 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
2792 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2794 impl->hint_flags = fi->hint_flags;
2795 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
2796 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
2797 fi->r.left, fi->r.top,
2798 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
2799 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2801 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
2804 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2809 gdk_window_set_keep_above (GdkWindow *window,
2812 g_return_if_fail (GDK_IS_WINDOW (window));
2814 if (GDK_WINDOW_DESTROYED (window))
2817 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
2818 GDK_WINDOW_HWND (window),
2819 setting ? "YES" : "NO"));
2821 if (GDK_WINDOW_IS_MAPPED (window))
2823 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2824 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
2826 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2829 gdk_synthesize_window_state (window,
2830 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
2831 setting ? GDK_WINDOW_STATE_ABOVE : 0);
2835 gdk_window_set_keep_below (GdkWindow *window,
2838 g_return_if_fail (GDK_IS_WINDOW (window));
2840 if (GDK_WINDOW_DESTROYED (window))
2843 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
2844 GDK_WINDOW_HWND (window),
2845 setting ? "YES" : "NO"));
2847 if (GDK_WINDOW_IS_MAPPED (window))
2849 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2850 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
2852 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2855 gdk_synthesize_window_state (window,
2856 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
2857 setting ? GDK_WINDOW_STATE_BELOW : 0);
2861 gdk_window_focus (GdkWindow *window,
2864 g_return_if_fail (GDK_IS_WINDOW (window));
2866 if (GDK_WINDOW_DESTROYED (window))
2869 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
2870 GDK_WINDOW_HWND (window),
2871 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2873 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
2874 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
2876 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2877 SetFocus (GDK_WINDOW_HWND (window));
2881 gdk_window_set_modal_hint (GdkWindow *window,
2884 GdkWindowObject *private;
2886 g_return_if_fail (GDK_IS_WINDOW (window));
2888 if (GDK_WINDOW_DESTROYED (window))
2891 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
2892 GDK_WINDOW_HWND (window),
2893 modal ? "YES" : "NO"));
2895 private = (GdkWindowObject*) window;
2897 if (modal == private->modal_hint)
2900 private->modal_hint = modal;
2903 /* Not sure about this one.. -- Cody */
2904 if (GDK_WINDOW_IS_MAPPED (window))
2905 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2906 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
2908 SWP_NOMOVE | SWP_NOSIZE));
2913 _gdk_push_modal_window (window);
2914 gdk_window_raise (window);
2918 _gdk_remove_modal_window (window);
2925 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2926 gboolean skips_taskbar)
2928 static GdkWindow *owner = NULL;
2931 g_return_if_fail (GDK_IS_WINDOW (window));
2933 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
2934 GDK_WINDOW_HWND (window),
2935 skips_taskbar ? "YES" : "NO"));
2937 // ### TODO: Need to figure out what to do here.
2945 wa.window_type = GDK_WINDOW_TEMP;
2946 wa.wclass = GDK_INPUT_OUTPUT;
2947 wa.width = wa.height = 1;
2949 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
2953 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
2955 #if 0 /* Should we also turn off the minimize and maximize buttons? */
2956 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2957 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
2959 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2961 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2962 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2967 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
2972 gdk_window_set_skip_pager_hint (GdkWindow *window,
2973 gboolean skips_pager)
2975 g_return_if_fail (GDK_IS_WINDOW (window));
2977 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
2978 GDK_WINDOW_HWND (window),
2979 skips_pager ? "YES" : "NO"));
2983 gdk_window_set_type_hint (GdkWindow *window,
2984 GdkWindowTypeHint hint)
2986 g_return_if_fail (GDK_IS_WINDOW (window));
2988 if (GDK_WINDOW_DESTROYED (window))
2993 static GEnumClass *class = NULL;
2995 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
2996 g_print ("gdk_window_set_type_hint: %p: %s\n",
2997 GDK_WINDOW_HWND (window),
2998 g_enum_get_value (class, hint)->value_name);
3001 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3003 update_style_bits (window);
3007 gdk_window_get_type_hint (GdkWindow *window)
3009 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3011 if (GDK_WINDOW_DESTROYED (window))
3012 return GDK_WINDOW_TYPE_HINT_NORMAL;
3014 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3018 cairo_region_to_hrgn (const cairo_region_t *region,
3025 cairo_rectangle_int_t r;
3026 const int nrects = cairo_region_num_rectangles (region);
3028 sizeof (RGNDATAHEADER) + (sizeof (RECT) * nrects);
3031 rgndata = g_malloc (nbytes);
3032 rgndata->rdh.dwSize = sizeof (RGNDATAHEADER);
3033 rgndata->rdh.iType = RDH_RECTANGLES;
3034 rgndata->rdh.nCount = rgndata->rdh.nRgnSize = 0;
3035 SetRect (&rgndata->rdh.rcBound,
3036 G_MAXLONG, G_MAXLONG, G_MINLONG, G_MINLONG);
3038 for (i = 0; i < nrects; i++)
3040 rect = ((RECT *) rgndata->Buffer) + rgndata->rdh.nCount++;
3042 cairo_region_get_rectangle (region, i, &r);
3043 rect->left = r.x + x_origin;
3044 rect->right = rect->left + r.width;
3045 rect->top = r.y + y_origin;
3046 rect->bottom = rect->top + r.height;
3048 if (rect->left < rgndata->rdh.rcBound.left)
3049 rgndata->rdh.rcBound.left = rect->left;
3050 if (rect->right > rgndata->rdh.rcBound.right)
3051 rgndata->rdh.rcBound.right = rect->right;
3052 if (rect->top < rgndata->rdh.rcBound.top)
3053 rgndata->rdh.rcBound.top = rect->top;
3054 if (rect->bottom > rgndata->rdh.rcBound.bottom)
3055 rgndata->rdh.rcBound.bottom = rect->bottom;
3057 if ((hrgn = ExtCreateRegion (NULL, nbytes, rgndata)) == NULL)
3058 WIN32_API_FAILED ("ExtCreateRegion");
3066 gdk_win32_window_shape_combine_region (GdkWindow *window,
3067 const cairo_region_t *shape_region,
3071 if (GDK_WINDOW_DESTROYED (window))
3076 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3077 GDK_WINDOW_HWND (window)));
3078 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3084 hrgn = cairo_region_to_hrgn (shape_region, 0, 0);
3086 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3087 GDK_WINDOW_HWND (window),
3090 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3095 gdk_window_lookup_for_display (GdkDisplay *display,
3096 GdkNativeWindow anid)
3098 g_return_val_if_fail (display == _gdk_display, NULL);
3100 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
3104 gdk_window_enable_synchronized_configure (GdkWindow *window)
3106 g_return_if_fail (GDK_IS_WINDOW (window));
3110 gdk_window_configure_finished (GdkWindow *window)
3112 g_return_if_fail (GDK_IS_WINDOW (window));
3116 gdk_window_set_opacity (GdkWindow *window,
3120 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3121 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3123 g_return_if_fail (GDK_IS_WINDOW (window));
3124 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3126 if (GDK_WINDOW_DESTROYED (window))
3131 else if (opacity > 1)
3134 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3136 if (!(exstyle & WS_EX_LAYERED))
3137 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3139 exstyle | WS_EX_LAYERED));
3141 setLayeredWindowAttributes =
3142 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3144 if (setLayeredWindowAttributes)
3146 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3153 static cairo_region_t *
3154 gdk_win32_window_get_shape (GdkWindow *window)
3156 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3157 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3159 if (type == SIMPLEREGION || type == COMPLEXREGION)
3161 cairo_region_t *region = _gdk_win32_hrgn_to_region (hrgn);
3163 DeleteObject (hrgn);
3170 static cairo_region_t *
3171 _gdk_win32_window_get_input_shape (GdkWindow *window)
3173 /* CHECK: are these really supposed to be the same? */
3174 return _gdk_windowing_window_get_shape (window);
3178 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3179 cairo_region_t *area)
3181 HRGN hrgn = cairo_region_to_hrgn (area, 0, 0);
3183 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3184 GDK_WINDOW_HWND (window),
3185 _gdk_win32_cairo_region_to_string (area)));
3187 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3189 DeleteObject (hrgn);
3194 /* FIXME: Tis function has never been compiled.
3195 * Please make it work. */
3197 _gdk_win32_window_translate (GdkWindow *window,
3198 cairo_region_t *area,
3202 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3205 GdkRectangle extents;
3207 cairo_region_get_extents (area, &extents);
3208 hdc = _gdk_win32_drawable_acquire_dc (GDK_DRAWABLE (window));
3209 GDI_CALL (BitBlt, (hdc, extents.x, extents.y, extents.width, extents.height,
3210 hdc, extents.x + dx, extents.y + dy, SRCCOPY));
3212 /* XXX: We probably need to get invalidations for the whole extents and not
3213 * just the area as we BitBlt */
3214 ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
3216 WIN32_API_FAILED ("GetUpdateRgn");
3217 else if (ret != NULLREGION)
3219 /* Get current updateregion, move any part of it that intersects area by dx,dy */
3220 HRGN update = cairo_region_to_hrgn (area, 0, 0);
3221 ret = CombineRgn (update, hrgn, update, RGN_AND);
3223 WIN32_API_FAILED ("CombineRgn");
3224 else if (ret != NULLREGION)
3226 OffsetRgn (update, dx, dy);
3227 API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE));
3229 DeleteObject (update);
3231 DeleteObject (hrgn);
3235 gdk_win32_input_shape_combine_region (GdkWindow *window,
3236 const cairo_region_t *shape_region,
3240 if (GDK_WINDOW_DESTROYED (window))
3242 /* CHECK: are these really supposed to be the same? */
3243 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3247 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3248 cairo_region_t *region)
3250 _gdk_window_process_updates_recurse (window, region);
3254 _gdk_windowing_before_process_all_updates (void)
3259 _gdk_windowing_after_process_all_updates (void)
3264 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3266 iface->show = gdk_win32_window_show;
3267 iface->hide = gdk_win32_window_hide;
3268 iface->withdraw = gdk_win32_window_withdraw;
3269 iface->set_events = gdk_win32_window_set_events;
3270 iface->get_events = gdk_win32_window_get_events;
3271 iface->raise = gdk_win32_window_raise;
3272 iface->lower = gdk_win32_window_lower;
3273 iface->restack_under = gdk_win32_window_restack_under;
3274 iface->restack_toplevel = gdk_win32_window_restack_toplevel;
3275 iface->move_resize = gdk_win32_window_move_resize;
3276 iface->set_background = gdk_win32_window_set_background;
3277 iface->reparent = gdk_win32_window_reparent;
3278 iface->set_device_cursor = gdk_win32_window_set_device_cursor;
3279 iface->get_geometry = gdk_win32_window_get_geometry;
3280 iface->get_device_state = gdk_window_win32_get_device_state;
3281 iface->get_root_coords = gdk_win32_window_get_root_coords;
3282 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3283 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3284 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3285 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3286 iface->translate = _gdk_win32_window_translate;
3287 iface->destroy = gdk_win32_window_destroy;
3288 iface->destroy_foreign = gdk_win32_window_destroy_foreign;
3289 iface->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
3290 iface->get_shape = gdk_win32_window_get_shape;
3291 iface->get_input_shape = gdk_win32_window_get_input_shape;
3295 gdk_win32_window_is_win32 (GdkWindow *window)
3297 return GDK_WINDOW_IS_WIN32 (window);