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-2004 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 "gdkinput-win32.h"
37 #include "gdkenumtypes.h"
39 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
40 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
42 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
43 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
44 static void gdk_window_impl_win32_finalize (GObject *object);
46 static gpointer parent_class = NULL;
47 static GSList *modal_window_stack = NULL;
49 static void update_style_bits (GdkWindow *window);
50 static gboolean _gdk_window_get_functions (GdkWindow *window,
51 GdkWMFunction *functions);
53 #define WINDOW_IS_TOPLEVEL(window) \
54 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
55 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
56 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
58 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
61 GDK_WINDOW_SCREEN (GObject *win)
67 _gdk_window_impl_win32_get_type (void)
69 static GType object_type = 0;
73 static const GTypeInfo object_info =
75 sizeof (GdkWindowImplWin32Class),
77 (GBaseFinalizeFunc) NULL,
78 (GClassInitFunc) gdk_window_impl_win32_class_init,
79 NULL, /* class_finalize */
80 NULL, /* class_data */
81 sizeof (GdkWindowImplWin32),
83 (GInstanceInitFunc) gdk_window_impl_win32_init,
86 const GInterfaceInfo window_impl_info =
88 (GInterfaceInitFunc) gdk_window_impl_iface_init,
93 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
96 g_type_add_interface_static (object_type,
105 _gdk_window_impl_get_type (void)
107 return _gdk_window_impl_win32_get_type ();
111 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
113 impl->toplevel_window_type = -1;
114 impl->hcursor = NULL;
115 impl->hicon_big = NULL;
116 impl->hicon_small = NULL;
117 impl->hint_flags = 0;
118 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
119 impl->extension_events_selected = FALSE;
120 impl->transient_owner = NULL;
121 impl->transient_children = NULL;
122 impl->num_transients = 0;
123 impl->changing_state = FALSE;
127 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
129 GObjectClass *object_class = G_OBJECT_CLASS (klass);
130 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
132 parent_class = g_type_class_peek_parent (klass);
134 object_class->finalize = gdk_window_impl_win32_finalize;
136 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
137 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
141 gdk_window_impl_win32_finalize (GObject *object)
143 GdkWindowObject *wrapper;
144 GdkDrawableImplWin32 *draw_impl;
145 GdkWindowImplWin32 *window_impl;
147 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
149 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
150 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
152 wrapper = (GdkWindowObject*) draw_impl->wrapper;
154 if (!GDK_WINDOW_DESTROYED (wrapper))
156 gdk_win32_handle_table_remove (draw_impl->handle);
159 if (window_impl->hcursor != NULL)
161 if (GetCursor () == window_impl->hcursor)
164 GDI_CALL (DestroyCursor, (window_impl->hcursor));
165 window_impl->hcursor = NULL;
168 if (window_impl->hicon_big != NULL)
170 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
171 window_impl->hicon_big = NULL;
174 if (window_impl->hicon_small != NULL)
176 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
177 window_impl->hicon_small = NULL;
180 G_OBJECT_CLASS (parent_class)->finalize (object);
184 _gdk_win32_adjust_client_rect (GdkWindow *window,
189 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
190 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
191 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
195 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
197 GdkDrawableImplWin32 *drawable_impl;
199 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
201 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
203 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
204 drawable_impl->colormap == NULL)
206 drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
207 g_object_ref (drawable_impl->colormap);
210 return drawable_impl->colormap;
214 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
217 GdkWindowImplWin32 *impl;
218 GdkDrawableImplWin32 *draw_impl;
220 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
222 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
223 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
226 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
231 g_print ("gdk_window_impl_win32_set_colormap: XXX\n");
236 _gdk_root_window_size_init (void)
238 GdkWindowObject *window_object;
239 //GdkWindowImplWin32 *impl;
243 window_object = GDK_WINDOW_OBJECT (_gdk_root);
244 //impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_root)->impl);
245 rect = _gdk_monitors[0].rect;
246 for (i = 1; i < _gdk_num_monitors; i++)
247 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
249 window_object->width = rect.width;
250 window_object->height = rect.height;
251 //impl->width = rect.width;
252 //impl->height = rect.height;
256 _gdk_windowing_window_init (GdkScreen *screen)
258 GdkWindowObject *private;
259 GdkDrawableImplWin32 *draw_impl;
261 g_assert (_gdk_root == NULL);
263 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
264 private = (GdkWindowObject *)_gdk_root;
265 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
266 private->impl_window = private;
268 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
270 draw_impl->handle = GetDesktopWindow ();
271 draw_impl->wrapper = GDK_DRAWABLE (private);
272 draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
273 g_object_ref (draw_impl->colormap);
275 private->window_type = GDK_WINDOW_ROOT;
276 private->depth = gdk_visual_get_system ()->depth;
278 _gdk_root_window_size_init ();
284 private->width = GetSystemMetrics (SM_CXSCREEN);
285 private->height = GetSystemMetrics (SM_CYSCREEN);
287 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
289 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
293 get_default_title (void)
296 title = g_get_application_name ();
298 title = g_get_prgname ();
304 * is a wrapper function for RegisterWindowClassEx.
305 * It creates at least one unique class for every
306 * GdkWindowType. If support for single window-specific icons
307 * is ever needed (e.g Dialog specific), every such window should
311 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
313 static ATOM klassTOPLEVEL = 0;
314 static ATOM klassDIALOG = 0;
315 static ATOM klassCHILD = 0;
316 static ATOM klassTEMP = 0;
317 static ATOM klassTEMPSHADOW = 0;
318 static HICON hAppIcon = NULL;
319 static HICON hAppIconSm = NULL;
320 static WNDCLASSEXW wcl;
323 wcl.cbSize = sizeof (WNDCLASSEX);
324 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
325 * on WM_SIZE and WM_MOVE. Flicker, Performance!
327 wcl.lpfnWndProc = _gdk_win32_window_procedure;
330 wcl.hInstance = _gdk_app_hmodule;
334 /* initialize once! */
335 if (0 == hAppIcon && 0 == hAppIconSm)
337 gchar sLoc [MAX_PATH+1];
339 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
341 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
343 if (0 == hAppIcon && 0 == hAppIconSm)
345 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
347 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
352 if (0 == hAppIcon && 0 == hAppIconSm)
354 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
355 GetSystemMetrics (SM_CXICON),
356 GetSystemMetrics (SM_CYICON), 0);
357 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
358 GetSystemMetrics (SM_CXSMICON),
359 GetSystemMetrics (SM_CYSMICON), 0);
364 hAppIcon = hAppIconSm;
365 else if (0 == hAppIconSm)
366 hAppIconSm = hAppIcon;
368 wcl.lpszMenuName = NULL;
370 /* initialize once per class */
372 * HB: Setting the background brush leads to flicker, because we
373 * don't get asked how to clear the background. This is not what
374 * we want, at least not for input_only windows ...
376 #define ONCE_PER_CLASS() \
377 wcl.hIcon = CopyIcon (hAppIcon); \
378 wcl.hIconSm = CopyIcon (hAppIconSm); \
379 wcl.hbrBackground = NULL; \
380 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
384 case GDK_WINDOW_TOPLEVEL:
385 if (0 == klassTOPLEVEL)
387 wcl.lpszClassName = L"gdkWindowToplevel";
390 klassTOPLEVEL = RegisterClassExW (&wcl);
392 klass = klassTOPLEVEL;
395 case GDK_WINDOW_CHILD:
398 wcl.lpszClassName = L"gdkWindowChild";
400 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
402 klassCHILD = RegisterClassExW (&wcl);
407 case GDK_WINDOW_DIALOG:
408 if (0 == klassDIALOG)
410 wcl.lpszClassName = L"gdkWindowDialog";
411 wcl.style |= CS_SAVEBITS;
413 klassDIALOG = RegisterClassExW (&wcl);
418 case GDK_WINDOW_TEMP:
419 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
420 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
421 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
422 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
424 if (klassTEMPSHADOW == 0)
426 wcl.lpszClassName = L"gdkWindowTempShadow";
427 wcl.style |= CS_SAVEBITS;
428 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
429 LOWORD (g_win32_get_windows_version()) == 0x0105)
431 /* Windows XP (5.1) or above */
432 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
435 klassTEMPSHADOW = RegisterClassExW (&wcl);
438 klass = klassTEMPSHADOW;
444 wcl.lpszClassName = L"gdkWindowTemp";
445 wcl.style |= CS_SAVEBITS;
447 klassTEMP = RegisterClassExW (&wcl);
455 g_assert_not_reached ();
461 WIN32_API_FAILED ("RegisterClassExW");
462 g_error ("That is a fatal error");
468 _gdk_window_impl_new (GdkWindow *window,
469 GdkWindow *real_parent,
472 GdkEventMask event_mask,
473 GdkWindowAttr *attributes,
474 gint attributes_mask)
479 DWORD dwStyle = 0, dwExStyle;
481 GdkWindow *orig_parent;
482 GdkWindowObject *private;
483 GdkWindowImplWin32 *impl;
484 GdkDrawableImplWin32 *draw_impl;
487 gint window_width, window_height;
488 gint offset_x = 0, offset_y = 0;
490 private = (GdkWindowObject *)window;
492 orig_parent = real_parent;
495 g_print ("gdk_window_new_internal: %s\n",
496 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
497 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
498 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
499 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
502 hparent = GDK_WINDOW_HWND (real_parent);
504 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
505 private->impl = (GdkDrawable *)impl;
506 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
507 draw_impl->wrapper = GDK_DRAWABLE (window);
509 // XXX: xattributes_mask = 0
512 if (attributes_mask & GDK_WA_VISUAL)
513 visual = attributes->visual;
515 visual = gdk_visual_get_system ();
519 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
520 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
522 impl->extension_events_selected = FALSE;
525 if (attributes->wclass == GDK_INPUT_OUTPUT)
529 private->input_only = FALSE;
530 private->depth = visual->depth;
532 if (attributes_mask & GDK_WA_COLORMAP)
534 draw_impl->colormap = attributes->colormap;
535 g_object_ref (attributes->colormap);
539 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
540 g_object_ref (draw_impl->colormap);
545 /* I very much doubt using WS_EX_TRANSPARENT actually
546 * corresponds to how X11 InputOnly windows work, but it appears
547 * to work well enough for the actual use cases in gtk.
549 dwExStyle = WS_EX_TRANSPARENT;
551 private->input_only = TRUE;
552 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
553 g_object_ref (draw_impl->colormap);
554 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap"));
557 switch (private->window_type)
559 case GDK_WINDOW_TOPLEVEL:
560 case GDK_WINDOW_DIALOG:
561 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
563 /* The common code warns for this case. */
564 hparent = GetDesktopWindow ();
566 /* Children of foreign windows aren't toplevel windows */
567 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
569 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
573 if (private->window_type == GDK_WINDOW_TOPLEVEL)
574 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
576 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
578 offset_x = _gdk_offset_x;
579 offset_y = _gdk_offset_y;
584 case GDK_WINDOW_CHILD:
585 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
589 case GDK_WINDOW_TEMP:
590 /* A temp window is not necessarily a top level window */
591 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
592 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
593 dwExStyle |= WS_EX_TOOLWINDOW;
594 offset_x = _gdk_offset_x;
595 offset_y = _gdk_offset_y;
599 g_assert_not_reached ();
602 //_gdk_window_init_position (GDK_WINDOW (private));
604 if (private->window_type != GDK_WINDOW_CHILD)
606 rect.left = rect.top = 0;
607 rect.right = private->width;
608 rect.bottom = private->height;
610 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
612 window_width = rect.right - rect.left;
613 window_height = rect.bottom - rect.top;
617 window_width = private->width;
618 window_height = private->height;
621 if (attributes_mask & GDK_WA_TITLE)
622 title = attributes->title;
624 title = get_default_title ();
625 if (!title || !*title)
628 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
630 if (attributes_mask & GDK_WA_TYPE_HINT)
631 impl->type_hint = attributes->type_hint;
633 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
635 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
636 dwExStyle |= WS_EX_TOOLWINDOW;
639 private->parent->children = g_list_prepend (private->parent->children, window);
641 klass = RegisterGdkClass (private->window_type, impl->type_hint);
643 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
645 hwndNew = CreateWindowExW (dwExStyle,
646 MAKEINTRESOURCEW (klass),
649 ((attributes_mask & GDK_WA_X) ?
650 private->x - offset_x : CW_USEDEFAULT),
651 private->y - offset_y,
652 window_width, window_height,
657 if (GDK_WINDOW_HWND (window) != hwndNew)
659 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
660 GDK_WINDOW_HWND (window),
663 /* HB: IHMO due to a race condition the handle was increased by
664 * one, which causes much trouble. Because I can't find the
665 * real bug, try to workaround it ...
666 * To reproduce: compile with MSVC 5, DEBUG=1
669 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
670 GDK_WINDOW_HWND (window) = hwndNew;
671 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
673 /* the old behaviour, but with warning */
674 draw_impl->handle = hwndNew;
679 g_object_ref (window);
680 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
682 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
684 window_width, window_height,
685 ((attributes_mask & GDK_WA_X) ?
686 private->x - offset_x: CW_USEDEFAULT),
687 private->y - offset_y,
689 GDK_WINDOW_HWND (window)));
691 /* Add window handle to title */
692 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
696 if (draw_impl->handle == NULL)
698 WIN32_API_FAILED ("CreateWindowExW");
699 g_object_unref (window);
703 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
704 // gdk_window_set_skip_taskbar_hint (window, TRUE);
706 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
707 (attributes->cursor) :
712 gdk_window_foreign_new_for_display (GdkDisplay *display,
713 GdkNativeWindow anid)
716 GdkWindowObject *private;
717 GdkWindowImplWin32 *impl;
718 GdkDrawableImplWin32 *draw_impl;
724 g_return_val_if_fail (display == _gdk_display, NULL);
726 window = g_object_new (GDK_TYPE_WINDOW, NULL);
727 private = (GdkWindowObject *)window;
728 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
729 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
730 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
731 draw_impl->wrapper = GDK_DRAWABLE (window);
732 parent = GetParent ((HWND)anid);
734 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
735 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
736 private->parent = (GdkWindowObject *)_gdk_root;
738 private->parent->children = g_list_prepend (private->parent->children, window);
740 draw_impl->handle = (HWND) anid;
741 GetClientRect ((HWND) anid, &rect);
743 point.y = rect.right;
744 ClientToScreen ((HWND) anid, &point);
745 if (parent != GetDesktopWindow ())
746 ScreenToClient (parent, &point);
747 private->x = point.x;
748 private->y = point.y;
749 private->width = rect.right - rect.left;
750 private->height = rect.bottom - rect.top;
751 private->window_type = GDK_WINDOW_FOREIGN;
752 private->destroyed = FALSE;
753 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
754 if (IsWindowVisible ((HWND) anid))
755 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
757 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
758 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
759 private->state |= GDK_WINDOW_STATE_ABOVE;
761 private->state &= (~GDK_WINDOW_STATE_ABOVE);
762 private->state &= (~GDK_WINDOW_STATE_BELOW);
764 private->depth = gdk_visual_get_system ()->depth;
766 //_gdk_window_init_position (GDK_WINDOW (private));
768 g_object_ref (window);
769 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
771 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
773 _gdk_win32_drawable_description (window),
774 private->x, private->y));
780 gdk_window_lookup (GdkNativeWindow hwnd)
782 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
786 _gdk_windowing_window_destroy (GdkWindow *window,
788 gboolean foreign_destroy)
790 GdkWindowObject *private = (GdkWindowObject *)window;
791 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
794 g_return_if_fail (GDK_IS_WINDOW (window));
796 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
797 GDK_WINDOW_HWND (window)));
799 if (private->extension_events != 0)
800 _gdk_input_window_destroy (window);
802 /* Remove ourself from the modal stack */
803 _gdk_remove_modal_window (window);
805 /* Remove all our transient children */
806 tmp = window_impl->transient_children;
809 GdkWindow *child = tmp->data;
810 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
812 child_impl->transient_owner = NULL;
813 tmp = g_slist_next (tmp);
815 g_slist_free (window_impl->transient_children);
816 window_impl->transient_children = NULL;
818 /* Remove ourself from our transient owner */
819 if (window_impl->transient_owner != NULL)
821 gdk_window_set_transient_for (window, NULL);
824 if (!recursing && !foreign_destroy)
826 _gdk_win32_drawable_finish (private->impl);
828 private->destroyed = TRUE;
829 DestroyWindow (GDK_WINDOW_HWND (window));
832 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
836 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
838 /* It's somebody else's window, but in our hierarchy, so reparent it
839 * to the desktop, and then try to destroy it.
841 gdk_window_hide (window);
842 gdk_window_reparent (window, NULL, 0, 0);
844 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
847 /* This function is called when the window really gone.
850 gdk_window_destroy_notify (GdkWindow *window)
852 g_return_if_fail (GDK_IS_WINDOW (window));
855 g_print ("gdk_window_destroy_notify: %p%s\n",
856 GDK_WINDOW_HWND (window),
857 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
859 if (!GDK_WINDOW_DESTROYED (window))
861 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
862 g_warning ("window %p unexpectedly destroyed",
863 GDK_WINDOW_HWND (window));
865 _gdk_window_destroy (window, TRUE);
868 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
869 g_object_unref (window);
873 get_outer_rect (GdkWindow *window,
878 rect->left = rect->top = 0;
880 rect->bottom = height;
882 _gdk_win32_adjust_client_rect (window, rect);
886 adjust_for_gravity_hints (GdkWindow *window,
891 GdkWindowObject *obj;
892 GdkWindowImplWin32 *impl;
894 obj = GDK_WINDOW_OBJECT (window);
895 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
897 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
899 gint orig_x = *x, orig_y = *y;
901 switch (impl->hints.win_gravity)
903 case GDK_GRAVITY_NORTH:
904 case GDK_GRAVITY_CENTER:
905 case GDK_GRAVITY_SOUTH:
906 *x -= (outer_rect->right - outer_rect->left) / 2;
907 *x += obj->width / 2;
910 case GDK_GRAVITY_SOUTH_EAST:
911 case GDK_GRAVITY_EAST:
912 case GDK_GRAVITY_NORTH_EAST:
913 *x -= outer_rect->right - outer_rect->left;
917 case GDK_GRAVITY_STATIC:
918 *x += outer_rect->left;
925 switch (impl->hints.win_gravity)
927 case GDK_GRAVITY_WEST:
928 case GDK_GRAVITY_CENTER:
929 case GDK_GRAVITY_EAST:
930 *y -= (outer_rect->bottom - outer_rect->top) / 2;
931 *y += obj->height / 2;
934 case GDK_GRAVITY_SOUTH_WEST:
935 case GDK_GRAVITY_SOUTH:
936 case GDK_GRAVITY_SOUTH_EAST:
937 *y -= outer_rect->bottom - outer_rect->top;
941 case GDK_GRAVITY_STATIC:
942 *y += outer_rect->top;
949 (orig_x != *x || orig_y != *y) ?
950 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
951 orig_x, *x, orig_y, *y)
957 show_window_internal (GdkWindow *window,
961 GdkWindowObject *private;
962 HWND old_active_window;
963 gboolean focus_on_map = TRUE;
967 private = (GdkWindowObject *) window;
969 if (private->destroyed)
972 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
973 GDK_WINDOW_HWND (window),
974 _gdk_win32_window_state_to_string (private->state),
975 (raise ? " raise" : ""),
976 (deiconify ? " deiconify" : "")));
978 /* If asked to show (not deiconify) an withdrawn and iconified
982 !GDK_WINDOW_IS_MAPPED (window) &&
983 (private->state & GDK_WINDOW_STATE_ICONIFIED))
985 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
989 /* If asked to just show an iconified window, do nothing. */
990 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
993 /* If asked to deiconify an already noniconified window, do
994 * nothing. (Especially, don't cause the window to rise and
995 * activate. There are different calls for that.)
997 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
1000 /* If asked to show (but not raise) a window that is already
1001 * visible, do nothing.
1003 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
1008 if (!GDK_WINDOW_IS_MAPPED (window))
1010 gdk_synthesize_window_state (window,
1011 GDK_WINDOW_STATE_WITHDRAWN,
1013 focus_on_map = private->focus_on_map;
1016 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1018 if (private->state & GDK_WINDOW_STATE_BELOW)
1019 exstyle &= (~WS_EX_TOPMOST);
1021 if (private->state & GDK_WINDOW_STATE_ABOVE)
1022 exstyle |= WS_EX_TOPMOST;
1024 if (exstyle & WS_EX_TOPMOST)
1029 /* Use SetWindowPos to show transparent windows so automatic redraws
1030 * in other windows can be suppressed.
1032 if (exstyle & WS_EX_TRANSPARENT)
1034 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1037 flags |= SWP_NOZORDER;
1038 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1039 flags |= SWP_NOACTIVATE;
1041 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
1046 old_active_window = GetActiveWindow ();
1048 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1050 gdk_window_fullscreen (window);
1052 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1054 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1056 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1058 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1060 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1062 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1066 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1071 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1072 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1074 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1075 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
1076 GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1078 if (focus_on_map && private->accept_focus)
1080 SetForegroundWindow (GDK_WINDOW_HWND (window));
1081 if (top == HWND_TOPMOST)
1082 SetWindowPos (GDK_WINDOW_HWND (window), top,
1084 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1088 SetWindowPos (GDK_WINDOW_HWND (window), top,
1090 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1095 BringWindowToTop (GDK_WINDOW_HWND (window));
1098 else if (old_active_window != GDK_WINDOW_HWND (window))
1100 SetActiveWindow (old_active_window);
1105 gdk_win32_window_show (GdkWindow *window,
1106 gboolean already_mapped)
1108 show_window_internal (window, FALSE, FALSE);
1112 gdk_win32_window_hide (GdkWindow *window)
1114 GdkWindowObject *private;
1116 private = (GdkWindowObject*) window;
1117 if (private->destroyed)
1120 GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
1121 GDK_WINDOW_HWND (window),
1122 _gdk_win32_window_state_to_string (private->state)));
1124 if (GDK_WINDOW_IS_MAPPED (window))
1125 gdk_synthesize_window_state (window,
1127 GDK_WINDOW_STATE_WITHDRAWN);
1129 _gdk_window_clear_update_area (window);
1131 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1132 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1134 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1136 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1138 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1142 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1147 gdk_win32_window_withdraw (GdkWindow *window)
1149 GdkWindowObject *private;
1151 private = (GdkWindowObject*) window;
1152 if (private->destroyed)
1155 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
1156 GDK_WINDOW_HWND (window),
1157 _gdk_win32_window_state_to_string (private->state)));
1159 gdk_window_hide (window); /* ??? */
1163 gdk_win32_window_move (GdkWindow *window,
1166 GdkWindowObject *private = (GdkWindowObject *)window;
1167 GdkWindowImplWin32 *impl;
1169 g_return_if_fail (GDK_IS_WINDOW (window));
1171 if (GDK_WINDOW_DESTROYED (window))
1174 GDK_NOTE (MISC, g_print ("gdk_window_move: %p: %+d%+d\n",
1175 GDK_WINDOW_HWND (window), x, y));
1177 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1179 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1182 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1183 * Foreign windows (another app's windows) might be children of our
1184 * windows! Especially in the case of gtkplug/socket.
1186 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1188 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1194 get_outer_rect (window, private->width, private->height, &outer_rect);
1196 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1198 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1199 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1200 GDK_WINDOW_HWND (window),
1201 x - _gdk_offset_x, y - _gdk_offset_y));
1203 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1204 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1205 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1210 gdk_win32_window_resize (GdkWindow *window,
1211 gint width, gint height)
1213 GdkWindowObject *private = (GdkWindowObject*) window;
1214 GdkWindowImplWin32 *impl;
1216 g_return_if_fail (GDK_IS_WINDOW (window));
1218 if (GDK_WINDOW_DESTROYED (window))
1226 GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
1227 GDK_WINDOW_HWND (window), width, height));
1229 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1231 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1234 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1236 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1242 get_outer_rect (window, width, height, &outer_rect);
1244 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1245 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1246 GDK_WINDOW_HWND (window),
1247 outer_rect.right - outer_rect.left,
1248 outer_rect.bottom - outer_rect.top));
1250 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1252 outer_rect.right - outer_rect.left,
1253 outer_rect.bottom - outer_rect.top,
1254 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1255 private->resize_count += 1;
1260 gdk_win32_window_move_resize_internal (GdkWindow *window,
1266 GdkWindowObject *private;
1267 GdkWindowImplWin32 *impl;
1269 g_return_if_fail (GDK_IS_WINDOW (window));
1271 if (GDK_WINDOW_DESTROYED (window))
1279 private = GDK_WINDOW_OBJECT (window);
1280 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1282 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1285 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@%+d%+d\n",
1286 GDK_WINDOW_HWND (window),
1287 width, height, x, y));
1289 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1291 _gdk_window_move_resize_child (window, x, y, width, height);
1297 get_outer_rect (window, width, height, &outer_rect);
1299 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1301 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1302 "NOACTIVATE|NOZORDER)\n",
1303 GDK_WINDOW_HWND (window),
1304 x - _gdk_offset_x, y - _gdk_offset_y,
1305 outer_rect.right - outer_rect.left,
1306 outer_rect.bottom - outer_rect.top));
1308 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1309 x - _gdk_offset_x, y - _gdk_offset_y,
1310 outer_rect.right - outer_rect.left,
1311 outer_rect.bottom - outer_rect.top,
1312 SWP_NOACTIVATE | SWP_NOZORDER));
1317 gdk_win32_window_move_resize (GdkWindow *window,
1324 if (with_move && (width < 0 && height < 0))
1326 gdk_win32_window_move (window, x, y);
1332 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1336 gdk_win32_window_resize (window, width, height);
1342 gdk_win32_window_reparent (GdkWindow *window,
1343 GdkWindow *new_parent,
1347 GdkWindowObject *window_private;
1348 GdkWindowObject *parent_private;
1349 GdkWindowObject *old_parent_private;
1350 GdkWindowImplWin32 *impl;
1351 gboolean was_toplevel;
1355 new_parent = _gdk_root;
1357 window_private = (GdkWindowObject*) window;
1358 old_parent_private = (GdkWindowObject *) window_private->parent;
1359 parent_private = (GdkWindowObject*) new_parent;
1360 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1362 GDK_NOTE (MISC, g_print ("_gdk_window_reparent: %p: %p\n",
1363 GDK_WINDOW_HWND (window),
1364 GDK_WINDOW_HWND (new_parent)));
1366 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1368 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1369 if (was_toplevel && new_parent != _gdk_root)
1371 /* Reparenting from top-level (child of desktop). Clear out
1374 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1376 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1378 else if (new_parent == _gdk_root)
1380 /* Reparenting to top-level. Add decorations. */
1381 style &= ~(WS_CHILD);
1382 style |= WS_OVERLAPPEDWINDOW;
1383 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1386 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1387 GDK_WINDOW_HWND (new_parent)));
1389 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1390 x, y, window_private->width, window_private->height, TRUE));
1392 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1395 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1396 new_parent = _gdk_root;
1398 window_private->parent = (GdkWindowObject *)new_parent;
1400 /* Switch the window type as appropriate */
1402 switch (GDK_WINDOW_TYPE (new_parent))
1404 case GDK_WINDOW_ROOT:
1405 if (impl->toplevel_window_type != -1)
1406 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1407 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1408 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1411 case GDK_WINDOW_TOPLEVEL:
1412 case GDK_WINDOW_CHILD:
1413 case GDK_WINDOW_DIALOG:
1414 case GDK_WINDOW_TEMP:
1415 if (WINDOW_IS_TOPLEVEL (window))
1417 /* Save the original window type so we can restore it if the
1418 * window is reparented back to be a toplevel.
1420 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1421 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1425 if (old_parent_private)
1426 old_parent_private->children =
1427 g_list_remove (old_parent_private->children, window);
1429 parent_private->children = g_list_prepend (parent_private->children, window);
1430 //_gdk_window_init_position (GDK_WINDOW (window_private));
1436 gdk_win32_window_raise (GdkWindow *window)
1438 if (!GDK_WINDOW_DESTROYED (window))
1440 GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
1441 GDK_WINDOW_HWND (window)));
1443 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1444 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1446 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1447 else if (((GdkWindowObject *)window)->accept_focus)
1448 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1450 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1452 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1457 gdk_win32_window_lower (GdkWindow *window)
1459 if (!GDK_WINDOW_DESTROYED (window))
1461 GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n"
1462 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1463 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1464 GDK_WINDOW_HWND (window),
1465 GDK_WINDOW_HWND (window)));
1467 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1469 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1474 gdk_window_set_hints (GdkWindow *window,
1483 /* Note that this function is obsolete */
1485 GdkWindowImplWin32 *impl;
1487 g_return_if_fail (GDK_IS_WINDOW (window));
1489 if (GDK_WINDOW_DESTROYED (window))
1492 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1494 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @%+d%+d\n",
1495 GDK_WINDOW_HWND (window),
1496 min_width, min_height, max_width, max_height,
1504 geom.min_width = min_width;
1505 geom.min_height = min_height;
1506 geom.max_width = max_width;
1507 geom.max_height = max_height;
1509 if (flags & GDK_HINT_MIN_SIZE)
1510 geom_mask |= GDK_HINT_MIN_SIZE;
1512 if (flags & GDK_HINT_MAX_SIZE)
1513 geom_mask |= GDK_HINT_MAX_SIZE;
1515 gdk_window_set_geometry_hints (window, &geom, geom_mask);
1520 gdk_window_set_urgency_hint (GdkWindow *window,
1523 FLASHWINFO flashwinfo;
1524 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1525 PFN_FlashWindowEx flashWindowEx = NULL;
1527 g_return_if_fail (GDK_IS_WINDOW (window));
1528 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1530 if (GDK_WINDOW_DESTROYED (window))
1533 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1537 flashwinfo.cbSize = sizeof (flashwinfo);
1538 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1540 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1542 flashwinfo.dwFlags = FLASHW_STOP;
1543 flashwinfo.uCount = 0;
1544 flashwinfo.dwTimeout = 0;
1546 flashWindowEx (&flashwinfo);
1550 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1555 get_effective_window_decorations (GdkWindow *window,
1556 GdkWMDecoration *decoration)
1558 GdkWindowImplWin32 *impl;
1560 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1562 if (gdk_window_get_decorations (window, decoration))
1565 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
1566 ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
1571 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1572 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1573 impl->hints.min_width == impl->hints.max_width &&
1574 impl->hints.min_height == impl->hints.max_height)
1576 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1578 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1579 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1580 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1582 *decoration |= GDK_DECOR_MINIMIZE;
1584 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1586 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1591 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1593 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1594 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1595 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1596 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1598 *decoration |= GDK_DECOR_MINIMIZE;
1605 switch (impl->type_hint)
1607 case GDK_WINDOW_TYPE_HINT_DIALOG:
1608 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1611 case GDK_WINDOW_TYPE_HINT_MENU:
1612 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1615 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1616 case GDK_WINDOW_TYPE_HINT_UTILITY:
1617 gdk_window_set_skip_taskbar_hint (window, TRUE);
1618 gdk_window_set_skip_pager_hint (window, TRUE);
1619 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1622 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1623 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1624 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1627 case GDK_WINDOW_TYPE_HINT_DOCK:
1630 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1635 case GDK_WINDOW_TYPE_HINT_NORMAL:
1636 *decoration = GDK_DECOR_ALL;
1645 gdk_window_set_geometry_hints (GdkWindow *window,
1646 const GdkGeometry *geometry,
1647 GdkWindowHints geom_mask)
1649 GdkWindowImplWin32 *impl;
1651 g_return_if_fail (GDK_IS_WINDOW (window));
1653 if (GDK_WINDOW_DESTROYED (window))
1656 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1657 GDK_WINDOW_HWND (window)));
1659 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1661 impl->hint_flags = geom_mask;
1662 impl->hints = *geometry;
1664 if (geom_mask & GDK_HINT_POS)
1665 ; /* even the X11 mplementation doesn't care */
1667 if (geom_mask & GDK_HINT_MIN_SIZE)
1669 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1670 geometry->min_width, geometry->min_height));
1673 if (geom_mask & GDK_HINT_MAX_SIZE)
1675 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1676 geometry->max_width, geometry->max_height));
1679 if (geom_mask & GDK_HINT_BASE_SIZE)
1681 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1682 geometry->base_width, geometry->base_height));
1685 if (geom_mask & GDK_HINT_RESIZE_INC)
1687 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1688 geometry->width_inc, geometry->height_inc));
1691 if (geom_mask & GDK_HINT_ASPECT)
1693 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1694 geometry->min_aspect, geometry->max_aspect));
1697 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1699 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1702 update_style_bits (window);
1706 gdk_window_set_title (GdkWindow *window,
1711 g_return_if_fail (GDK_IS_WINDOW (window));
1712 g_return_if_fail (title != NULL);
1714 if (GDK_WINDOW_DESTROYED (window))
1717 /* Empty window titles not allowed, so set it to just a period. */
1721 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1722 GDK_WINDOW_HWND (window), title));
1724 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1726 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1727 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1730 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1734 gdk_window_set_role (GdkWindow *window,
1737 g_return_if_fail (GDK_IS_WINDOW (window));
1739 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1740 GDK_WINDOW_HWND (window),
1741 (role ? role : "NULL")));
1746 gdk_window_set_transient_for (GdkWindow *window,
1749 HWND window_id, parent_id;
1750 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1751 GdkWindowImplWin32 *parent_impl = NULL;
1754 g_return_if_fail (GDK_IS_WINDOW (window));
1756 window_id = GDK_WINDOW_HWND (window);
1757 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1759 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1761 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1763 if (GDK_WINDOW_DESTROYED (window))
1764 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1766 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1771 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1773 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1779 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1780 if (trans_impl->transient_children != NULL)
1782 item = g_slist_find (trans_impl->transient_children, window);
1784 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1785 trans_impl->num_transients--;
1787 if (!trans_impl->num_transients)
1789 trans_impl->transient_children = NULL;
1792 g_object_unref (G_OBJECT (window_impl->transient_owner));
1793 g_object_unref (G_OBJECT (window));
1795 window_impl->transient_owner = NULL;
1799 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1801 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1802 g_object_ref (G_OBJECT (window));
1803 parent_impl->num_transients++;
1804 window_impl->transient_owner = parent;
1805 g_object_ref (G_OBJECT (parent));
1808 /* This changes the *owner* of the window, despite the misleading
1809 * name. (Owner and parent are unrelated concepts.) At least that's
1810 * what people who seem to know what they talk about say on
1811 * USENET. Search on Google.
1814 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1815 GetLastError () != 0)
1816 WIN32_API_FAILED ("SetWindowLongPtr");
1820 _gdk_push_modal_window (GdkWindow *window)
1822 modal_window_stack = g_slist_prepend (modal_window_stack,
1827 _gdk_remove_modal_window (GdkWindow *window)
1831 g_return_if_fail (window != NULL);
1833 /* It's possible to be NULL here if someone sets the modal hint of the window
1834 * to FALSE before a modal window stack has ever been created. */
1835 if (modal_window_stack == NULL)
1838 /* Find the requested window in the stack and remove it. Yeah, I realize this
1839 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1840 tmp = g_slist_find (modal_window_stack, window);
1843 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1848 _gdk_modal_current ()
1850 if (modal_window_stack != NULL)
1852 GSList *tmp = modal_window_stack;
1854 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1856 tmp = g_slist_next (tmp);
1859 return tmp != NULL ? tmp->data : NULL;
1868 gdk_win32_window_set_background (GdkWindow *window,
1869 const GdkColor *color)
1872 GdkWindowObject *private = (GdkWindowObject *)window;
1874 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
1875 GDK_WINDOW_HWND (window),
1876 _gdk_win32_color_to_string (color)));
1878 private->bg_color = *color;
1880 if (private->bg_pixmap &&
1881 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1882 private->bg_pixmap != GDK_NO_BG)
1884 g_object_unref (private->bg_pixmap);
1885 private->bg_pixmap = NULL;
1891 gdk_win32_window_set_back_pixmap (GdkWindow *window,
1894 GdkWindowObject *private = (GdkWindowObject *)window;
1896 if (private->bg_pixmap &&
1897 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1898 private->bg_pixmap != GDK_NO_BG)
1899 g_object_unref (private->bg_pixmap);
1901 if (pixmap == GDK_PARENT_RELATIVE_BG || pixmap == GDK_NO_BG)
1903 private->bg_pixmap = pixmap;
1908 gdk_win32_window_set_cursor (GdkWindow *window,
1911 GdkWindowImplWin32 *impl;
1912 GdkCursorPrivate *cursor_private;
1913 GdkWindowObject *parent_window;
1915 HCURSOR hprevcursor;
1917 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1918 cursor_private = (GdkCursorPrivate*) cursor;
1920 if (GDK_WINDOW_DESTROYED (window))
1926 hcursor = cursor_private->hcursor;
1928 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
1929 GDK_WINDOW_HWND (window),
1932 /* First get the old cursor, if any (we wait to free the old one
1933 * since it may be the current cursor set in the Win32 API right
1936 hprevcursor = impl->hcursor;
1938 if (hcursor == NULL)
1939 impl->hcursor = NULL;
1942 /* We must copy the cursor as it is OK to destroy the GdkCursor
1943 * while still in use for some window. See for instance
1944 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1945 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1948 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1949 WIN32_API_FAILED ("CopyCursor");
1950 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1951 hcursor, impl->hcursor));
1954 if (impl->hcursor != NULL)
1956 /* If the pointer is over our window, set new cursor */
1957 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
1958 if (curr_window == window)
1959 SetCursor (impl->hcursor);
1962 /* Climb up the tree and find whether our window is the
1963 * first ancestor that has cursor defined, and if so, set
1966 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
1967 while (curr_window_obj &&
1968 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
1970 curr_window_obj = curr_window_obj->parent;
1971 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
1973 SetCursor (impl->hcursor);
1980 /* Destroy the previous cursor: Need to make sure it's no longer in
1981 * use before we destroy it, in case we're not over our window but
1982 * the cursor is still set to our old one.
1984 if (hprevcursor != NULL)
1986 if (GetCursor () == hprevcursor)
1988 /* Look for a suitable cursor to use instead */
1990 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1991 while (hcursor == NULL)
1995 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1996 hcursor = impl->hcursor;
1997 parent_window = parent_window->parent;
2001 hcursor = LoadCursor (NULL, IDC_ARROW);
2004 SetCursor (hcursor);
2007 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
2009 API_CALL (DestroyCursor, (hprevcursor));
2014 gdk_win32_window_get_geometry (GdkWindow *window,
2024 if (!GDK_WINDOW_DESTROYED (window))
2028 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
2030 if (window != _gdk_root)
2033 GdkWindow *parent = gdk_window_get_parent (window);
2037 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2038 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2044 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2045 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2049 if (parent == _gdk_root)
2051 rect.left += _gdk_offset_x;
2052 rect.top += _gdk_offset_y;
2053 rect.right += _gdk_offset_x;
2054 rect.bottom += _gdk_offset_y;
2063 *width = rect.right - rect.left;
2065 *height = rect.bottom - rect.top;
2067 *depth = gdk_drawable_get_visual (window)->depth;
2069 GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
2070 GDK_WINDOW_HWND (window),
2071 rect.right - rect.left, rect.bottom - rect.top,
2072 gdk_drawable_get_visual (window)->depth,
2073 rect.left, rect.top));
2078 gdk_win32_window_get_root_coords (GdkWindow *window,
2090 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2095 *root_x = tx + _gdk_offset_x;
2097 *root_y = ty + _gdk_offset_y;
2099 GDK_NOTE (MISC, g_print ("gdk_window_get_root_coords: %p: %+d%+d %+d%+d\n",
2100 GDK_WINDOW_HWND (window),
2107 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2111 return gdk_win32_window_get_root_coords (window, 0, 0, x, y);
2115 gdk_win32_window_restack_under (GdkWindow *window,
2116 GList *native_siblings)
2122 gdk_window_get_root_origin (GdkWindow *window,
2128 g_return_if_fail (GDK_IS_WINDOW (window));
2130 gdk_window_get_frame_extents (window, &rect);
2138 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2139 GDK_WINDOW_HWND (window), rect.x, rect.y));
2143 gdk_window_get_frame_extents (GdkWindow *window,
2146 GdkWindowObject *private;
2150 g_return_if_fail (GDK_IS_WINDOW (window));
2151 g_return_if_fail (rect != NULL);
2153 private = GDK_WINDOW_OBJECT (window);
2160 if (GDK_WINDOW_DESTROYED (window))
2163 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2164 * necessary to walk its parent chain?
2166 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2167 private = (GdkWindowObject*) private->parent;
2169 hwnd = GDK_WINDOW_HWND (window);
2170 API_CALL (GetWindowRect, (hwnd, &r));
2172 rect->x = r.left + _gdk_offset_x;
2173 rect->y = r.top + _gdk_offset_y;
2174 rect->width = r.right - r.left;
2175 rect->height = r.bottom - r.top;
2177 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2178 GDK_WINDOW_HWND (window),
2179 r.right - r.left, r.bottom - r.top,
2184 static GdkModifierType
2185 get_current_mask (void)
2187 GdkModifierType mask;
2190 GetKeyboardState (kbd);
2192 if (kbd[VK_SHIFT] & 0x80)
2193 mask |= GDK_SHIFT_MASK;
2194 if (kbd[VK_CAPITAL] & 0x80)
2195 mask |= GDK_LOCK_MASK;
2196 if (kbd[VK_CONTROL] & 0x80)
2197 mask |= GDK_CONTROL_MASK;
2198 if (kbd[VK_MENU] & 0x80)
2199 mask |= GDK_MOD1_MASK;
2200 if (kbd[VK_LBUTTON] & 0x80)
2201 mask |= GDK_BUTTON1_MASK;
2202 if (kbd[VK_MBUTTON] & 0x80)
2203 mask |= GDK_BUTTON2_MASK;
2204 if (kbd[VK_RBUTTON] & 0x80)
2205 mask |= GDK_BUTTON3_MASK;
2211 gdk_window_win32_get_pointer (GdkWindow *window,
2214 GdkModifierType *mask)
2216 gboolean return_val;
2220 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2224 hwnd = GDK_WINDOW_HWND (window);
2225 GetCursorPos (&point);
2226 ScreenToClient (hwnd, &point);
2231 if (window == _gdk_root)
2233 *x += _gdk_offset_x;
2234 *y += _gdk_offset_y;
2237 hwndc = ChildWindowFromPoint (hwnd, point);
2238 if (hwndc != NULL && hwndc != hwnd &&
2239 !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc))
2240 return_val = FALSE; /* Direct child unknown to gdk */
2242 *mask = get_current_mask ();
2248 _gdk_windowing_get_pointer (GdkDisplay *display,
2252 GdkModifierType *mask)
2256 g_return_if_fail (display == _gdk_display);
2258 *screen = _gdk_screen;
2259 GetCursorPos (&point);
2260 *x = point.x + _gdk_offset_x;
2261 *y = point.y + _gdk_offset_y;
2263 *mask = get_current_mask ();
2267 gdk_display_warp_pointer (GdkDisplay *display,
2272 g_return_if_fail (display == _gdk_display);
2273 g_return_if_fail (screen == _gdk_screen);
2275 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2279 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2282 GdkModifierType *mask)
2285 POINT point, pointc;
2289 GetCursorPos (&pointc);
2291 hwnd = WindowFromPoint (point);
2296 *win_x = pointc.x + _gdk_offset_x;
2297 *win_y = pointc.y + _gdk_offset_y;
2301 ScreenToClient (hwnd, &point);
2304 hwndc = ChildWindowFromPoint (hwnd, point);
2305 ClientToScreen (hwnd, &point);
2306 ScreenToClient (hwndc, &point);
2307 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2309 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2311 if (window && (win_x || win_y))
2313 GetClientRect (hwnd, &rect);
2314 *win_x = point.x - rect.left;
2315 *win_y = point.y - rect.top;
2318 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2321 (window == NULL ? " NULL" : "")));
2327 gdk_win32_window_get_events (GdkWindow *window)
2329 if (GDK_WINDOW_DESTROYED (window))
2332 return GDK_WINDOW_OBJECT (window)->event_mask;
2336 gdk_win32_window_set_events (GdkWindow *window,
2337 GdkEventMask event_mask)
2339 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2340 * set it here, too. Not that I know or remember why it is
2341 * necessary, will have to test some day.
2343 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2347 do_shape_combine_region (GdkWindow *window,
2353 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2354 _gdk_win32_adjust_client_rect (window, &rect);
2356 OffsetRgn (hrgn, -rect.left, -rect.top);
2357 OffsetRgn (hrgn, x, y);
2359 /* If this is a top-level window, add the title bar to the region */
2360 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2362 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2363 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2367 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2371 gdk_win32_window_shape_combine_mask (GdkWindow *window,
2375 GdkWindowObject *private = (GdkWindowObject *)window;
2379 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2380 GDK_WINDOW_HWND (window)));
2381 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2383 private->shaped = FALSE;
2389 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2390 GDK_WINDOW_HWND (window),
2391 GDK_WINDOW_HWND (mask)));
2393 /* Convert mask bitmap to region */
2394 hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2396 do_shape_combine_region (window, hrgn, x, y);
2398 private->shaped = TRUE;
2403 gdk_window_set_override_redirect (GdkWindow *window,
2404 gboolean override_redirect)
2406 g_return_if_fail (GDK_IS_WINDOW (window));
2408 g_warning ("gdk_window_set_override_redirect not implemented");
2412 gdk_window_set_accept_focus (GdkWindow *window,
2413 gboolean accept_focus)
2415 GdkWindowObject *private;
2417 g_return_if_fail (GDK_IS_WINDOW (window));
2419 private = (GdkWindowObject *)window;
2421 accept_focus = accept_focus != FALSE;
2423 if (private->accept_focus != accept_focus)
2424 private->accept_focus = accept_focus;
2428 gdk_window_set_focus_on_map (GdkWindow *window,
2429 gboolean focus_on_map)
2431 GdkWindowObject *private;
2433 g_return_if_fail (GDK_IS_WINDOW (window));
2435 private = (GdkWindowObject *)window;
2437 focus_on_map = focus_on_map != FALSE;
2439 if (private->focus_on_map != focus_on_map)
2440 private->focus_on_map = focus_on_map;
2444 gdk_window_set_icon_list (GdkWindow *window,
2447 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2448 gint big_diff, small_diff;
2449 gint big_w, big_h, small_w, small_h;
2452 HICON small_hicon, big_hicon;
2453 GdkWindowImplWin32 *impl;
2454 gint i, big_i, small_i;
2456 g_return_if_fail (GDK_IS_WINDOW (window));
2458 if (GDK_WINDOW_DESTROYED (window))
2461 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2463 /* ideal sizes for small and large icons */
2464 big_w = GetSystemMetrics (SM_CXICON);
2465 big_h = GetSystemMetrics (SM_CYICON);
2466 small_w = GetSystemMetrics (SM_CXSMICON);
2467 small_h = GetSystemMetrics (SM_CYSMICON);
2469 /* find closest sized icons in the list */
2471 small_pixbuf = NULL;
2477 pixbuf = (GdkPixbuf*) pixbufs->data;
2478 w = gdk_pixbuf_get_width (pixbuf);
2479 h = gdk_pixbuf_get_height (pixbuf);
2481 dw = ABS (w - big_w);
2482 dh = ABS (h - big_h);
2483 diff = dw*dw + dh*dh;
2484 if (big_pixbuf == NULL || diff < big_diff)
2486 big_pixbuf = pixbuf;
2491 dw = ABS (w - small_w);
2492 dh = ABS (h - small_h);
2493 diff = dw*dw + dh*dh;
2494 if (small_pixbuf == NULL || diff < small_diff)
2496 small_pixbuf = pixbuf;
2501 pixbufs = g_list_next (pixbufs);
2505 /* Create the icons */
2506 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2507 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2510 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2512 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2513 (LPARAM)small_hicon);
2515 /* Store the icons, destroying any previous icons */
2516 if (impl->hicon_big)
2517 GDI_CALL (DestroyIcon, (impl->hicon_big));
2518 impl->hicon_big = big_hicon;
2519 if (impl->hicon_small)
2520 GDI_CALL (DestroyIcon, (impl->hicon_small));
2521 impl->hicon_small = small_hicon;
2525 gdk_window_set_icon (GdkWindow *window,
2526 GdkWindow *icon_window,
2530 g_return_if_fail (GDK_IS_WINDOW (window));
2532 /* do nothing, use gdk_window_set_icon_list instead */
2536 gdk_window_set_icon_name (GdkWindow *window,
2539 /* In case I manage to confuse this again (or somebody else does):
2540 * Please note that "icon name" here really *does* mean the name or
2541 * title of an window minimized as an icon on the desktop, or in the
2542 * taskbar. It has nothing to do with the freedesktop.org icon
2546 g_return_if_fail (GDK_IS_WINDOW (window));
2548 if (GDK_WINDOW_DESTROYED (window))
2552 /* This is not the correct thing to do. We should keep both the
2553 * "normal" window title, and the icon name. When the window is
2554 * minimized, call SetWindowText() with the icon name, and when the
2555 * window is restored, with the normal window title. Also, the name
2556 * is in UTF-8, so we should do the normal conversion to either wide
2557 * chars or system codepage, and use either the W or A version of
2558 * SetWindowText(), depending on Windows version.
2560 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2565 gdk_window_get_group (GdkWindow *window)
2567 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2568 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2570 if (GDK_WINDOW_DESTROYED (window))
2573 g_warning ("gdk_window_get_group not yet implemented");
2579 gdk_window_set_group (GdkWindow *window,
2582 g_return_if_fail (GDK_IS_WINDOW (window));
2583 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2584 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2586 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2589 g_warning ("gdk_window_set_group not implemented");
2593 update_single_bit (LONG *style,
2598 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2599 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2600 * bit indicate whether style_bit is on
2602 if ((!all && gdk_bit) || (all && !gdk_bit))
2603 *style |= style_bit;
2605 *style &= ~style_bit;
2609 update_style_bits (GdkWindow *window)
2611 GdkWindowObject *private = (GdkWindowObject *)window;
2612 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2613 GdkWMDecoration decorations;
2614 LONG old_style, new_style, old_exstyle, new_exstyle;
2616 RECT rect, before, after;
2618 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2619 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2621 GetClientRect (GDK_WINDOW_HWND (window), &before);
2623 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2625 new_style = old_style;
2626 new_exstyle = old_exstyle;
2628 if (private->window_type == GDK_WINDOW_TEMP ||
2629 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2630 new_exstyle |= WS_EX_TOOLWINDOW;
2632 new_exstyle &= ~WS_EX_TOOLWINDOW;
2634 if (get_effective_window_decorations (window, &decorations))
2636 all = (decorations & GDK_DECOR_ALL);
2637 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2638 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2639 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2640 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2641 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2642 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2645 if (old_style == new_style && old_exstyle == new_exstyle )
2647 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2648 GDK_WINDOW_HWND (window)));
2652 if (old_style != new_style)
2654 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2655 GDK_WINDOW_HWND (window),
2656 _gdk_win32_window_style_to_string (old_style),
2657 _gdk_win32_window_style_to_string (new_style)));
2659 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2662 if (old_exstyle != new_exstyle)
2664 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2665 GDK_WINDOW_HWND (window),
2666 _gdk_win32_window_exstyle_to_string (old_exstyle),
2667 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2669 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2672 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2674 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2675 rect.left += after.left - before.left;
2676 rect.top += after.top - before.top;
2677 rect.right += after.right - before.right;
2678 rect.bottom += after.bottom - before.bottom;
2680 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2681 rect.left, rect.top,
2682 rect.right - rect.left, rect.bottom - rect.top,
2683 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2684 SWP_NOREPOSITION | SWP_NOZORDER);
2689 update_single_system_menu_entry (HMENU hmenu,
2694 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2695 * gdk_bit indicates whether menu entry is disabled; if all is
2696 * FALSE, gdk bit indicate whether menu entry is enabled
2698 if ((!all && gdk_bit) || (all && !gdk_bit))
2699 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2701 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2705 update_system_menu (GdkWindow *window)
2707 GdkWMFunction functions;
2710 if (_gdk_window_get_functions (window, &functions))
2712 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2714 all = (functions & GDK_FUNC_ALL);
2715 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2716 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2717 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2718 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2719 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2724 get_decorations_quark ()
2726 static GQuark quark = 0;
2729 quark = g_quark_from_static_string ("gdk-window-decorations");
2735 gdk_window_set_decorations (GdkWindow *window,
2736 GdkWMDecoration decorations)
2738 GdkWMDecoration* decorations_copy;
2740 g_return_if_fail (GDK_IS_WINDOW (window));
2742 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2743 GDK_WINDOW_HWND (window),
2744 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2745 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2746 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2747 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2748 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2749 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2750 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2752 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2753 *decorations_copy = decorations;
2754 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2756 update_style_bits (window);
2760 gdk_window_get_decorations (GdkWindow *window,
2761 GdkWMDecoration *decorations)
2763 GdkWMDecoration* decorations_set;
2765 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2767 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2768 if (decorations_set)
2769 *decorations = *decorations_set;
2771 return (decorations_set != NULL);
2775 get_functions_quark ()
2777 static GQuark quark = 0;
2780 quark = g_quark_from_static_string ("gdk-window-functions");
2786 gdk_window_set_functions (GdkWindow *window,
2787 GdkWMFunction functions)
2789 GdkWMFunction* functions_copy;
2791 g_return_if_fail (GDK_IS_WINDOW (window));
2793 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2794 GDK_WINDOW_HWND (window),
2795 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2796 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2797 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2798 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2799 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2800 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2802 functions_copy = g_malloc (sizeof (GdkWMFunction));
2803 *functions_copy = functions;
2804 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2806 update_system_menu (window);
2810 _gdk_window_get_functions (GdkWindow *window,
2811 GdkWMFunction *functions)
2813 GdkWMDecoration* functions_set;
2815 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2817 *functions = *functions_set;
2819 return (functions_set != NULL);
2823 QueryTree (HWND hwnd,
2833 child = GetWindow (hwnd, GW_CHILD);
2835 child = GetWindow (child, GW_HWNDNEXT);
2838 } while (child != NULL);
2842 *children = g_new (HWND, n);
2843 for (i = 0; i < n; i++)
2846 child = GetWindow (hwnd, GW_CHILD);
2848 child = GetWindow (child, GW_HWNDNEXT);
2849 *children[i] = child;
2855 gdk_propagate_shapes (HANDLE win,
2859 HRGN region, childRegion;
2863 SetRectEmpty (&emptyRect);
2864 region = CreateRectRgnIndirect (&emptyRect);
2866 GetWindowRgn (win, region);
2868 QueryTree (win, &list, &num);
2871 WINDOWPLACEMENT placement;
2873 placement.length = sizeof (WINDOWPLACEMENT);
2874 /* go through all child windows and combine regions */
2875 for (i = 0; i < num; i++)
2877 GetWindowPlacement (list[i], &placement);
2878 if (placement.showCmd == SW_SHOWNORMAL)
2880 childRegion = CreateRectRgnIndirect (&emptyRect);
2881 GetWindowRgn (list[i], childRegion);
2882 CombineRgn (region, region, childRegion, RGN_OR);
2883 DeleteObject (childRegion);
2886 SetWindowRgn (win, region, TRUE);
2890 DeleteObject (region);
2894 gdk_win32_window_set_child_shapes (GdkWindow *window)
2896 if (GDK_WINDOW_DESTROYED (window))
2899 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2903 gdk_win32_window_merge_child_shapes (GdkWindow *window)
2905 if (GDK_WINDOW_DESTROYED (window))
2908 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2913 gdk_window_set_child_input_shapes (GdkWindow *window)
2915 g_return_if_fail (GDK_IS_WINDOW (window));
2917 /* Not yet implemented. See comment in
2918 * gdk_window_input_shape_combine_mask().
2925 gdk_window_merge_child_input_shapes (GdkWindow *window)
2927 g_return_if_fail (GDK_IS_WINDOW (window));
2929 /* Not yet implemented. See comment in
2930 * gdk_window_input_shape_combine_mask().
2936 gdk_win32_window_set_static_gravities (GdkWindow *window,
2937 gboolean use_static)
2939 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2945 gdk_window_begin_resize_drag (GdkWindow *window,
2954 g_return_if_fail (GDK_IS_WINDOW (window));
2956 if (GDK_WINDOW_DESTROYED (window))
2959 /* Tell Windows to start interactively resizing the window by pretending that
2960 * the left pointer button was clicked in the suitable edge or corner. This
2961 * will only work if the button is down when this function is called, and
2962 * will only work with button 1 (left), since Windows only allows window
2963 * dragging using the left mouse button.
2968 /* Must break the automatic grab that occured when the button was
2969 * pressed, otherwise it won't work.
2971 gdk_display_pointer_ungrab (_gdk_display, 0);
2975 case GDK_WINDOW_EDGE_NORTH_WEST:
2976 winedge = HTTOPLEFT;
2979 case GDK_WINDOW_EDGE_NORTH:
2983 case GDK_WINDOW_EDGE_NORTH_EAST:
2984 winedge = HTTOPRIGHT;
2987 case GDK_WINDOW_EDGE_WEST:
2991 case GDK_WINDOW_EDGE_EAST:
2995 case GDK_WINDOW_EDGE_SOUTH_WEST:
2996 winedge = HTBOTTOMLEFT;
2999 case GDK_WINDOW_EDGE_SOUTH:
3003 case GDK_WINDOW_EDGE_SOUTH_EAST:
3005 winedge = HTBOTTOMRIGHT;
3009 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
3010 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3014 gdk_window_begin_move_drag (GdkWindow *window,
3020 g_return_if_fail (GDK_IS_WINDOW (window));
3022 if (GDK_WINDOW_DESTROYED (window))
3025 /* Tell Windows to start interactively moving the window by pretending that
3026 * the left pointer button was clicked in the titlebar. This will only work
3027 * if the button is down when this function is called, and will only work
3028 * with button 1 (left), since Windows only allows window dragging using the
3029 * left mouse button.
3034 /* Must break the automatic grab that occured when the button was pressed,
3035 * otherwise it won't work.
3037 gdk_display_pointer_ungrab (_gdk_display, 0);
3039 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
3040 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3045 * Setting window states
3048 gdk_window_iconify (GdkWindow *window)
3050 HWND old_active_window;
3052 g_return_if_fail (GDK_IS_WINDOW (window));
3054 if (GDK_WINDOW_DESTROYED (window))
3057 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
3058 GDK_WINDOW_HWND (window),
3059 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3061 if (GDK_WINDOW_IS_MAPPED (window))
3063 old_active_window = GetActiveWindow ();
3064 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
3065 if (old_active_window != GDK_WINDOW_HWND (window))
3066 SetActiveWindow (old_active_window);
3070 gdk_synthesize_window_state (window,
3072 GDK_WINDOW_STATE_ICONIFIED);
3077 gdk_window_deiconify (GdkWindow *window)
3079 g_return_if_fail (GDK_IS_WINDOW (window));
3081 if (GDK_WINDOW_DESTROYED (window))
3084 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
3085 GDK_WINDOW_HWND (window),
3086 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3088 if (GDK_WINDOW_IS_MAPPED (window))
3090 show_window_internal (window, FALSE, TRUE);
3094 gdk_synthesize_window_state (window,
3095 GDK_WINDOW_STATE_ICONIFIED,
3101 gdk_window_stick (GdkWindow *window)
3103 g_return_if_fail (GDK_IS_WINDOW (window));
3105 if (GDK_WINDOW_DESTROYED (window))
3108 /* FIXME: Do something? */
3112 gdk_window_unstick (GdkWindow *window)
3114 g_return_if_fail (GDK_IS_WINDOW (window));
3116 if (GDK_WINDOW_DESTROYED (window))
3119 /* FIXME: Do something? */
3123 gdk_window_maximize (GdkWindow *window)
3125 g_return_if_fail (GDK_IS_WINDOW (window));
3127 if (GDK_WINDOW_DESTROYED (window))
3130 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
3131 GDK_WINDOW_HWND (window),
3132 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3134 if (GDK_WINDOW_IS_MAPPED (window))
3135 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
3137 gdk_synthesize_window_state (window,
3139 GDK_WINDOW_STATE_MAXIMIZED);
3143 gdk_window_unmaximize (GdkWindow *window)
3145 g_return_if_fail (GDK_IS_WINDOW (window));
3147 if (GDK_WINDOW_DESTROYED (window))
3150 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
3151 GDK_WINDOW_HWND (window),
3152 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3154 if (GDK_WINDOW_IS_MAPPED (window))
3155 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
3157 gdk_synthesize_window_state (window,
3158 GDK_WINDOW_STATE_MAXIMIZED,
3162 typedef struct _FullscreenInfo FullscreenInfo;
3164 struct _FullscreenInfo
3172 gdk_window_fullscreen (GdkWindow *window)
3174 gint x, y, width, height;
3176 GdkWindowObject *private = (GdkWindowObject *) window;
3180 g_return_if_fail (GDK_IS_WINDOW (window));
3182 fi = g_new (FullscreenInfo, 1);
3184 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3188 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3190 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
3191 mi.cbSize = sizeof (mi);
3192 if (monitor && GetMonitorInfo (monitor, &mi))
3194 x = mi.rcMonitor.left;
3195 y = mi.rcMonitor.top;
3196 width = mi.rcMonitor.right - x;
3197 height = mi.rcMonitor.bottom - y;
3202 width = GetSystemMetrics (SM_CXSCREEN);
3203 height = GetSystemMetrics (SM_CYSCREEN);
3206 /* remember for restoring */
3207 fi->hint_flags = impl->hint_flags;
3208 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3209 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3210 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3212 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3213 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3215 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3216 x, y, width, height,
3217 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3219 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3224 gdk_window_unfullscreen (GdkWindow *window)
3227 GdkWindowObject *private = (GdkWindowObject *) window;
3229 g_return_if_fail (GDK_IS_WINDOW (window));
3231 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3234 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3236 impl->hint_flags = fi->hint_flags;
3237 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3238 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3239 fi->r.left, fi->r.top,
3240 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3241 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3243 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3246 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3251 gdk_window_set_keep_above (GdkWindow *window,
3254 g_return_if_fail (GDK_IS_WINDOW (window));
3256 if (GDK_WINDOW_DESTROYED (window))
3259 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3260 GDK_WINDOW_HWND (window),
3261 setting ? "YES" : "NO"));
3263 if (GDK_WINDOW_IS_MAPPED (window))
3265 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3266 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3268 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3271 gdk_synthesize_window_state (window,
3272 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3273 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3277 gdk_window_set_keep_below (GdkWindow *window,
3280 g_return_if_fail (GDK_IS_WINDOW (window));
3282 if (GDK_WINDOW_DESTROYED (window))
3285 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3286 GDK_WINDOW_HWND (window),
3287 setting ? "YES" : "NO"));
3289 if (GDK_WINDOW_IS_MAPPED (window))
3291 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3292 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3294 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3297 gdk_synthesize_window_state (window,
3298 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3299 setting ? GDK_WINDOW_STATE_BELOW : 0);
3303 gdk_window_focus (GdkWindow *window,
3306 g_return_if_fail (GDK_IS_WINDOW (window));
3308 if (GDK_WINDOW_DESTROYED (window))
3311 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3312 GDK_WINDOW_HWND (window),
3313 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3315 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3316 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3318 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3319 SetFocus (GDK_WINDOW_HWND (window));
3323 gdk_window_set_modal_hint (GdkWindow *window,
3326 GdkWindowObject *private;
3328 g_return_if_fail (GDK_IS_WINDOW (window));
3330 if (GDK_WINDOW_DESTROYED (window))
3333 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3334 GDK_WINDOW_HWND (window),
3335 modal ? "YES" : "NO"));
3337 private = (GdkWindowObject*) window;
3339 if (modal == private->modal_hint)
3342 private->modal_hint = modal;
3345 /* Not sure about this one.. -- Cody */
3346 if (GDK_WINDOW_IS_MAPPED (window))
3347 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3348 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3350 SWP_NOMOVE | SWP_NOSIZE));
3355 _gdk_push_modal_window (window);
3356 gdk_window_raise (window);
3360 _gdk_remove_modal_window (window);
3367 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3368 gboolean skips_taskbar)
3370 static GdkWindow *owner = NULL;
3373 g_return_if_fail (GDK_IS_WINDOW (window));
3375 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3376 GDK_WINDOW_HWND (window),
3377 skips_taskbar ? "YES" : "NO"));
3379 // ### TODO: Need to figure out what to do here.
3387 wa.window_type = GDK_WINDOW_TEMP;
3388 wa.wclass = GDK_INPUT_OUTPUT;
3389 wa.width = wa.height = 1;
3391 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3395 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3397 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3398 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3399 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3400 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3402 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3403 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3408 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3413 gdk_window_set_skip_pager_hint (GdkWindow *window,
3414 gboolean skips_pager)
3416 g_return_if_fail (GDK_IS_WINDOW (window));
3418 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3419 GDK_WINDOW_HWND (window),
3420 skips_pager ? "YES" : "NO"));
3424 gdk_window_set_type_hint (GdkWindow *window,
3425 GdkWindowTypeHint hint)
3427 g_return_if_fail (GDK_IS_WINDOW (window));
3429 if (GDK_WINDOW_DESTROYED (window))
3434 static GEnumClass *class = NULL;
3436 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3437 g_print ("gdk_window_set_type_hint: %p: %s\n",
3438 GDK_WINDOW_HWND (window),
3439 g_enum_get_value (class, hint)->value_name);
3442 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3444 update_style_bits (window);
3448 gdk_window_get_type_hint (GdkWindow *window)
3450 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3452 if (GDK_WINDOW_DESTROYED (window))
3453 return GDK_WINDOW_TYPE_HINT_NORMAL;
3455 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3459 gdk_win32_window_shape_combine_region (GdkWindow *window,
3460 const GdkRegion *shape_region,
3464 GdkWindowObject *private = (GdkWindowObject *)window;
3466 if (GDK_WINDOW_DESTROYED (window))
3471 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n",
3472 GDK_WINDOW_HWND (window)));
3473 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3475 private->shaped = FALSE;
3481 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3483 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: %p\n",
3484 GDK_WINDOW_HWND (window),
3487 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3489 private->shaped = TRUE;
3494 gdk_window_lookup_for_display (GdkDisplay *display,
3495 GdkNativeWindow anid)
3497 g_return_val_if_fail (display == _gdk_display, NULL);
3499 return gdk_window_lookup (anid);
3503 gdk_window_enable_synchronized_configure (GdkWindow *window)
3505 g_return_if_fail (GDK_IS_WINDOW (window));
3509 gdk_window_configure_finished (GdkWindow *window)
3511 g_return_if_fail (GDK_IS_WINDOW (window));
3515 _gdk_windowing_window_beep (GdkWindow *window)
3517 gdk_display_beep (_gdk_display);
3521 gdk_window_set_opacity (GdkWindow *window,
3525 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3526 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3528 g_return_if_fail (GDK_IS_WINDOW (window));
3529 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3531 if (GDK_WINDOW_DESTROYED (window))
3536 else if (opacity > 1)
3539 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3541 if (!(exstyle & WS_EX_LAYERED))
3542 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3544 exstyle | WS_EX_LAYERED));
3546 setLayeredWindowAttributes =
3547 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3549 if (setLayeredWindowAttributes)
3551 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3559 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3566 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3571 _gdk_windowing_window_get_shape (GdkWindow *window)
3577 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3583 _gdk_win32_window_destroy (GdkWindow *window,
3585 gboolean foreign_destroy)
3590 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3593 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3595 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3596 GDK_WINDOW_HWND (window),
3597 _gdk_win32_gdkregion_to_string (area)));
3599 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3601 DeleteObject (hrgn);
3607 _gdk_win32_window_queue_translation (GdkWindow *window,
3612 /* TODO: Get current updateregion, move any part of it that intersects area by dx,dy */
3613 g_print ("queue_translation\n");
3617 gdk_win32_input_shape_combine_region (GdkWindow *window,
3618 const GdkRegion *shape_region,
3625 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3628 _gdk_window_process_updates_recurse (window, region);
3632 _gdk_windowing_before_process_all_updates (void)
3637 _gdk_windowing_after_process_all_updates (void)
3642 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3644 iface->show = gdk_win32_window_show;
3645 iface->hide = gdk_win32_window_hide;
3646 iface->withdraw = gdk_win32_window_withdraw;
3647 iface->set_events = gdk_win32_window_set_events;
3648 iface->get_events = gdk_win32_window_get_events;
3649 iface->raise = gdk_win32_window_raise;
3650 iface->lower = gdk_win32_window_lower;
3651 iface->restack_under = gdk_win32_window_restack_under;
3652 iface->move_resize = gdk_win32_window_move_resize;
3653 iface->set_background = gdk_win32_window_set_background;
3654 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3655 iface->reparent = gdk_win32_window_reparent;
3656 iface->set_cursor = gdk_win32_window_set_cursor;
3657 iface->get_geometry = gdk_win32_window_get_geometry;
3658 iface->get_pointer = gdk_window_win32_get_pointer;
3659 iface->get_root_coords = gdk_win32_window_get_root_coords;
3660 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3661 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3662 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3663 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3664 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3665 iface->queue_translation = _gdk_win32_window_queue_translation;
3666 iface->destroy = _gdk_win32_window_destroy;