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 GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
41 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
42 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
43 static void gdk_window_impl_win32_finalize (GObject *object);
45 static gpointer parent_class = NULL;
46 static GSList *modal_window_stack = NULL;
48 static void update_style_bits (GdkWindow *window);
49 static gboolean _gdk_window_get_functions (GdkWindow *window,
50 GdkWMFunction *functions);
52 #define WINDOW_IS_TOPLEVEL(window) \
53 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
54 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
55 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
57 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
60 GDK_WINDOW_SCREEN (GObject *win)
66 _gdk_window_impl_win32_get_type (void)
68 static GType object_type = 0;
72 const GTypeInfo object_info =
74 sizeof (GdkWindowImplWin32Class),
76 (GBaseFinalizeFunc) NULL,
77 (GClassInitFunc) gdk_window_impl_win32_class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (GdkWindowImplWin32),
82 (GInstanceInitFunc) gdk_window_impl_win32_init,
85 const GInterfaceInfo window_impl_info =
87 (GInterfaceInitFunc) gdk_window_impl_iface_init,
92 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
95 g_type_add_interface_static (object_type,
104 _gdk_window_impl_get_type (void)
106 return _gdk_window_impl_win32_get_type ();
110 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
112 impl->toplevel_window_type = -1;
113 impl->hcursor = NULL;
114 impl->hicon_big = NULL;
115 impl->hicon_small = NULL;
116 impl->hint_flags = 0;
117 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
118 impl->extension_events_selected = FALSE;
119 impl->transient_owner = NULL;
120 impl->transient_children = NULL;
121 impl->num_transients = 0;
122 impl->changing_state = FALSE;
126 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
128 GObjectClass *object_class = G_OBJECT_CLASS (klass);
129 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
131 parent_class = g_type_class_peek_parent (klass);
133 object_class->finalize = gdk_window_impl_win32_finalize;
135 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
139 gdk_window_impl_win32_finalize (GObject *object)
141 GdkWindowObject *wrapper;
142 GdkDrawableImplWin32 *draw_impl;
143 GdkWindowImplWin32 *window_impl;
145 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
147 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
148 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
150 wrapper = (GdkWindowObject*) draw_impl->wrapper;
152 if (!GDK_WINDOW_DESTROYED (wrapper))
154 gdk_win32_handle_table_remove (draw_impl->handle);
157 if (window_impl->hcursor != NULL)
159 if (GetCursor () == window_impl->hcursor)
162 GDI_CALL (DestroyCursor, (window_impl->hcursor));
163 window_impl->hcursor = NULL;
166 if (window_impl->hicon_big != NULL)
168 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
169 window_impl->hicon_big = NULL;
172 if (window_impl->hicon_small != NULL)
174 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
175 window_impl->hicon_small = NULL;
178 G_OBJECT_CLASS (parent_class)->finalize (object);
182 _gdk_win32_adjust_client_rect (GdkWindow *window,
187 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
188 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
189 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
193 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
195 GdkDrawableImplWin32 *drawable_impl;
197 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
199 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
201 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
202 drawable_impl->colormap == NULL)
204 drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
205 g_object_ref (drawable_impl->colormap);
208 return drawable_impl->colormap;
212 _gdk_root_window_size_init (void)
214 GdkWindowObject *window_object;
218 window_object = GDK_WINDOW_OBJECT (_gdk_root);
219 rect = _gdk_monitors[0].rect;
220 for (i = 1; i < _gdk_num_monitors; i++)
221 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
223 window_object->width = rect.width;
224 window_object->height = rect.height;
228 _gdk_windowing_window_init (GdkScreen *screen)
230 GdkWindowObject *private;
231 GdkDrawableImplWin32 *draw_impl;
233 g_assert (_gdk_root == NULL);
235 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
236 private = (GdkWindowObject *)_gdk_root;
237 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
238 private->impl_window = private;
239 private->visual = gdk_screen_get_system_visual (screen);
241 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
243 draw_impl->handle = GetDesktopWindow ();
244 draw_impl->wrapper = GDK_DRAWABLE (private);
245 draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
246 g_object_ref (draw_impl->colormap);
248 private->window_type = GDK_WINDOW_ROOT;
249 private->depth = gdk_visual_get_system ()->depth;
251 _gdk_root_window_size_init ();
257 /* width and height already initialised in _gdk_root_window_size_init() */
258 private->viewable = TRUE;
260 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
262 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
266 get_default_title (void)
269 title = g_get_application_name ();
271 title = g_get_prgname ();
277 * is a wrapper function for RegisterWindowClassEx.
278 * It creates at least one unique class for every
279 * GdkWindowType. If support for single window-specific icons
280 * is ever needed (e.g Dialog specific), every such window should
284 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
286 static ATOM klassTOPLEVEL = 0;
287 static ATOM klassCHILD = 0;
288 static ATOM klassTEMP = 0;
289 static ATOM klassTEMPSHADOW = 0;
290 static HICON hAppIcon = NULL;
291 static HICON hAppIconSm = NULL;
292 static WNDCLASSEXW wcl;
295 wcl.cbSize = sizeof (WNDCLASSEX);
296 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
297 * on WM_SIZE and WM_MOVE. Flicker, Performance!
299 wcl.lpfnWndProc = _gdk_win32_window_procedure;
302 wcl.hInstance = _gdk_app_hmodule;
306 /* initialize once! */
307 if (0 == hAppIcon && 0 == hAppIconSm)
309 gchar sLoc [MAX_PATH+1];
311 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
313 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
315 if (0 == hAppIcon && 0 == hAppIconSm)
317 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
319 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
324 if (0 == hAppIcon && 0 == hAppIconSm)
326 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
327 GetSystemMetrics (SM_CXICON),
328 GetSystemMetrics (SM_CYICON), 0);
329 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
330 GetSystemMetrics (SM_CXSMICON),
331 GetSystemMetrics (SM_CYSMICON), 0);
336 hAppIcon = hAppIconSm;
337 else if (0 == hAppIconSm)
338 hAppIconSm = hAppIcon;
340 wcl.lpszMenuName = NULL;
342 /* initialize once per class */
344 * HB: Setting the background brush leads to flicker, because we
345 * don't get asked how to clear the background. This is not what
346 * we want, at least not for input_only windows ...
348 #define ONCE_PER_CLASS() \
349 wcl.hIcon = CopyIcon (hAppIcon); \
350 wcl.hIconSm = CopyIcon (hAppIconSm); \
351 wcl.hbrBackground = NULL; \
352 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
356 case GDK_WINDOW_TOPLEVEL:
357 if (0 == klassTOPLEVEL)
359 wcl.lpszClassName = L"gdkWindowToplevel";
362 klassTOPLEVEL = RegisterClassExW (&wcl);
364 klass = klassTOPLEVEL;
367 case GDK_WINDOW_CHILD:
370 wcl.lpszClassName = L"gdkWindowChild";
372 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
374 klassCHILD = RegisterClassExW (&wcl);
379 case GDK_WINDOW_TEMP:
380 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
381 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
382 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
383 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
385 if (klassTEMPSHADOW == 0)
387 wcl.lpszClassName = L"gdkWindowTempShadow";
388 wcl.style |= CS_SAVEBITS;
389 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
390 LOWORD (g_win32_get_windows_version()) == 0x0105)
392 /* Windows XP (5.1) or above */
393 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
396 klassTEMPSHADOW = RegisterClassExW (&wcl);
399 klass = klassTEMPSHADOW;
405 wcl.lpszClassName = L"gdkWindowTemp";
406 wcl.style |= CS_SAVEBITS;
408 klassTEMP = RegisterClassExW (&wcl);
416 g_assert_not_reached ();
422 WIN32_API_FAILED ("RegisterClassExW");
423 g_error ("That is a fatal error");
429 _gdk_window_impl_new (GdkWindow *window,
430 GdkWindow *real_parent,
432 GdkEventMask event_mask,
433 GdkWindowAttr *attributes,
434 gint attributes_mask)
439 DWORD dwStyle = 0, dwExStyle;
441 GdkWindow *orig_parent;
442 GdkWindowObject *private;
443 GdkWindowImplWin32 *impl;
444 GdkDrawableImplWin32 *draw_impl;
447 gint window_width, window_height;
448 gint offset_x = 0, offset_y = 0;
450 private = (GdkWindowObject *)window;
452 orig_parent = real_parent;
455 g_print ("_gdk_window_impl_new: %s\n",
456 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
457 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
458 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
461 hparent = GDK_WINDOW_HWND (real_parent);
463 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
464 private->impl = (GdkDrawable *)impl;
465 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
466 draw_impl->wrapper = GDK_DRAWABLE (window);
468 // XXX: xattributes_mask = 0
471 if (attributes_mask & GDK_WA_VISUAL)
472 visual = attributes->visual;
474 visual = gdk_visual_get_system ();
478 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
479 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
481 impl->extension_events_selected = FALSE;
484 if (attributes->wclass == GDK_INPUT_OUTPUT)
488 private->input_only = FALSE;
490 if (attributes_mask & GDK_WA_COLORMAP)
492 draw_impl->colormap = attributes->colormap;
493 g_object_ref (attributes->colormap);
497 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
498 g_object_ref (draw_impl->colormap);
503 /* I very much doubt using WS_EX_TRANSPARENT actually
504 * corresponds to how X11 InputOnly windows work, but it appears
505 * to work well enough for the actual use cases in gtk.
507 dwExStyle = WS_EX_TRANSPARENT;
509 private->input_only = TRUE;
510 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
511 g_object_ref (draw_impl->colormap);
512 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap\n"));
515 switch (private->window_type)
517 case GDK_WINDOW_TOPLEVEL:
518 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
520 /* The common code warns for this case. */
521 hparent = GetDesktopWindow ();
523 /* Children of foreign windows aren't toplevel windows */
524 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
526 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
530 if (private->window_type == GDK_WINDOW_TOPLEVEL)
531 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
533 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
535 offset_x = _gdk_offset_x;
536 offset_y = _gdk_offset_y;
540 case GDK_WINDOW_CHILD:
541 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
544 case GDK_WINDOW_TEMP:
545 /* A temp window is not necessarily a top level window */
546 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
547 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
548 dwExStyle |= WS_EX_TOOLWINDOW;
549 offset_x = _gdk_offset_x;
550 offset_y = _gdk_offset_y;
554 g_assert_not_reached ();
557 if (private->window_type != GDK_WINDOW_CHILD)
559 rect.left = rect.top = 0;
560 rect.right = private->width;
561 rect.bottom = private->height;
563 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
565 window_width = rect.right - rect.left;
566 window_height = rect.bottom - rect.top;
570 window_width = private->width;
571 window_height = private->height;
574 if (attributes_mask & GDK_WA_TITLE)
575 title = attributes->title;
577 title = get_default_title ();
578 if (!title || !*title)
581 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
583 if (attributes_mask & GDK_WA_TYPE_HINT)
584 impl->type_hint = attributes->type_hint;
586 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
588 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
589 dwExStyle |= WS_EX_TOOLWINDOW;
592 private->parent->children = g_list_prepend (private->parent->children, window);
594 klass = RegisterGdkClass (private->window_type, impl->type_hint);
596 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
598 hwndNew = CreateWindowExW (dwExStyle,
599 MAKEINTRESOURCEW (klass),
602 ((attributes_mask & GDK_WA_X) ?
603 private->x - offset_x : CW_USEDEFAULT),
604 private->y - offset_y,
605 window_width, window_height,
610 if (GDK_WINDOW_HWND (window) != hwndNew)
612 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
613 GDK_WINDOW_HWND (window),
616 /* HB: IHMO due to a race condition the handle was increased by
617 * one, which causes much trouble. Because I can't find the
618 * real bug, try to workaround it ...
619 * To reproduce: compile with MSVC 5, DEBUG=1
622 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
623 GDK_WINDOW_HWND (window) = hwndNew;
624 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
626 /* the old behaviour, but with warning */
627 draw_impl->handle = hwndNew;
632 g_object_ref (window);
633 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
635 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
637 window_width, window_height,
638 ((attributes_mask & GDK_WA_X) ?
639 private->x - offset_x: CW_USEDEFAULT),
640 private->y - offset_y,
642 GDK_WINDOW_HWND (window)));
644 /* Add window handle to title */
645 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
649 if (draw_impl->handle == NULL)
651 WIN32_API_FAILED ("CreateWindowExW");
652 g_object_unref (window);
656 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
657 // gdk_window_set_skip_taskbar_hint (window, TRUE);
659 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
660 (attributes->cursor) :
665 gdk_window_foreign_new_for_display (GdkDisplay *display,
666 GdkNativeWindow anid)
669 GdkWindowObject *private;
670 GdkWindowImplWin32 *impl;
671 GdkDrawableImplWin32 *draw_impl;
677 g_return_val_if_fail (display == _gdk_display, NULL);
679 window = g_object_new (GDK_TYPE_WINDOW, NULL);
680 private = (GdkWindowObject *)window;
681 private->visual = gdk_screen_get_system_visual (_gdk_screen);
682 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
683 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
684 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
685 draw_impl->wrapper = GDK_DRAWABLE (window);
686 parent = GetParent ((HWND)anid);
688 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
689 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
690 private->parent = (GdkWindowObject *)_gdk_root;
692 private->parent->children = g_list_prepend (private->parent->children, window);
694 draw_impl->handle = (HWND) anid;
695 GetClientRect ((HWND) anid, &rect);
697 point.y = rect.right;
698 ClientToScreen ((HWND) anid, &point);
699 if (parent != GetDesktopWindow ())
700 ScreenToClient (parent, &point);
701 private->x = point.x;
702 private->y = point.y;
703 private->width = rect.right - rect.left;
704 private->height = rect.bottom - rect.top;
705 private->window_type = GDK_WINDOW_FOREIGN;
706 private->destroyed = FALSE;
707 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
708 if (IsWindowVisible ((HWND) anid))
709 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
711 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
712 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
713 private->state |= GDK_WINDOW_STATE_ABOVE;
715 private->state &= (~GDK_WINDOW_STATE_ABOVE);
716 private->state &= (~GDK_WINDOW_STATE_BELOW);
717 private->viewable = TRUE;
719 private->depth = gdk_visual_get_system ()->depth;
721 g_object_ref (window);
722 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
724 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
726 _gdk_win32_drawable_description (window),
727 private->x, private->y));
733 gdk_window_lookup (GdkNativeWindow hwnd)
735 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
739 _gdk_win32_window_destroy (GdkWindow *window,
741 gboolean foreign_destroy)
743 GdkWindowObject *private = (GdkWindowObject *)window;
744 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
747 g_return_if_fail (GDK_IS_WINDOW (window));
749 GDK_NOTE (MISC, g_print ("_gdk_win32_window_destroy: %p\n",
750 GDK_WINDOW_HWND (window)));
752 /* Remove ourself from the modal stack */
753 _gdk_remove_modal_window (window);
755 /* Remove all our transient children */
756 tmp = window_impl->transient_children;
759 GdkWindow *child = tmp->data;
760 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
762 child_impl->transient_owner = NULL;
763 tmp = g_slist_next (tmp);
765 g_slist_free (window_impl->transient_children);
766 window_impl->transient_children = NULL;
768 /* Remove ourself from our transient owner */
769 if (window_impl->transient_owner != NULL)
771 gdk_window_set_transient_for (window, NULL);
774 if (!recursing && !foreign_destroy)
776 _gdk_win32_drawable_finish (private->impl);
778 private->destroyed = TRUE;
779 DestroyWindow (GDK_WINDOW_HWND (window));
782 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
786 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
788 /* It's somebody else's window, but in our hierarchy, so reparent it
789 * to the desktop, and then try to destroy it.
791 gdk_window_hide (window);
792 gdk_window_reparent (window, NULL, 0, 0);
794 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
797 /* This function is called when the window really gone.
800 gdk_window_destroy_notify (GdkWindow *window)
802 g_return_if_fail (GDK_IS_WINDOW (window));
805 g_print ("gdk_window_destroy_notify: %p%s\n",
806 GDK_WINDOW_HWND (window),
807 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
809 if (!GDK_WINDOW_DESTROYED (window))
811 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
812 g_warning ("window %p unexpectedly destroyed",
813 GDK_WINDOW_HWND (window));
815 _gdk_window_destroy (window, TRUE);
818 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
819 g_object_unref (window);
823 get_outer_rect (GdkWindow *window,
828 rect->left = rect->top = 0;
830 rect->bottom = height;
832 _gdk_win32_adjust_client_rect (window, rect);
836 adjust_for_gravity_hints (GdkWindow *window,
841 GdkWindowObject *obj;
842 GdkWindowImplWin32 *impl;
844 obj = GDK_WINDOW_OBJECT (window);
845 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
847 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
849 gint orig_x = *x, orig_y = *y;
851 switch (impl->hints.win_gravity)
853 case GDK_GRAVITY_NORTH:
854 case GDK_GRAVITY_CENTER:
855 case GDK_GRAVITY_SOUTH:
856 *x -= (outer_rect->right - outer_rect->left) / 2;
857 *x += obj->width / 2;
860 case GDK_GRAVITY_SOUTH_EAST:
861 case GDK_GRAVITY_EAST:
862 case GDK_GRAVITY_NORTH_EAST:
863 *x -= outer_rect->right - outer_rect->left;
867 case GDK_GRAVITY_STATIC:
868 *x += outer_rect->left;
875 switch (impl->hints.win_gravity)
877 case GDK_GRAVITY_WEST:
878 case GDK_GRAVITY_CENTER:
879 case GDK_GRAVITY_EAST:
880 *y -= (outer_rect->bottom - outer_rect->top) / 2;
881 *y += obj->height / 2;
884 case GDK_GRAVITY_SOUTH_WEST:
885 case GDK_GRAVITY_SOUTH:
886 case GDK_GRAVITY_SOUTH_EAST:
887 *y -= outer_rect->bottom - outer_rect->top;
891 case GDK_GRAVITY_STATIC:
892 *y += outer_rect->top;
899 (orig_x != *x || orig_y != *y) ?
900 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
901 orig_x, *x, orig_y, *y)
907 show_window_internal (GdkWindow *window,
911 GdkWindowObject *private;
912 HWND old_active_window;
913 gboolean focus_on_map = TRUE;
917 private = (GdkWindowObject *) window;
919 if (private->destroyed)
922 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
923 GDK_WINDOW_HWND (window),
924 _gdk_win32_window_state_to_string (private->state),
925 (raise ? " raise" : ""),
926 (deiconify ? " deiconify" : "")));
928 /* If asked to show (not deiconify) an withdrawn and iconified
932 !GDK_WINDOW_IS_MAPPED (window) &&
933 (private->state & GDK_WINDOW_STATE_ICONIFIED))
935 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
939 /* If asked to just show an iconified window, do nothing. */
940 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
943 /* If asked to deiconify an already noniconified window, do
944 * nothing. (Especially, don't cause the window to rise and
945 * activate. There are different calls for that.)
947 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
950 /* If asked to show (but not raise) a window that is already
951 * visible, do nothing.
953 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
958 if (!GDK_WINDOW_IS_MAPPED (window))
960 gdk_synthesize_window_state (window,
961 GDK_WINDOW_STATE_WITHDRAWN,
963 focus_on_map = private->focus_on_map;
966 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
968 if (private->state & GDK_WINDOW_STATE_BELOW)
969 exstyle &= (~WS_EX_TOPMOST);
971 if (private->state & GDK_WINDOW_STATE_ABOVE)
972 exstyle |= WS_EX_TOPMOST;
974 if (exstyle & WS_EX_TOPMOST)
979 /* Use SetWindowPos to show transparent windows so automatic redraws
980 * in other windows can be suppressed.
982 if (exstyle & WS_EX_TRANSPARENT)
984 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
987 flags |= SWP_NOZORDER;
988 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
989 flags |= SWP_NOACTIVATE;
991 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
996 old_active_window = GetActiveWindow ();
998 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1000 gdk_window_fullscreen (window);
1002 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1004 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1006 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1008 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1010 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1012 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1016 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1021 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1022 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1024 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1025 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1027 if (focus_on_map && private->accept_focus)
1029 SetForegroundWindow (GDK_WINDOW_HWND (window));
1030 if (top == HWND_TOPMOST)
1031 SetWindowPos (GDK_WINDOW_HWND (window), top,
1033 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1037 SetWindowPos (GDK_WINDOW_HWND (window), top,
1039 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1044 BringWindowToTop (GDK_WINDOW_HWND (window));
1047 else if (old_active_window != GDK_WINDOW_HWND (window))
1049 SetActiveWindow (old_active_window);
1054 gdk_win32_window_show (GdkWindow *window,
1055 gboolean already_mapped)
1057 show_window_internal (window, FALSE, FALSE);
1061 gdk_win32_window_hide (GdkWindow *window)
1063 GdkWindowObject *private;
1065 private = (GdkWindowObject*) window;
1066 if (private->destroyed)
1069 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1070 GDK_WINDOW_HWND (window),
1071 _gdk_win32_window_state_to_string (private->state)));
1073 if (GDK_WINDOW_IS_MAPPED (window))
1074 gdk_synthesize_window_state (window,
1076 GDK_WINDOW_STATE_WITHDRAWN);
1078 _gdk_window_clear_update_area (window);
1080 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1081 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1083 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1085 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1087 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1091 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1096 gdk_win32_window_withdraw (GdkWindow *window)
1098 GdkWindowObject *private;
1100 private = (GdkWindowObject*) window;
1101 if (private->destroyed)
1104 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1105 GDK_WINDOW_HWND (window),
1106 _gdk_win32_window_state_to_string (private->state)));
1108 gdk_window_hide (window); /* ??? */
1112 gdk_win32_window_move (GdkWindow *window,
1115 GdkWindowObject *private = (GdkWindowObject *)window;
1116 GdkWindowImplWin32 *impl;
1118 g_return_if_fail (GDK_IS_WINDOW (window));
1120 if (GDK_WINDOW_DESTROYED (window))
1123 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1124 GDK_WINDOW_HWND (window), x, y));
1126 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1128 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1131 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1132 * Foreign windows (another app's windows) might be children of our
1133 * windows! Especially in the case of gtkplug/socket.
1135 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1137 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1143 get_outer_rect (window, private->width, private->height, &outer_rect);
1145 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1147 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1148 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1149 GDK_WINDOW_HWND (window),
1150 x - _gdk_offset_x, y - _gdk_offset_y));
1152 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1153 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1154 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1159 gdk_win32_window_resize (GdkWindow *window,
1160 gint width, gint height)
1162 GdkWindowObject *private = (GdkWindowObject*) window;
1163 GdkWindowImplWin32 *impl;
1165 g_return_if_fail (GDK_IS_WINDOW (window));
1167 if (GDK_WINDOW_DESTROYED (window))
1175 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1176 GDK_WINDOW_HWND (window), width, height));
1178 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1180 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1183 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1185 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1191 get_outer_rect (window, width, height, &outer_rect);
1193 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1194 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1195 GDK_WINDOW_HWND (window),
1196 outer_rect.right - outer_rect.left,
1197 outer_rect.bottom - outer_rect.top));
1199 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1201 outer_rect.right - outer_rect.left,
1202 outer_rect.bottom - outer_rect.top,
1203 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1204 private->resize_count += 1;
1209 gdk_win32_window_move_resize_internal (GdkWindow *window,
1215 GdkWindowObject *private;
1216 GdkWindowImplWin32 *impl;
1218 g_return_if_fail (GDK_IS_WINDOW (window));
1220 if (GDK_WINDOW_DESTROYED (window))
1228 private = GDK_WINDOW_OBJECT (window);
1229 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1231 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1234 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1235 GDK_WINDOW_HWND (window),
1236 width, height, x, y));
1238 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1240 _gdk_window_move_resize_child (window, x, y, width, height);
1246 get_outer_rect (window, width, height, &outer_rect);
1248 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1250 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1251 "NOACTIVATE|NOZORDER)\n",
1252 GDK_WINDOW_HWND (window),
1253 x - _gdk_offset_x, y - _gdk_offset_y,
1254 outer_rect.right - outer_rect.left,
1255 outer_rect.bottom - outer_rect.top));
1257 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1258 x - _gdk_offset_x, y - _gdk_offset_y,
1259 outer_rect.right - outer_rect.left,
1260 outer_rect.bottom - outer_rect.top,
1261 SWP_NOACTIVATE | SWP_NOZORDER));
1266 gdk_win32_window_move_resize (GdkWindow *window,
1273 if (with_move && (width < 0 && height < 0))
1275 gdk_win32_window_move (window, x, y);
1281 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1285 gdk_win32_window_resize (window, width, height);
1291 gdk_win32_window_reparent (GdkWindow *window,
1292 GdkWindow *new_parent,
1296 GdkWindowObject *window_private;
1297 GdkWindowObject *parent_private;
1298 GdkWindowObject *old_parent_private;
1299 GdkWindowImplWin32 *impl;
1300 gboolean was_toplevel;
1304 new_parent = _gdk_root;
1306 window_private = (GdkWindowObject*) window;
1307 old_parent_private = (GdkWindowObject *) window_private->parent;
1308 parent_private = (GdkWindowObject*) new_parent;
1309 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1311 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1312 GDK_WINDOW_HWND (window),
1313 GDK_WINDOW_HWND (new_parent)));
1315 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1317 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1318 if (was_toplevel && new_parent != _gdk_root)
1320 /* Reparenting from top-level (child of desktop). Clear out
1323 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1325 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1327 else if (new_parent == _gdk_root)
1329 /* Reparenting to top-level. Add decorations. */
1330 style &= ~(WS_CHILD);
1331 style |= WS_OVERLAPPEDWINDOW;
1332 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1335 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1336 GDK_WINDOW_HWND (new_parent)));
1338 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1339 x, y, window_private->width, window_private->height, TRUE));
1341 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1344 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1345 new_parent = _gdk_root;
1347 window_private->parent = (GdkWindowObject *)new_parent;
1349 /* Switch the window type as appropriate */
1351 switch (GDK_WINDOW_TYPE (new_parent))
1353 case GDK_WINDOW_ROOT:
1354 if (impl->toplevel_window_type != -1)
1355 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1356 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1357 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1360 case GDK_WINDOW_TOPLEVEL:
1361 case GDK_WINDOW_CHILD:
1362 case GDK_WINDOW_TEMP:
1363 if (WINDOW_IS_TOPLEVEL (window))
1365 /* Save the original window type so we can restore it if the
1366 * window is reparented back to be a toplevel.
1368 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1369 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1373 if (old_parent_private)
1374 old_parent_private->children =
1375 g_list_remove (old_parent_private->children, window);
1377 parent_private->children = g_list_prepend (parent_private->children, window);
1383 gdk_win32_window_raise (GdkWindow *window)
1385 if (!GDK_WINDOW_DESTROYED (window))
1387 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1388 GDK_WINDOW_HWND (window)));
1390 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1391 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1393 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1394 else if (((GdkWindowObject *)window)->accept_focus)
1395 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1397 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1399 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1404 gdk_win32_window_lower (GdkWindow *window)
1406 if (!GDK_WINDOW_DESTROYED (window))
1408 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1409 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1410 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1411 GDK_WINDOW_HWND (window),
1412 GDK_WINDOW_HWND (window)));
1414 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1416 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1421 gdk_window_set_urgency_hint (GdkWindow *window,
1424 FLASHWINFO flashwinfo;
1425 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1426 PFN_FlashWindowEx flashWindowEx = NULL;
1428 g_return_if_fail (GDK_IS_WINDOW (window));
1429 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1431 if (GDK_WINDOW_DESTROYED (window))
1434 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1438 flashwinfo.cbSize = sizeof (flashwinfo);
1439 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1441 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1443 flashwinfo.dwFlags = FLASHW_STOP;
1444 flashwinfo.uCount = 0;
1445 flashwinfo.dwTimeout = 0;
1447 flashWindowEx (&flashwinfo);
1451 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1456 get_effective_window_decorations (GdkWindow *window,
1457 GdkWMDecoration *decoration)
1459 GdkWindowImplWin32 *impl;
1461 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1463 if (gdk_window_get_decorations (window, decoration))
1466 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL)
1471 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1472 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1473 impl->hints.min_width == impl->hints.max_width &&
1474 impl->hints.min_height == impl->hints.max_height)
1476 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1478 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1479 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1480 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1482 *decoration |= GDK_DECOR_MINIMIZE;
1484 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1486 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1491 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1493 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1494 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1495 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1496 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1498 *decoration |= GDK_DECOR_MINIMIZE;
1505 switch (impl->type_hint)
1507 case GDK_WINDOW_TYPE_HINT_DIALOG:
1508 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1511 case GDK_WINDOW_TYPE_HINT_MENU:
1512 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1515 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1516 case GDK_WINDOW_TYPE_HINT_UTILITY:
1517 gdk_window_set_skip_taskbar_hint (window, TRUE);
1518 gdk_window_set_skip_pager_hint (window, TRUE);
1519 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1522 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1523 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1524 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1527 case GDK_WINDOW_TYPE_HINT_DOCK:
1530 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1535 case GDK_WINDOW_TYPE_HINT_NORMAL:
1536 *decoration = GDK_DECOR_ALL;
1545 gdk_window_set_geometry_hints (GdkWindow *window,
1546 const GdkGeometry *geometry,
1547 GdkWindowHints geom_mask)
1549 GdkWindowImplWin32 *impl;
1551 g_return_if_fail (GDK_IS_WINDOW (window));
1553 if (GDK_WINDOW_DESTROYED (window))
1556 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1557 GDK_WINDOW_HWND (window)));
1559 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1561 impl->hint_flags = geom_mask;
1562 impl->hints = *geometry;
1564 if (geom_mask & GDK_HINT_POS)
1565 ; /* even the X11 mplementation doesn't care */
1567 if (geom_mask & GDK_HINT_MIN_SIZE)
1569 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1570 geometry->min_width, geometry->min_height));
1573 if (geom_mask & GDK_HINT_MAX_SIZE)
1575 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1576 geometry->max_width, geometry->max_height));
1579 if (geom_mask & GDK_HINT_BASE_SIZE)
1581 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1582 geometry->base_width, geometry->base_height));
1585 if (geom_mask & GDK_HINT_RESIZE_INC)
1587 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1588 geometry->width_inc, geometry->height_inc));
1591 if (geom_mask & GDK_HINT_ASPECT)
1593 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1594 geometry->min_aspect, geometry->max_aspect));
1597 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1599 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1602 update_style_bits (window);
1606 gdk_window_set_title (GdkWindow *window,
1611 g_return_if_fail (GDK_IS_WINDOW (window));
1612 g_return_if_fail (title != NULL);
1614 if (GDK_WINDOW_DESTROYED (window))
1617 /* Empty window titles not allowed, so set it to just a period. */
1621 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1622 GDK_WINDOW_HWND (window), title));
1624 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1626 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1627 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1630 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1634 gdk_window_set_role (GdkWindow *window,
1637 g_return_if_fail (GDK_IS_WINDOW (window));
1639 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1640 GDK_WINDOW_HWND (window),
1641 (role ? role : "NULL")));
1646 gdk_window_set_transient_for (GdkWindow *window,
1649 HWND window_id, parent_id;
1650 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1651 GdkWindowImplWin32 *parent_impl = NULL;
1654 g_return_if_fail (GDK_IS_WINDOW (window));
1656 window_id = GDK_WINDOW_HWND (window);
1657 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1659 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1661 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1663 if (GDK_WINDOW_DESTROYED (window))
1664 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1666 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1671 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1673 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1679 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1680 if (trans_impl->transient_children != NULL)
1682 item = g_slist_find (trans_impl->transient_children, window);
1684 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1685 trans_impl->num_transients--;
1687 if (!trans_impl->num_transients)
1689 trans_impl->transient_children = NULL;
1692 g_object_unref (G_OBJECT (window_impl->transient_owner));
1693 g_object_unref (G_OBJECT (window));
1695 window_impl->transient_owner = NULL;
1699 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1701 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1702 g_object_ref (G_OBJECT (window));
1703 parent_impl->num_transients++;
1704 window_impl->transient_owner = parent;
1705 g_object_ref (G_OBJECT (parent));
1708 /* This changes the *owner* of the window, despite the misleading
1709 * name. (Owner and parent are unrelated concepts.) At least that's
1710 * what people who seem to know what they talk about say on
1711 * USENET. Search on Google.
1714 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1715 GetLastError () != 0)
1716 WIN32_API_FAILED ("SetWindowLongPtr");
1720 _gdk_push_modal_window (GdkWindow *window)
1722 modal_window_stack = g_slist_prepend (modal_window_stack,
1727 _gdk_remove_modal_window (GdkWindow *window)
1731 g_return_if_fail (window != NULL);
1733 /* It's possible to be NULL here if someone sets the modal hint of the window
1734 * to FALSE before a modal window stack has ever been created. */
1735 if (modal_window_stack == NULL)
1738 /* Find the requested window in the stack and remove it. Yeah, I realize this
1739 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1740 tmp = g_slist_find (modal_window_stack, window);
1743 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1748 _gdk_modal_current (void)
1750 if (modal_window_stack != NULL)
1752 GSList *tmp = modal_window_stack;
1754 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1756 tmp = g_slist_next (tmp);
1759 return tmp != NULL ? tmp->data : NULL;
1768 gdk_win32_window_set_background (GdkWindow *window,
1769 cairo_pattern_t *pattern)
1774 gdk_win32_window_set_device_cursor (GdkWindow *window,
1778 GdkWindowImplWin32 *impl;
1779 GdkCursorPrivate *cursor_private;
1781 HCURSOR hprevcursor;
1783 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1784 cursor_private = (GdkCursorPrivate*) cursor;
1786 if (GDK_WINDOW_DESTROYED (window))
1792 hcursor = cursor_private->hcursor;
1794 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1795 GDK_WINDOW_HWND (window),
1798 /* First get the old cursor, if any (we wait to free the old one
1799 * since it may be the current cursor set in the Win32 API right
1802 hprevcursor = impl->hcursor;
1804 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
1806 if (hcursor == NULL)
1807 impl->hcursor = NULL;
1810 /* We must copy the cursor as it is OK to destroy the GdkCursor
1811 * while still in use for some window. See for instance
1812 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1813 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1816 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1817 WIN32_API_FAILED ("CopyCursor");
1818 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1819 hcursor, impl->hcursor));
1822 /* Destroy the previous cursor */
1823 if (hprevcursor != NULL)
1825 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1826 API_CALL (DestroyCursor, (hprevcursor));
1831 gdk_win32_window_get_geometry (GdkWindow *window,
1841 if (!GDK_WINDOW_DESTROYED (window))
1845 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1847 if (window != _gdk_root)
1850 GdkWindow *parent = gdk_window_get_parent (window);
1854 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1855 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1861 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1862 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1866 if (parent == _gdk_root)
1868 rect.left += _gdk_offset_x;
1869 rect.top += _gdk_offset_y;
1870 rect.right += _gdk_offset_x;
1871 rect.bottom += _gdk_offset_y;
1880 *width = rect.right - rect.left;
1882 *height = rect.bottom - rect.top;
1884 *depth = gdk_window_get_visual (window)->depth;
1886 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
1887 GDK_WINDOW_HWND (window),
1888 rect.right - rect.left, rect.bottom - rect.top,
1889 gdk_window_get_visual (window)->depth,
1890 rect.left, rect.top));
1895 gdk_win32_window_get_root_coords (GdkWindow *window,
1907 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1912 *root_x = tx + _gdk_offset_x;
1914 *root_y = ty + _gdk_offset_y;
1916 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
1917 GDK_WINDOW_HWND (window),
1919 tx + _gdk_offset_x, ty + _gdk_offset_y));
1924 gdk_win32_window_restack_under (GdkWindow *window,
1925 GList *native_siblings)
1931 gdk_win32_window_restack_toplevel (GdkWindow *window,
1939 gdk_window_get_root_origin (GdkWindow *window,
1945 g_return_if_fail (GDK_IS_WINDOW (window));
1947 gdk_window_get_frame_extents (window, &rect);
1955 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
1956 GDK_WINDOW_HWND (window), rect.x, rect.y));
1960 gdk_window_get_frame_extents (GdkWindow *window,
1963 GdkWindowObject *private;
1967 g_return_if_fail (GDK_IS_WINDOW (window));
1968 g_return_if_fail (rect != NULL);
1970 private = GDK_WINDOW_OBJECT (window);
1977 if (GDK_WINDOW_DESTROYED (window))
1980 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
1981 * necessary to walk its parent chain?
1983 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1984 private = (GdkWindowObject*) private->parent;
1986 hwnd = GDK_WINDOW_HWND (window);
1987 API_CALL (GetWindowRect, (hwnd, &r));
1989 rect->x = r.left + _gdk_offset_x;
1990 rect->y = r.top + _gdk_offset_y;
1991 rect->width = r.right - r.left;
1992 rect->height = r.bottom - r.top;
1994 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
1995 GDK_WINDOW_HWND (window),
1996 r.right - r.left, r.bottom - r.top,
2001 gdk_window_win32_get_device_state (GdkWindow *window,
2005 GdkModifierType *mask)
2009 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2011 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
2015 return (child != NULL);
2019 _gdk_windowing_get_device_state (GdkDisplay *display,
2024 GdkModifierType *mask)
2026 g_return_if_fail (display == _gdk_display);
2029 *screen = _gdk_screen;
2031 GDK_DEVICE_GET_CLASS (device)->query_state (device,
2032 gdk_screen_get_root_window (_gdk_screen),
2040 gdk_display_warp_pointer (GdkDisplay *display,
2045 GdkDeviceManagerWin32 *device_manager;
2047 g_return_if_fail (display == _gdk_display);
2048 g_return_if_fail (screen == _gdk_screen);
2050 device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
2051 GDK_DEVICE_GET_CLASS (device_manager->core_pointer)->warp (device_manager->core_pointer,
2056 gdk_display_warp_device (GdkDisplay *display,
2062 g_return_if_fail (display == _gdk_display);
2063 g_return_if_fail (screen == _gdk_screen);
2064 g_return_if_fail (GDK_IS_DEVICE (device));
2065 g_return_if_fail (display == gdk_device_get_display (device));
2067 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
2071 _gdk_windowing_window_at_device_position (GdkDisplay *display,
2075 GdkModifierType *mask,
2076 gboolean get_toplevel)
2078 return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
2082 gdk_win32_window_get_events (GdkWindow *window)
2084 if (GDK_WINDOW_DESTROYED (window))
2087 return GDK_WINDOW_OBJECT (window)->event_mask;
2091 gdk_win32_window_set_events (GdkWindow *window,
2092 GdkEventMask event_mask)
2094 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2095 * set it here, too. Not that I know or remember why it is
2096 * necessary, will have to test some day.
2098 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2102 do_shape_combine_region (GdkWindow *window,
2108 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2109 _gdk_win32_adjust_client_rect (window, &rect);
2111 OffsetRgn (hrgn, -rect.left, -rect.top);
2112 OffsetRgn (hrgn, x, y);
2114 /* If this is a top-level window, add the title bar to the region */
2115 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2117 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2118 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2122 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2126 gdk_window_set_override_redirect (GdkWindow *window,
2127 gboolean override_redirect)
2129 g_return_if_fail (GDK_IS_WINDOW (window));
2131 g_warning ("gdk_window_set_override_redirect not implemented");
2135 gdk_window_set_accept_focus (GdkWindow *window,
2136 gboolean accept_focus)
2138 GdkWindowObject *private;
2140 g_return_if_fail (GDK_IS_WINDOW (window));
2142 private = (GdkWindowObject *)window;
2144 accept_focus = accept_focus != FALSE;
2146 if (private->accept_focus != accept_focus)
2147 private->accept_focus = accept_focus;
2151 gdk_window_set_focus_on_map (GdkWindow *window,
2152 gboolean focus_on_map)
2154 GdkWindowObject *private;
2156 g_return_if_fail (GDK_IS_WINDOW (window));
2158 private = (GdkWindowObject *)window;
2160 focus_on_map = focus_on_map != FALSE;
2162 if (private->focus_on_map != focus_on_map)
2163 private->focus_on_map = focus_on_map;
2167 gdk_window_set_icon_list (GdkWindow *window,
2170 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2171 gint big_diff, small_diff;
2172 gint big_w, big_h, small_w, small_h;
2175 HICON small_hicon, big_hicon;
2176 GdkWindowImplWin32 *impl;
2177 gint i, big_i, small_i;
2179 g_return_if_fail (GDK_IS_WINDOW (window));
2181 if (GDK_WINDOW_DESTROYED (window))
2184 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2186 /* ideal sizes for small and large icons */
2187 big_w = GetSystemMetrics (SM_CXICON);
2188 big_h = GetSystemMetrics (SM_CYICON);
2189 small_w = GetSystemMetrics (SM_CXSMICON);
2190 small_h = GetSystemMetrics (SM_CYSMICON);
2192 /* find closest sized icons in the list */
2194 small_pixbuf = NULL;
2200 pixbuf = (GdkPixbuf*) pixbufs->data;
2201 w = gdk_pixbuf_get_width (pixbuf);
2202 h = gdk_pixbuf_get_height (pixbuf);
2204 dw = ABS (w - big_w);
2205 dh = ABS (h - big_h);
2206 diff = dw*dw + dh*dh;
2207 if (big_pixbuf == NULL || diff < big_diff)
2209 big_pixbuf = pixbuf;
2214 dw = ABS (w - small_w);
2215 dh = ABS (h - small_h);
2216 diff = dw*dw + dh*dh;
2217 if (small_pixbuf == NULL || diff < small_diff)
2219 small_pixbuf = pixbuf;
2224 pixbufs = g_list_next (pixbufs);
2228 /* Create the icons */
2229 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2230 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2233 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2235 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2236 (LPARAM)small_hicon);
2238 /* Store the icons, destroying any previous icons */
2239 if (impl->hicon_big)
2240 GDI_CALL (DestroyIcon, (impl->hicon_big));
2241 impl->hicon_big = big_hicon;
2242 if (impl->hicon_small)
2243 GDI_CALL (DestroyIcon, (impl->hicon_small));
2244 impl->hicon_small = small_hicon;
2248 gdk_window_set_icon_name (GdkWindow *window,
2251 /* In case I manage to confuse this again (or somebody else does):
2252 * Please note that "icon name" here really *does* mean the name or
2253 * title of an window minimized as an icon on the desktop, or in the
2254 * taskbar. It has nothing to do with the freedesktop.org icon
2258 g_return_if_fail (GDK_IS_WINDOW (window));
2260 if (GDK_WINDOW_DESTROYED (window))
2264 /* This is not the correct thing to do. We should keep both the
2265 * "normal" window title, and the icon name. When the window is
2266 * minimized, call SetWindowText() with the icon name, and when the
2267 * window is restored, with the normal window title. Also, the name
2268 * is in UTF-8, so we should do the normal conversion to either wide
2269 * chars or system codepage, and use either the W or A version of
2270 * SetWindowText(), depending on Windows version.
2272 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2277 gdk_window_get_group (GdkWindow *window)
2279 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2280 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2282 if (GDK_WINDOW_DESTROYED (window))
2285 g_warning ("gdk_window_get_group not yet implemented");
2291 gdk_window_set_group (GdkWindow *window,
2294 g_return_if_fail (GDK_IS_WINDOW (window));
2295 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2296 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2298 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2301 g_warning ("gdk_window_set_group not implemented");
2305 update_single_bit (LONG *style,
2310 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2311 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2312 * bit indicate whether style_bit is on
2314 if ((!all && gdk_bit) || (all && !gdk_bit))
2315 *style |= style_bit;
2317 *style &= ~style_bit;
2321 update_style_bits (GdkWindow *window)
2323 GdkWindowObject *private = (GdkWindowObject *)window;
2324 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2325 GdkWMDecoration decorations;
2326 LONG old_style, new_style, old_exstyle, new_exstyle;
2328 RECT rect, before, after;
2330 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2331 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2333 GetClientRect (GDK_WINDOW_HWND (window), &before);
2335 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2337 new_style = old_style;
2338 new_exstyle = old_exstyle;
2340 if (private->window_type == GDK_WINDOW_TEMP ||
2341 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2342 new_exstyle |= WS_EX_TOOLWINDOW;
2344 new_exstyle &= ~WS_EX_TOOLWINDOW;
2346 if (get_effective_window_decorations (window, &decorations))
2348 all = (decorations & GDK_DECOR_ALL);
2349 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2350 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2351 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2352 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2353 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2354 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2357 if (old_style == new_style && old_exstyle == new_exstyle )
2359 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2360 GDK_WINDOW_HWND (window)));
2364 if (old_style != new_style)
2366 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2367 GDK_WINDOW_HWND (window),
2368 _gdk_win32_window_style_to_string (old_style),
2369 _gdk_win32_window_style_to_string (new_style)));
2371 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2374 if (old_exstyle != new_exstyle)
2376 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2377 GDK_WINDOW_HWND (window),
2378 _gdk_win32_window_exstyle_to_string (old_exstyle),
2379 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2381 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2384 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2386 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2387 rect.left += after.left - before.left;
2388 rect.top += after.top - before.top;
2389 rect.right += after.right - before.right;
2390 rect.bottom += after.bottom - before.bottom;
2392 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2393 rect.left, rect.top,
2394 rect.right - rect.left, rect.bottom - rect.top,
2395 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2396 SWP_NOREPOSITION | SWP_NOZORDER);
2401 update_single_system_menu_entry (HMENU hmenu,
2406 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2407 * gdk_bit indicates whether menu entry is disabled; if all is
2408 * FALSE, gdk bit indicate whether menu entry is enabled
2410 if ((!all && gdk_bit) || (all && !gdk_bit))
2411 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2413 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2417 update_system_menu (GdkWindow *window)
2419 GdkWMFunction functions;
2422 if (_gdk_window_get_functions (window, &functions))
2424 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2426 all = (functions & GDK_FUNC_ALL);
2427 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2428 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2429 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2430 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2431 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2436 get_decorations_quark ()
2438 static GQuark quark = 0;
2441 quark = g_quark_from_static_string ("gdk-window-decorations");
2447 gdk_window_set_decorations (GdkWindow *window,
2448 GdkWMDecoration decorations)
2450 GdkWMDecoration* decorations_copy;
2452 g_return_if_fail (GDK_IS_WINDOW (window));
2454 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2455 GDK_WINDOW_HWND (window),
2456 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2457 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2458 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2459 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2460 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2461 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2462 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2464 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2465 *decorations_copy = decorations;
2466 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2468 update_style_bits (window);
2472 gdk_window_get_decorations (GdkWindow *window,
2473 GdkWMDecoration *decorations)
2475 GdkWMDecoration* decorations_set;
2477 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2479 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2480 if (decorations_set)
2481 *decorations = *decorations_set;
2483 return (decorations_set != NULL);
2487 get_functions_quark ()
2489 static GQuark quark = 0;
2492 quark = g_quark_from_static_string ("gdk-window-functions");
2498 gdk_window_set_functions (GdkWindow *window,
2499 GdkWMFunction functions)
2501 GdkWMFunction* functions_copy;
2503 g_return_if_fail (GDK_IS_WINDOW (window));
2505 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2506 GDK_WINDOW_HWND (window),
2507 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2508 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2509 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2510 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2511 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2512 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2514 functions_copy = g_malloc (sizeof (GdkWMFunction));
2515 *functions_copy = functions;
2516 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2518 update_system_menu (window);
2522 _gdk_window_get_functions (GdkWindow *window,
2523 GdkWMFunction *functions)
2525 GdkWMDecoration* functions_set;
2527 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2529 *functions = *functions_set;
2531 return (functions_set != NULL);
2535 gdk_win32_window_set_static_gravities (GdkWindow *window,
2536 gboolean use_static)
2538 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2544 gdk_window_begin_resize_drag (GdkWindow *window,
2553 g_return_if_fail (GDK_IS_WINDOW (window));
2555 if (GDK_WINDOW_DESTROYED (window))
2558 /* Tell Windows to start interactively resizing the window by pretending that
2559 * the left pointer button was clicked in the suitable edge or corner. This
2560 * will only work if the button is down when this function is called, and
2561 * will only work with button 1 (left), since Windows only allows window
2562 * dragging using the left mouse button.
2567 /* Must break the automatic grab that occured when the button was
2568 * pressed, otherwise it won't work.
2570 gdk_display_pointer_ungrab (_gdk_display, 0);
2574 case GDK_WINDOW_EDGE_NORTH_WEST:
2575 winedge = HTTOPLEFT;
2578 case GDK_WINDOW_EDGE_NORTH:
2582 case GDK_WINDOW_EDGE_NORTH_EAST:
2583 winedge = HTTOPRIGHT;
2586 case GDK_WINDOW_EDGE_WEST:
2590 case GDK_WINDOW_EDGE_EAST:
2594 case GDK_WINDOW_EDGE_SOUTH_WEST:
2595 winedge = HTBOTTOMLEFT;
2598 case GDK_WINDOW_EDGE_SOUTH:
2602 case GDK_WINDOW_EDGE_SOUTH_EAST:
2604 winedge = HTBOTTOMRIGHT;
2608 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2609 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2613 gdk_window_begin_move_drag (GdkWindow *window,
2619 g_return_if_fail (GDK_IS_WINDOW (window));
2621 if (GDK_WINDOW_DESTROYED (window))
2624 /* Tell Windows to start interactively moving the window by pretending that
2625 * the left pointer button was clicked in the titlebar. This will only work
2626 * if the button is down when this function is called, and will only work
2627 * with button 1 (left), since Windows only allows window dragging using the
2628 * left mouse button.
2633 /* Must break the automatic grab that occured when the button was pressed,
2634 * otherwise it won't work.
2636 gdk_display_pointer_ungrab (_gdk_display, 0);
2638 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2639 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2644 * Setting window states
2647 gdk_window_iconify (GdkWindow *window)
2649 HWND old_active_window;
2651 g_return_if_fail (GDK_IS_WINDOW (window));
2653 if (GDK_WINDOW_DESTROYED (window))
2656 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2657 GDK_WINDOW_HWND (window),
2658 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2660 if (GDK_WINDOW_IS_MAPPED (window))
2662 old_active_window = GetActiveWindow ();
2663 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2664 if (old_active_window != GDK_WINDOW_HWND (window))
2665 SetActiveWindow (old_active_window);
2669 gdk_synthesize_window_state (window,
2671 GDK_WINDOW_STATE_ICONIFIED);
2676 gdk_window_deiconify (GdkWindow *window)
2678 g_return_if_fail (GDK_IS_WINDOW (window));
2680 if (GDK_WINDOW_DESTROYED (window))
2683 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2684 GDK_WINDOW_HWND (window),
2685 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2687 if (GDK_WINDOW_IS_MAPPED (window))
2689 show_window_internal (window, FALSE, TRUE);
2693 gdk_synthesize_window_state (window,
2694 GDK_WINDOW_STATE_ICONIFIED,
2700 gdk_window_stick (GdkWindow *window)
2702 g_return_if_fail (GDK_IS_WINDOW (window));
2704 if (GDK_WINDOW_DESTROYED (window))
2707 /* FIXME: Do something? */
2711 gdk_window_unstick (GdkWindow *window)
2713 g_return_if_fail (GDK_IS_WINDOW (window));
2715 if (GDK_WINDOW_DESTROYED (window))
2718 /* FIXME: Do something? */
2722 gdk_window_maximize (GdkWindow *window)
2724 g_return_if_fail (GDK_IS_WINDOW (window));
2726 if (GDK_WINDOW_DESTROYED (window))
2729 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2730 GDK_WINDOW_HWND (window),
2731 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2733 if (GDK_WINDOW_IS_MAPPED (window))
2734 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2736 gdk_synthesize_window_state (window,
2738 GDK_WINDOW_STATE_MAXIMIZED);
2742 gdk_window_unmaximize (GdkWindow *window)
2744 g_return_if_fail (GDK_IS_WINDOW (window));
2746 if (GDK_WINDOW_DESTROYED (window))
2749 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2750 GDK_WINDOW_HWND (window),
2751 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2753 if (GDK_WINDOW_IS_MAPPED (window))
2754 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2756 gdk_synthesize_window_state (window,
2757 GDK_WINDOW_STATE_MAXIMIZED,
2761 typedef struct _FullscreenInfo FullscreenInfo;
2763 struct _FullscreenInfo
2771 gdk_window_fullscreen (GdkWindow *window)
2773 gint x, y, width, height;
2775 GdkWindowObject *private = (GdkWindowObject *) window;
2779 g_return_if_fail (GDK_IS_WINDOW (window));
2781 fi = g_new (FullscreenInfo, 1);
2783 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2787 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2789 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
2790 mi.cbSize = sizeof (mi);
2791 if (monitor && GetMonitorInfo (monitor, &mi))
2793 x = mi.rcMonitor.left;
2794 y = mi.rcMonitor.top;
2795 width = mi.rcMonitor.right - x;
2796 height = mi.rcMonitor.bottom - y;
2801 width = GetSystemMetrics (SM_CXSCREEN);
2802 height = GetSystemMetrics (SM_CYSCREEN);
2805 /* remember for restoring */
2806 fi->hint_flags = impl->hint_flags;
2807 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
2808 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
2809 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2811 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2812 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
2814 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
2815 x, y, width, height,
2816 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2818 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2823 gdk_window_unfullscreen (GdkWindow *window)
2826 GdkWindowObject *private = (GdkWindowObject *) window;
2828 g_return_if_fail (GDK_IS_WINDOW (window));
2830 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
2833 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2835 impl->hint_flags = fi->hint_flags;
2836 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
2837 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
2838 fi->r.left, fi->r.top,
2839 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
2840 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
2842 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
2845 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2850 gdk_window_set_keep_above (GdkWindow *window,
2853 g_return_if_fail (GDK_IS_WINDOW (window));
2855 if (GDK_WINDOW_DESTROYED (window))
2858 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
2859 GDK_WINDOW_HWND (window),
2860 setting ? "YES" : "NO"));
2862 if (GDK_WINDOW_IS_MAPPED (window))
2864 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2865 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
2867 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2870 gdk_synthesize_window_state (window,
2871 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
2872 setting ? GDK_WINDOW_STATE_ABOVE : 0);
2876 gdk_window_set_keep_below (GdkWindow *window,
2879 g_return_if_fail (GDK_IS_WINDOW (window));
2881 if (GDK_WINDOW_DESTROYED (window))
2884 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
2885 GDK_WINDOW_HWND (window),
2886 setting ? "YES" : "NO"));
2888 if (GDK_WINDOW_IS_MAPPED (window))
2890 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2891 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
2893 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
2896 gdk_synthesize_window_state (window,
2897 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
2898 setting ? GDK_WINDOW_STATE_BELOW : 0);
2902 gdk_window_focus (GdkWindow *window,
2905 g_return_if_fail (GDK_IS_WINDOW (window));
2907 if (GDK_WINDOW_DESTROYED (window))
2910 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
2911 GDK_WINDOW_HWND (window),
2912 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2914 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
2915 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
2917 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2918 SetFocus (GDK_WINDOW_HWND (window));
2922 gdk_window_set_modal_hint (GdkWindow *window,
2925 GdkWindowObject *private;
2927 g_return_if_fail (GDK_IS_WINDOW (window));
2929 if (GDK_WINDOW_DESTROYED (window))
2932 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
2933 GDK_WINDOW_HWND (window),
2934 modal ? "YES" : "NO"));
2936 private = (GdkWindowObject*) window;
2938 if (modal == private->modal_hint)
2941 private->modal_hint = modal;
2944 /* Not sure about this one.. -- Cody */
2945 if (GDK_WINDOW_IS_MAPPED (window))
2946 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2947 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
2949 SWP_NOMOVE | SWP_NOSIZE));
2954 _gdk_push_modal_window (window);
2955 gdk_window_raise (window);
2959 _gdk_remove_modal_window (window);
2966 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2967 gboolean skips_taskbar)
2969 static GdkWindow *owner = NULL;
2972 g_return_if_fail (GDK_IS_WINDOW (window));
2974 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
2975 GDK_WINDOW_HWND (window),
2976 skips_taskbar ? "YES" : "NO"));
2978 // ### TODO: Need to figure out what to do here.
2986 wa.window_type = GDK_WINDOW_TEMP;
2987 wa.wclass = GDK_INPUT_OUTPUT;
2988 wa.width = wa.height = 1;
2990 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
2994 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
2996 #if 0 /* Should we also turn off the minimize and maximize buttons? */
2997 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2998 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3000 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3002 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3003 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3008 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3013 gdk_window_set_skip_pager_hint (GdkWindow *window,
3014 gboolean skips_pager)
3016 g_return_if_fail (GDK_IS_WINDOW (window));
3018 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3019 GDK_WINDOW_HWND (window),
3020 skips_pager ? "YES" : "NO"));
3024 gdk_window_set_type_hint (GdkWindow *window,
3025 GdkWindowTypeHint hint)
3027 g_return_if_fail (GDK_IS_WINDOW (window));
3029 if (GDK_WINDOW_DESTROYED (window))
3034 static GEnumClass *class = NULL;
3036 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3037 g_print ("gdk_window_set_type_hint: %p: %s\n",
3038 GDK_WINDOW_HWND (window),
3039 g_enum_get_value (class, hint)->value_name);
3042 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3044 update_style_bits (window);
3048 gdk_window_get_type_hint (GdkWindow *window)
3050 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3052 if (GDK_WINDOW_DESTROYED (window))
3053 return GDK_WINDOW_TYPE_HINT_NORMAL;
3055 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3059 cairo_region_to_hrgn (const cairo_region_t *region,
3066 cairo_rectangle_int_t r;
3067 const int nrects = cairo_region_num_rectangles (region);
3069 sizeof (RGNDATAHEADER) + (sizeof (RECT) * nrects);
3072 rgndata = g_malloc (nbytes);
3073 rgndata->rdh.dwSize = sizeof (RGNDATAHEADER);
3074 rgndata->rdh.iType = RDH_RECTANGLES;
3075 rgndata->rdh.nCount = rgndata->rdh.nRgnSize = 0;
3076 SetRect (&rgndata->rdh.rcBound,
3077 G_MAXLONG, G_MAXLONG, G_MINLONG, G_MINLONG);
3079 for (i = 0; i < nrects; i++)
3081 rect = ((RECT *) rgndata->Buffer) + rgndata->rdh.nCount++;
3083 cairo_region_get_rectangle (region, i, &r);
3084 rect->left = r.x + x_origin;
3085 rect->right = rect->left + r.width;
3086 rect->top = r.y + y_origin;
3087 rect->bottom = rect->top + r.height;
3089 if (rect->left < rgndata->rdh.rcBound.left)
3090 rgndata->rdh.rcBound.left = rect->left;
3091 if (rect->right > rgndata->rdh.rcBound.right)
3092 rgndata->rdh.rcBound.right = rect->right;
3093 if (rect->top < rgndata->rdh.rcBound.top)
3094 rgndata->rdh.rcBound.top = rect->top;
3095 if (rect->bottom > rgndata->rdh.rcBound.bottom)
3096 rgndata->rdh.rcBound.bottom = rect->bottom;
3098 if ((hrgn = ExtCreateRegion (NULL, nbytes, rgndata)) == NULL)
3099 WIN32_API_FAILED ("ExtCreateRegion");
3107 gdk_win32_window_shape_combine_region (GdkWindow *window,
3108 const cairo_region_t *shape_region,
3112 if (GDK_WINDOW_DESTROYED (window))
3117 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3118 GDK_WINDOW_HWND (window)));
3119 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3125 hrgn = cairo_region_to_hrgn (shape_region, 0, 0);
3127 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3128 GDK_WINDOW_HWND (window),
3131 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3136 gdk_window_lookup_for_display (GdkDisplay *display,
3137 GdkNativeWindow anid)
3139 g_return_val_if_fail (display == _gdk_display, NULL);
3141 return gdk_window_lookup (anid);
3145 gdk_window_enable_synchronized_configure (GdkWindow *window)
3147 g_return_if_fail (GDK_IS_WINDOW (window));
3151 gdk_window_configure_finished (GdkWindow *window)
3153 g_return_if_fail (GDK_IS_WINDOW (window));
3157 _gdk_windowing_window_beep (GdkWindow *window)
3159 gdk_display_beep (_gdk_display);
3163 gdk_window_set_opacity (GdkWindow *window,
3167 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3168 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3170 g_return_if_fail (GDK_IS_WINDOW (window));
3171 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3173 if (GDK_WINDOW_DESTROYED (window))
3178 else if (opacity > 1)
3181 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3183 if (!(exstyle & WS_EX_LAYERED))
3184 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3186 exstyle | WS_EX_LAYERED));
3188 setLayeredWindowAttributes =
3189 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3191 if (setLayeredWindowAttributes)
3193 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3201 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3206 _gdk_windowing_window_get_shape (GdkWindow *window)
3208 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3209 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3211 if (type == SIMPLEREGION || type == COMPLEXREGION)
3213 cairo_region_t *region = _gdk_win32_hrgn_to_region (hrgn);
3215 DeleteObject (hrgn);
3223 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3225 /* CHECK: are these really supposed to be the same? */
3226 return _gdk_windowing_window_get_shape (window);
3230 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3231 cairo_region_t *area)
3233 HRGN hrgn = cairo_region_to_hrgn (area, 0, 0);
3235 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3236 GDK_WINDOW_HWND (window),
3237 _gdk_win32_cairo_region_to_string (area)));
3239 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3241 DeleteObject (hrgn);
3246 /* FIXME: Tis function has never been compiled.
3247 * Please make it work. */
3249 _gdk_win32_window_translate (GdkWindow *window,
3250 cairo_region_t *area,
3254 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3257 GdkRectangle extents;
3259 cairo_region_get_extents (area, &extents);
3260 hdc = _gdk_win32_drawable_acquire_dc (GDK_DRAWABLE (window));
3261 GDI_CALL (BitBlt, (hdc, extents.x, extents.y, extents.width, extents.height,
3262 hdc, extents.x + dx, extents.y + dy, SRCCOPY));
3264 /* XXX: We probably need to get invalidations for the whole extents and not
3265 * just the area as we BitBlt */
3266 ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
3268 WIN32_API_FAILED ("GetUpdateRgn");
3269 else if (ret != NULLREGION)
3271 /* Get current updateregion, move any part of it that intersects area by dx,dy */
3272 HRGN update = cairo_region_to_hrgn (area, 0, 0);
3273 ret = CombineRgn (update, hrgn, update, RGN_AND);
3275 WIN32_API_FAILED ("CombineRgn");
3276 else if (ret != NULLREGION)
3278 OffsetRgn (update, dx, dy);
3279 API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE));
3281 DeleteObject (update);
3283 DeleteObject (hrgn);
3287 gdk_win32_input_shape_combine_region (GdkWindow *window,
3288 const cairo_region_t *shape_region,
3292 if (GDK_WINDOW_DESTROYED (window))
3294 /* CHECK: are these really supposed to be the same? */
3295 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3299 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3300 cairo_region_t *region)
3302 _gdk_window_process_updates_recurse (window, region);
3306 _gdk_windowing_before_process_all_updates (void)
3311 _gdk_windowing_after_process_all_updates (void)
3316 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3318 iface->show = gdk_win32_window_show;
3319 iface->hide = gdk_win32_window_hide;
3320 iface->withdraw = gdk_win32_window_withdraw;
3321 iface->set_events = gdk_win32_window_set_events;
3322 iface->get_events = gdk_win32_window_get_events;
3323 iface->raise = gdk_win32_window_raise;
3324 iface->lower = gdk_win32_window_lower;
3325 iface->restack_under = gdk_win32_window_restack_under;
3326 iface->restack_toplevel = gdk_win32_window_restack_toplevel;
3327 iface->move_resize = gdk_win32_window_move_resize;
3328 iface->set_background = gdk_win32_window_set_background;
3329 iface->reparent = gdk_win32_window_reparent;
3330 iface->set_device_cursor = gdk_win32_window_set_device_cursor;
3331 iface->get_geometry = gdk_win32_window_get_geometry;
3332 iface->get_device_state = gdk_window_win32_get_device_state;
3333 iface->get_root_coords = gdk_win32_window_get_root_coords;
3334 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3335 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3336 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3337 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3338 iface->translate = _gdk_win32_window_translate;
3339 iface->destroy = _gdk_win32_window_destroy;
3343 gdk_win32_window_is_win32 (GdkWindow *window)
3345 return GDK_WINDOW_IS_WIN32 (window);