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 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 GdkWindowImplWin32 *impl;
242 impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_root)->impl);
243 rect = _gdk_monitors[0].rect;
244 for (i = 1; i < _gdk_num_monitors; i++)
245 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
247 //impl->width = rect.width;
248 //impl->height = rect.height;
252 _gdk_windowing_window_init (GdkScreen *screen)
254 GdkWindowObject *private;
255 GdkDrawableImplWin32 *draw_impl;
257 g_assert (_gdk_root == NULL);
259 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
260 private = (GdkWindowObject *)_gdk_root;
261 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
262 private->impl_window = private;
264 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
266 draw_impl->handle = GetDesktopWindow ();
267 draw_impl->wrapper = GDK_DRAWABLE (private);
268 draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
269 g_object_ref (draw_impl->colormap);
271 private->window_type = GDK_WINDOW_ROOT;
272 private->depth = gdk_visual_get_system ()->depth;
274 _gdk_root_window_size_init ();
280 private->width = GetSystemMetrics (SM_CXSCREEN);
281 private->height = GetSystemMetrics (SM_CYSCREEN);
283 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
285 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
289 get_default_title (void)
292 title = g_get_application_name ();
294 title = g_get_prgname ();
300 * is a wrapper function for RegisterWindowClassEx.
301 * It creates at least one unique class for every
302 * GdkWindowType. If support for single window-specific icons
303 * is ever needed (e.g Dialog specific), every such window should
307 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
309 static ATOM klassTOPLEVEL = 0;
310 static ATOM klassDIALOG = 0;
311 static ATOM klassCHILD = 0;
312 static ATOM klassTEMP = 0;
313 static ATOM klassTEMPSHADOW = 0;
314 static HICON hAppIcon = NULL;
315 static HICON hAppIconSm = NULL;
316 static WNDCLASSEXW wcl;
319 wcl.cbSize = sizeof (WNDCLASSEX);
320 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
321 * on WM_SIZE and WM_MOVE. Flicker, Performance!
323 wcl.lpfnWndProc = _gdk_win32_window_procedure;
326 wcl.hInstance = _gdk_app_hmodule;
330 /* initialize once! */
331 if (0 == hAppIcon && 0 == hAppIconSm)
333 gchar sLoc [MAX_PATH+1];
335 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
337 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
339 if (0 == hAppIcon && 0 == hAppIconSm)
341 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
343 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
348 if (0 == hAppIcon && 0 == hAppIconSm)
350 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
351 GetSystemMetrics (SM_CXICON),
352 GetSystemMetrics (SM_CYICON), 0);
353 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
354 GetSystemMetrics (SM_CXSMICON),
355 GetSystemMetrics (SM_CYSMICON), 0);
360 hAppIcon = hAppIconSm;
361 else if (0 == hAppIconSm)
362 hAppIconSm = hAppIcon;
364 wcl.lpszMenuName = NULL;
366 /* initialize once per class */
368 * HB: Setting the background brush leads to flicker, because we
369 * don't get asked how to clear the background. This is not what
370 * we want, at least not for input_only windows ...
372 #define ONCE_PER_CLASS() \
373 wcl.hIcon = CopyIcon (hAppIcon); \
374 wcl.hIconSm = CopyIcon (hAppIconSm); \
375 wcl.hbrBackground = NULL; \
376 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
380 case GDK_WINDOW_TOPLEVEL:
381 if (0 == klassTOPLEVEL)
383 wcl.lpszClassName = L"gdkWindowToplevel";
386 klassTOPLEVEL = RegisterClassExW (&wcl);
388 klass = klassTOPLEVEL;
391 case GDK_WINDOW_CHILD:
394 wcl.lpszClassName = L"gdkWindowChild";
396 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
398 klassCHILD = RegisterClassExW (&wcl);
403 case GDK_WINDOW_DIALOG:
404 if (0 == klassDIALOG)
406 wcl.lpszClassName = L"gdkWindowDialog";
407 wcl.style |= CS_SAVEBITS;
409 klassDIALOG = RegisterClassExW (&wcl);
414 case GDK_WINDOW_TEMP:
415 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
416 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
417 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
418 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
420 if (klassTEMPSHADOW == 0)
422 wcl.lpszClassName = L"gdkWindowTempShadow";
423 wcl.style |= CS_SAVEBITS;
424 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
425 LOWORD (g_win32_get_windows_version()) == 0x0105)
427 /* Windows XP (5.1) or above */
428 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
431 klassTEMPSHADOW = RegisterClassExW (&wcl);
434 klass = klassTEMPSHADOW;
440 wcl.lpszClassName = L"gdkWindowTemp";
441 wcl.style |= CS_SAVEBITS;
443 klassTEMP = RegisterClassExW (&wcl);
451 g_assert_not_reached ();
457 WIN32_API_FAILED ("RegisterClassExW");
458 g_error ("That is a fatal error");
464 _gdk_window_impl_new (GdkWindow *window,
465 GdkWindow *real_parent,
468 GdkEventMask event_mask,
469 GdkWindowAttr *attributes,
470 gint attributes_mask)
475 DWORD dwStyle = 0, dwExStyle;
477 GdkWindow *orig_parent;
478 GdkWindowObject *private;
479 GdkWindowImplWin32 *impl;
480 GdkDrawableImplWin32 *draw_impl;
483 gint window_width, window_height;
484 gint offset_x = 0, offset_y = 0;
486 private = (GdkWindowObject *)window;
488 orig_parent = real_parent;
491 g_print ("gdk_window_new_internal: %s\n",
492 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
493 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
494 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
495 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
498 hparent = GDK_WINDOW_HWND (real_parent);
500 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
501 private->impl = (GdkDrawable *)impl;
502 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
503 draw_impl->wrapper = GDK_DRAWABLE (window);
505 // XXX: xattributes_mask = 0
508 if (attributes_mask & GDK_WA_VISUAL)
509 visual = attributes->visual;
511 visual = gdk_visual_get_system ();
515 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
516 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
518 impl->extension_events_selected = FALSE;
521 if (attributes->wclass == GDK_INPUT_OUTPUT)
525 private->input_only = FALSE;
526 private->depth = visual->depth;
528 if (attributes_mask & GDK_WA_COLORMAP)
530 draw_impl->colormap = attributes->colormap;
531 g_object_ref (attributes->colormap);
535 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
536 g_object_ref (draw_impl->colormap);
541 /* I very much doubt using WS_EX_TRANSPARENT actually
542 * corresponds to how X11 InputOnly windows work, but it appears
543 * to work well enough for the actual use cases in gtk.
545 dwExStyle = WS_EX_TRANSPARENT;
547 private->input_only = TRUE;
548 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
549 g_object_ref (draw_impl->colormap);
550 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap"));
553 switch (private->window_type)
555 case GDK_WINDOW_TOPLEVEL:
556 case GDK_WINDOW_DIALOG:
557 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
559 /* The common code warns for this case. */
560 hparent = GetDesktopWindow ();
562 /* Children of foreign windows aren't toplevel windows */
563 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
565 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
569 if (private->window_type == GDK_WINDOW_TOPLEVEL)
570 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
572 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
574 offset_x = _gdk_offset_x;
575 offset_y = _gdk_offset_y;
580 case GDK_WINDOW_CHILD:
581 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
585 case GDK_WINDOW_TEMP:
586 /* A temp window is not necessarily a top level window */
587 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
588 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
589 dwExStyle |= WS_EX_TOOLWINDOW;
590 offset_x = _gdk_offset_x;
591 offset_y = _gdk_offset_y;
595 g_assert_not_reached ();
598 //_gdk_window_init_position (GDK_WINDOW (private));
600 if (private->window_type != GDK_WINDOW_CHILD)
602 rect.left = rect.top = 0;
603 rect.right = private->width;
604 rect.bottom = private->height;
606 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
608 window_width = rect.right - rect.left;
609 window_height = rect.bottom - rect.top;
613 window_width = private->width;
614 window_height = private->height;
617 if (attributes_mask & GDK_WA_TITLE)
618 title = attributes->title;
620 title = get_default_title ();
621 if (!title || !*title)
624 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
626 if (attributes_mask & GDK_WA_TYPE_HINT)
627 impl->type_hint = attributes->type_hint;
629 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
631 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
632 dwExStyle |= WS_EX_TOOLWINDOW;
635 private->parent->children = g_list_prepend (private->parent->children, window);
637 klass = RegisterGdkClass (private->window_type, impl->type_hint);
639 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
641 hwndNew = CreateWindowExW (dwExStyle,
642 MAKEINTRESOURCEW (klass),
645 ((attributes_mask & GDK_WA_X) ?
646 private->x - offset_x : CW_USEDEFAULT),
647 private->y - offset_y,
648 window_width, window_height,
653 if (GDK_WINDOW_HWND (window) != hwndNew)
655 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
656 GDK_WINDOW_HWND (window),
659 /* HB: IHMO due to a race condition the handle was increased by
660 * one, which causes much trouble. Because I can't find the
661 * real bug, try to workaround it ...
662 * To reproduce: compile with MSVC 5, DEBUG=1
665 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
666 GDK_WINDOW_HWND (window) = hwndNew;
667 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
669 /* the old behaviour, but with warning */
670 draw_impl->handle = hwndNew;
675 g_object_ref (window);
676 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
678 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
680 window_width, window_height,
681 ((attributes_mask & GDK_WA_X) ?
682 private->x - offset_x: CW_USEDEFAULT),
683 private->y - offset_y,
685 GDK_WINDOW_HWND (window)));
687 /* Add window handle to title */
688 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
692 if (draw_impl->handle == NULL)
694 WIN32_API_FAILED ("CreateWindowExW");
695 g_object_unref (window);
699 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
700 // gdk_window_set_skip_taskbar_hint (window, TRUE);
702 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
703 (attributes->cursor) :
708 gdk_window_foreign_new_for_display (GdkDisplay *display,
709 GdkNativeWindow anid)
712 GdkWindowObject *private;
713 GdkWindowImplWin32 *impl;
714 GdkDrawableImplWin32 *draw_impl;
720 g_return_val_if_fail (display == _gdk_display, NULL);
722 window = g_object_new (GDK_TYPE_WINDOW, NULL);
723 private = (GdkWindowObject *)window;
724 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
725 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
726 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
727 draw_impl->wrapper = GDK_DRAWABLE (window);
728 parent = GetParent ((HWND)anid);
730 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
731 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
732 private->parent = (GdkWindowObject *)_gdk_root;
734 private->parent->children = g_list_prepend (private->parent->children, window);
736 draw_impl->handle = (HWND) anid;
737 GetClientRect ((HWND) anid, &rect);
739 point.y = rect.right;
740 ClientToScreen ((HWND) anid, &point);
741 if (parent != GetDesktopWindow ())
742 ScreenToClient (parent, &point);
743 private->x = point.x;
744 private->y = point.y;
745 private->width = rect.right - rect.left;
746 private->height = rect.bottom - rect.top;
747 private->window_type = GDK_WINDOW_FOREIGN;
748 private->destroyed = FALSE;
749 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
750 if (IsWindowVisible ((HWND) anid))
751 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
753 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
754 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
755 private->state |= GDK_WINDOW_STATE_ABOVE;
757 private->state &= (~GDK_WINDOW_STATE_ABOVE);
758 private->state &= (~GDK_WINDOW_STATE_BELOW);
760 private->depth = gdk_visual_get_system ()->depth;
762 //_gdk_window_init_position (GDK_WINDOW (private));
764 g_object_ref (window);
765 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
767 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
769 _gdk_win32_drawable_description (window),
770 private->x, private->y));
776 gdk_window_lookup (GdkNativeWindow hwnd)
778 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
782 _gdk_windowing_window_destroy (GdkWindow *window,
784 gboolean foreign_destroy)
786 GdkWindowObject *private = (GdkWindowObject *)window;
787 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
790 g_return_if_fail (GDK_IS_WINDOW (window));
792 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
793 GDK_WINDOW_HWND (window)));
795 if (private->extension_events != 0)
796 _gdk_input_window_destroy (window);
798 /* Remove ourself from the modal stack */
799 _gdk_remove_modal_window (window);
801 /* Remove all our transient children */
802 tmp = window_impl->transient_children;
805 GdkWindow *child = tmp->data;
806 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
808 child_impl->transient_owner = NULL;
809 tmp = g_slist_next (tmp);
811 g_slist_free (window_impl->transient_children);
812 window_impl->transient_children = NULL;
814 /* Remove ourself from our transient owner */
815 if (window_impl->transient_owner != NULL)
817 gdk_window_set_transient_for (window, NULL);
820 if (!recursing && !foreign_destroy)
822 _gdk_win32_drawable_finish (private->impl);
824 private->destroyed = TRUE;
825 DestroyWindow (GDK_WINDOW_HWND (window));
828 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
832 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
834 /* It's somebody else's window, but in our hierarchy, so reparent it
835 * to the desktop, and then try to destroy it.
837 gdk_window_hide (window);
838 gdk_window_reparent (window, NULL, 0, 0);
840 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
843 /* This function is called when the window really gone.
846 gdk_window_destroy_notify (GdkWindow *window)
848 g_return_if_fail (GDK_IS_WINDOW (window));
851 g_print ("gdk_window_destroy_notify: %p%s\n",
852 GDK_WINDOW_HWND (window),
853 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
855 if (!GDK_WINDOW_DESTROYED (window))
857 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
858 g_warning ("window %p unexpectedly destroyed",
859 GDK_WINDOW_HWND (window));
861 _gdk_window_destroy (window, TRUE);
864 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
865 g_object_unref (window);
869 get_outer_rect (GdkWindow *window,
874 rect->left = rect->top = 0;
876 rect->bottom = height;
878 _gdk_win32_adjust_client_rect (window, rect);
882 adjust_for_gravity_hints (GdkWindow *window,
887 GdkWindowObject *obj;
888 GdkWindowImplWin32 *impl;
890 obj = GDK_WINDOW_OBJECT (window);
891 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
893 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
895 gint orig_x = *x, orig_y = *y;
897 switch (impl->hints.win_gravity)
899 case GDK_GRAVITY_NORTH:
900 case GDK_GRAVITY_CENTER:
901 case GDK_GRAVITY_SOUTH:
902 *x -= (outer_rect->right - outer_rect->left) / 2;
903 *x += obj->width / 2;
906 case GDK_GRAVITY_SOUTH_EAST:
907 case GDK_GRAVITY_EAST:
908 case GDK_GRAVITY_NORTH_EAST:
909 *x -= outer_rect->right - outer_rect->left;
913 case GDK_GRAVITY_STATIC:
914 *x += outer_rect->left;
921 switch (impl->hints.win_gravity)
923 case GDK_GRAVITY_WEST:
924 case GDK_GRAVITY_CENTER:
925 case GDK_GRAVITY_EAST:
926 *y -= (outer_rect->bottom - outer_rect->top) / 2;
927 *y += obj->height / 2;
930 case GDK_GRAVITY_SOUTH_WEST:
931 case GDK_GRAVITY_SOUTH:
932 case GDK_GRAVITY_SOUTH_EAST:
933 *y -= outer_rect->bottom - outer_rect->top;
937 case GDK_GRAVITY_STATIC:
938 *y += outer_rect->top;
945 (orig_x != *x || orig_y != *y) ?
946 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
947 orig_x, *x, orig_y, *y)
953 show_window_internal (GdkWindow *window,
957 GdkWindowObject *private;
958 HWND old_active_window;
959 gboolean focus_on_map = TRUE;
963 private = (GdkWindowObject *) window;
965 if (private->destroyed)
968 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
969 GDK_WINDOW_HWND (window),
970 _gdk_win32_window_state_to_string (private->state),
971 //(raise ? " raise" : ""),
972 (deiconify ? " deiconify" : "")));
974 /* If asked to show (not deiconify) an withdrawn and iconified
978 !GDK_WINDOW_IS_MAPPED (window) &&
979 (private->state & GDK_WINDOW_STATE_ICONIFIED))
981 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
985 /* If asked to just show an iconified window, do nothing. */
986 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
989 /* If asked to deiconify an already noniconified window, do
990 * nothing. (Especially, don't cause the window to rise and
991 * activate. There are different calls for that.)
993 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
996 /* If asked to show (but not raise) a window that is already
997 * visible, do nothing.
999 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
1004 if (!GDK_WINDOW_IS_MAPPED (window))
1006 gdk_synthesize_window_state (window,
1007 GDK_WINDOW_STATE_WITHDRAWN,
1009 focus_on_map = private->focus_on_map;
1012 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1014 if (private->state & GDK_WINDOW_STATE_BELOW)
1015 exstyle &= (~WS_EX_TOPMOST);
1017 if (private->state & GDK_WINDOW_STATE_ABOVE)
1018 exstyle |= WS_EX_TOPMOST;
1020 if (exstyle & WS_EX_TOPMOST)
1025 /* Use SetWindowPos to show transparent windows so automatic redraws
1026 * in other windows can be suppressed.
1028 if (exstyle & WS_EX_TRANSPARENT)
1030 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1033 flags |= SWP_NOZORDER;
1034 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1035 flags |= SWP_NOACTIVATE;
1037 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
1042 old_active_window = GetActiveWindow ();
1044 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1046 gdk_window_fullscreen (window);
1048 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1050 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1052 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1054 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1056 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1058 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1062 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1067 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1068 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1070 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1071 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
1072 GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1074 if (focus_on_map && private->accept_focus)
1076 SetForegroundWindow (GDK_WINDOW_HWND (window));
1077 if (top == HWND_TOPMOST)
1078 SetWindowPos (GDK_WINDOW_HWND (window), top,
1080 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1084 SetWindowPos (GDK_WINDOW_HWND (window), top,
1086 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1091 BringWindowToTop (GDK_WINDOW_HWND (window));
1094 else if (old_active_window != GDK_WINDOW_HWND (window))
1096 SetActiveWindow (old_active_window);
1101 gdk_win32_window_show (GdkWindow *window)
1103 show_window_internal (window, FALSE, FALSE);
1107 gdk_win32_window_hide (GdkWindow *window)
1109 GdkWindowObject *private;
1111 private = (GdkWindowObject*) window;
1112 if (private->destroyed)
1115 GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
1116 GDK_WINDOW_HWND (window),
1117 _gdk_win32_window_state_to_string (private->state)));
1119 if (GDK_WINDOW_IS_MAPPED (window))
1120 gdk_synthesize_window_state (window,
1122 GDK_WINDOW_STATE_WITHDRAWN);
1124 _gdk_window_clear_update_area (window);
1126 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1127 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1129 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1131 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1133 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1137 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1142 gdk_win32_window_withdraw (GdkWindow *window)
1144 GdkWindowObject *private;
1146 private = (GdkWindowObject*) window;
1147 if (private->destroyed)
1150 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
1151 GDK_WINDOW_HWND (window),
1152 _gdk_win32_window_state_to_string (private->state)));
1154 gdk_window_hide (window); /* ??? */
1158 gdk_win32_window_move (GdkWindow *window,
1161 GdkWindowObject *private = (GdkWindowObject *)window;
1162 GdkWindowImplWin32 *impl;
1164 g_return_if_fail (GDK_IS_WINDOW (window));
1166 if (GDK_WINDOW_DESTROYED (window))
1169 GDK_NOTE (MISC, g_print ("gdk_window_move: %p: %+d%+d\n",
1170 GDK_WINDOW_HWND (window), x, y));
1172 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1174 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1177 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1178 * Foreign windows (another app's windows) might be children of our
1179 * windows! Especially in the case of gtkplug/socket.
1181 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1183 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1189 get_outer_rect (window, private->width, private->height, &outer_rect);
1191 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1193 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1194 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1195 GDK_WINDOW_HWND (window),
1196 x - _gdk_offset_x, y - _gdk_offset_y));
1198 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1199 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1200 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1205 gdk_win32_window_resize (GdkWindow *window,
1206 gint width, gint height)
1208 GdkWindowObject *private = (GdkWindowObject*) window;
1209 GdkWindowImplWin32 *impl;
1211 g_return_if_fail (GDK_IS_WINDOW (window));
1213 if (GDK_WINDOW_DESTROYED (window))
1221 GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
1222 GDK_WINDOW_HWND (window), width, height));
1224 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1226 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1229 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1231 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1237 get_outer_rect (window, width, height, &outer_rect);
1239 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1240 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1241 GDK_WINDOW_HWND (window),
1242 outer_rect.right - outer_rect.left,
1243 outer_rect.bottom - outer_rect.top));
1245 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1247 outer_rect.right - outer_rect.left,
1248 outer_rect.bottom - outer_rect.top,
1249 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1250 private->resize_count += 1;
1255 gdk_win32_window_move_resize_internal (GdkWindow *window,
1261 GdkWindowObject *private;
1262 GdkWindowImplWin32 *impl;
1264 g_return_if_fail (GDK_IS_WINDOW (window));
1266 if (GDK_WINDOW_DESTROYED (window))
1274 private = GDK_WINDOW_OBJECT (window);
1275 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1277 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1280 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@%+d%+d\n",
1281 GDK_WINDOW_HWND (window),
1282 width, height, x, y));
1284 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1286 _gdk_window_move_resize_child (window, x, y, width, height);
1292 get_outer_rect (window, width, height, &outer_rect);
1294 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1296 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1297 "NOACTIVATE|NOZORDER)\n",
1298 GDK_WINDOW_HWND (window),
1299 x - _gdk_offset_x, y - _gdk_offset_y,
1300 outer_rect.right - outer_rect.left,
1301 outer_rect.bottom - outer_rect.top));
1303 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1304 x - _gdk_offset_x, y - _gdk_offset_y,
1305 outer_rect.right - outer_rect.left,
1306 outer_rect.bottom - outer_rect.top,
1307 SWP_NOACTIVATE | SWP_NOZORDER));
1312 gdk_win32_window_move_resize (GdkWindow *window,
1319 if (with_move && (width < 0 && height < 0))
1321 gdk_win32_window_move (window, x, y);
1327 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1331 gdk_win32_window_resize (window, width, height);
1337 gdk_win32_window_reparent (GdkWindow *window,
1338 GdkWindow *new_parent,
1342 GdkWindowObject *window_private;
1343 GdkWindowObject *parent_private;
1344 GdkWindowObject *old_parent_private;
1345 GdkWindowImplWin32 *impl;
1346 gboolean was_toplevel;
1350 new_parent = _gdk_root;
1352 window_private = (GdkWindowObject*) window;
1353 old_parent_private = (GdkWindowObject *) window_private->parent;
1354 parent_private = (GdkWindowObject*) new_parent;
1355 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1357 GDK_NOTE (MISC, g_print ("_gdk_window_reparent: %p: %p\n",
1358 GDK_WINDOW_HWND (window),
1359 GDK_WINDOW_HWND (new_parent)));
1361 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1363 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1364 if (was_toplevel && new_parent != _gdk_root)
1366 /* Reparenting from top-level (child of desktop). Clear out
1369 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1371 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1373 else if (new_parent == _gdk_root)
1375 /* Reparenting to top-level. Add decorations. */
1376 style &= ~(WS_CHILD);
1377 style |= WS_OVERLAPPEDWINDOW;
1378 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1381 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1382 GDK_WINDOW_HWND (new_parent)));
1384 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1385 x, y, window_private->width, window_private->height, TRUE));
1387 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1390 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1391 new_parent = _gdk_root;
1393 window_private->parent = (GdkWindowObject *)new_parent;
1395 /* Switch the window type as appropriate */
1397 switch (GDK_WINDOW_TYPE (new_parent))
1399 case GDK_WINDOW_ROOT:
1400 if (impl->toplevel_window_type != -1)
1401 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1402 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1403 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1406 case GDK_WINDOW_TOPLEVEL:
1407 case GDK_WINDOW_CHILD:
1408 case GDK_WINDOW_DIALOG:
1409 case GDK_WINDOW_TEMP:
1410 if (WINDOW_IS_TOPLEVEL (window))
1412 /* Save the original window type so we can restore it if the
1413 * window is reparented back to be a toplevel.
1415 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1416 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1420 if (old_parent_private)
1421 old_parent_private->children =
1422 g_list_remove (old_parent_private->children, window);
1424 parent_private->children = g_list_prepend (parent_private->children, window);
1425 //_gdk_window_init_position (GDK_WINDOW (window_private));
1431 erase_background (GdkWindow *window,
1437 HPALETTE holdpal = NULL;
1440 GdkColormap *colormap;
1441 GdkColormapPrivateWin32 *colormap_private;
1443 int x_offset, y_offset;
1445 if (((GdkWindowObject *) window)->input_only ||
1446 ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG ||
1447 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->no_bg)
1452 colormap = gdk_drawable_get_colormap (window);
1455 (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
1456 colormap->visual->type == GDK_VISUAL_STATIC_COLOR))
1460 colormap_private = GDK_WIN32_COLORMAP_DATA (colormap);
1462 if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE)))
1463 WIN32_GDI_FAILED ("SelectPalette");
1464 else if ((k = RealizePalette (hdc)) == GDI_ERROR)
1465 WIN32_GDI_FAILED ("RealizePalette");
1467 GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n",
1468 colormap_private->hpal, k));
1471 x_offset = y_offset = 0;
1472 while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
1474 /* If this window should have the same background as the parent,
1475 * fetch the parent. (And if the same goes for the parent, fetch
1476 * the grandparent, etc.)
1478 x_offset += ((GdkWindowObject *) window)->x;
1479 y_offset += ((GdkWindowObject *) window)->y;
1480 window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
1483 if (GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->no_bg)
1485 /* Improves scolling effect, e.g. main buttons of testgtk */
1489 GetClipBox (hdc, &rect);
1491 if (((GdkWindowObject *) window)->bg_pixmap == NULL)
1493 bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap,
1494 ((GdkWindowObject *) window)->bg_color.pixel);
1496 if (!(hbr = CreateSolidBrush (bg)))
1497 WIN32_GDI_FAILED ("CreateSolidBrush");
1498 else if (!FillRect (hdc, &rect, hbr))
1499 WIN32_GDI_FAILED ("FillRect");
1503 else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG)
1505 GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap;
1506 GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
1508 if (x_offset == 0 && y_offset == 0 &&
1509 pixmap_impl->width <= 8 && pixmap_impl->height <= 8)
1511 if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap))))
1512 WIN32_GDI_FAILED ("CreatePatternBrush");
1513 else if (!FillRect (hdc, &rect, hbr))
1514 WIN32_GDI_FAILED ("FillRect");
1522 if (!(bgdc = CreateCompatibleDC (hdc)))
1524 WIN32_GDI_FAILED ("CreateCompatibleDC");
1527 if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap))))
1529 WIN32_GDI_FAILED ("SelectObject");
1534 while (x < rect.right)
1536 if (x + pixmap_impl->width >= rect.left)
1539 while (y < rect.bottom)
1541 if (y + pixmap_impl->height >= rect.top)
1543 if (!BitBlt (hdc, x, y,
1544 pixmap_impl->width, pixmap_impl->height,
1545 bgdc, 0, 0, SRCCOPY))
1547 WIN32_GDI_FAILED ("BitBlt");
1548 SelectObject (bgdc, oldbitmap);
1553 y += pixmap_impl->height;
1556 x += pixmap_impl->width;
1558 SelectObject (bgdc, oldbitmap);
1566 gdk_win32_window_clear_area (GdkWindow *window,
1571 gboolean send_expose)
1573 GdkWindowImplWin32 *impl;
1574 GdkWindowObject *obj;
1576 obj = GDK_WINDOW_OBJECT (window);
1577 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
1579 if (!GDK_WINDOW_DESTROYED (window))
1584 hdc = GetDC (GDK_WINDOW_HWND (window));
1589 width = obj->width - x;
1591 height = obj->height - y;
1592 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: "
1594 GDK_WINDOW_HWND (window),
1595 width, height, x, y));
1596 IntersectClipRect (hdc, x, y, x + width, y + height);
1597 erase_background (window, hdc);
1598 GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
1602 /* The background should be erased before the expose event is
1604 IntersectClipRect (hdc, x, y, x + width, y + height);
1605 erase_background (window, hdc);
1606 GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
1609 rect.right = x + width;
1611 rect.bottom = y + height;
1613 GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
1614 UpdateWindow (GDK_WINDOW_HWND (window));
1620 gdk_win32_window_raise (GdkWindow *window)
1622 if (!GDK_WINDOW_DESTROYED (window))
1624 GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
1625 GDK_WINDOW_HWND (window)));
1627 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1628 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1630 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1631 else if (((GdkWindowObject *)window)->accept_focus)
1632 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1634 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1636 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1641 gdk_win32_window_lower (GdkWindow *window)
1643 if (!GDK_WINDOW_DESTROYED (window))
1645 GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n"
1646 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1647 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1648 GDK_WINDOW_HWND (window),
1649 GDK_WINDOW_HWND (window)));
1651 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1653 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1658 gdk_window_set_hints (GdkWindow *window,
1667 /* Note that this function is obsolete */
1669 GdkWindowImplWin32 *impl;
1671 g_return_if_fail (GDK_IS_WINDOW (window));
1673 if (GDK_WINDOW_DESTROYED (window))
1676 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1678 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @%+d%+d\n",
1679 GDK_WINDOW_HWND (window),
1680 min_width, min_height, max_width, max_height,
1688 geom.min_width = min_width;
1689 geom.min_height = min_height;
1690 geom.max_width = max_width;
1691 geom.max_height = max_height;
1693 if (flags & GDK_HINT_MIN_SIZE)
1694 geom_mask |= GDK_HINT_MIN_SIZE;
1696 if (flags & GDK_HINT_MAX_SIZE)
1697 geom_mask |= GDK_HINT_MAX_SIZE;
1699 gdk_window_set_geometry_hints (window, &geom, geom_mask);
1704 gdk_window_set_urgency_hint (GdkWindow *window,
1707 FLASHWINFO flashwinfo;
1708 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1709 PFN_FlashWindowEx flashWindowEx = NULL;
1711 g_return_if_fail (GDK_IS_WINDOW (window));
1712 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1714 if (GDK_WINDOW_DESTROYED (window))
1717 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1721 flashwinfo.cbSize = sizeof (flashwinfo);
1722 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1724 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1726 flashwinfo.dwFlags = FLASHW_STOP;
1727 flashwinfo.uCount = 0;
1728 flashwinfo.dwTimeout = 0;
1730 flashWindowEx (&flashwinfo);
1734 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1739 get_effective_window_decorations (GdkWindow *window,
1740 GdkWMDecoration *decoration)
1742 GdkWindowImplWin32 *impl;
1744 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1746 if (gdk_window_get_decorations (window, decoration))
1749 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
1750 ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
1755 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1756 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1757 impl->hints.min_width == impl->hints.max_width &&
1758 impl->hints.min_height == impl->hints.max_height)
1760 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1762 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1763 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1764 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1766 *decoration |= GDK_DECOR_MINIMIZE;
1768 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1770 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1775 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1777 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1778 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1779 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1780 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1782 *decoration |= GDK_DECOR_MINIMIZE;
1789 switch (impl->type_hint)
1791 case GDK_WINDOW_TYPE_HINT_DIALOG:
1792 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1795 case GDK_WINDOW_TYPE_HINT_MENU:
1796 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1799 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1800 case GDK_WINDOW_TYPE_HINT_UTILITY:
1801 gdk_window_set_skip_taskbar_hint (window, TRUE);
1802 gdk_window_set_skip_pager_hint (window, TRUE);
1803 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1806 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1807 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1808 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1811 case GDK_WINDOW_TYPE_HINT_DOCK:
1814 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1819 case GDK_WINDOW_TYPE_HINT_NORMAL:
1820 *decoration = GDK_DECOR_ALL;
1829 gdk_window_set_geometry_hints (GdkWindow *window,
1830 const GdkGeometry *geometry,
1831 GdkWindowHints geom_mask)
1833 GdkWindowImplWin32 *impl;
1835 g_return_if_fail (GDK_IS_WINDOW (window));
1837 if (GDK_WINDOW_DESTROYED (window))
1840 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1841 GDK_WINDOW_HWND (window)));
1843 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1845 impl->hint_flags = geom_mask;
1846 impl->hints = *geometry;
1848 if (geom_mask & GDK_HINT_POS)
1849 ; /* even the X11 mplementation doesn't care */
1851 if (geom_mask & GDK_HINT_MIN_SIZE)
1853 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1854 geometry->min_width, geometry->min_height));
1857 if (geom_mask & GDK_HINT_MAX_SIZE)
1859 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1860 geometry->max_width, geometry->max_height));
1863 if (geom_mask & GDK_HINT_BASE_SIZE)
1865 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1866 geometry->base_width, geometry->base_height));
1869 if (geom_mask & GDK_HINT_RESIZE_INC)
1871 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1872 geometry->width_inc, geometry->height_inc));
1875 if (geom_mask & GDK_HINT_ASPECT)
1877 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1878 geometry->min_aspect, geometry->max_aspect));
1881 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1883 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1886 update_style_bits (window);
1890 gdk_window_set_title (GdkWindow *window,
1895 g_return_if_fail (GDK_IS_WINDOW (window));
1896 g_return_if_fail (title != NULL);
1898 if (GDK_WINDOW_DESTROYED (window))
1901 /* Empty window titles not allowed, so set it to just a period. */
1905 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1906 GDK_WINDOW_HWND (window), title));
1908 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1910 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1911 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1914 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1918 gdk_window_set_role (GdkWindow *window,
1921 g_return_if_fail (GDK_IS_WINDOW (window));
1923 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1924 GDK_WINDOW_HWND (window),
1925 (role ? role : "NULL")));
1930 gdk_window_set_transient_for (GdkWindow *window,
1933 HWND window_id, parent_id;
1934 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1935 GdkWindowImplWin32 *parent_impl = NULL;
1938 g_return_if_fail (GDK_IS_WINDOW (window));
1940 window_id = GDK_WINDOW_HWND (window);
1941 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1943 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1945 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1947 if (GDK_WINDOW_DESTROYED (window))
1948 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1950 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1955 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1957 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1963 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1964 if (trans_impl->transient_children != NULL)
1966 item = g_slist_find (trans_impl->transient_children, window);
1968 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1969 trans_impl->num_transients--;
1971 if (!trans_impl->num_transients)
1973 trans_impl->transient_children = NULL;
1976 g_object_unref (G_OBJECT (window_impl->transient_owner));
1977 g_object_unref (G_OBJECT (window));
1979 window_impl->transient_owner = NULL;
1983 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1985 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1986 g_object_ref (G_OBJECT (window));
1987 parent_impl->num_transients++;
1988 window_impl->transient_owner = parent;
1989 g_object_ref (G_OBJECT (parent));
1992 /* This changes the *owner* of the window, despite the misleading
1993 * name. (Owner and parent are unrelated concepts.) At least that's
1994 * what people who seem to know what they talk about say on
1995 * USENET. Search on Google.
1998 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1999 GetLastError () != 0)
2000 WIN32_API_FAILED ("SetWindowLongPtr");
2004 _gdk_push_modal_window (GdkWindow *window)
2006 modal_window_stack = g_slist_prepend (modal_window_stack,
2011 _gdk_remove_modal_window (GdkWindow *window)
2015 g_return_if_fail (window != NULL);
2017 /* It's possible to be NULL here if someone sets the modal hint of the window
2018 * to FALSE before a modal window stack has ever been created. */
2019 if (modal_window_stack == NULL)
2022 /* Find the requested window in the stack and remove it. Yeah, I realize this
2023 * means we're not a 'real stack', strictly speaking. Sue me. :) */
2024 tmp = g_slist_find (modal_window_stack, window);
2027 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
2032 _gdk_modal_current ()
2034 if (modal_window_stack != NULL)
2036 GSList *tmp = modal_window_stack;
2038 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
2040 tmp = g_slist_next (tmp);
2043 return tmp != NULL ? tmp->data : NULL;
2052 gdk_win32_window_set_background (GdkWindow *window,
2053 const GdkColor *color)
2056 GdkWindowObject *private = (GdkWindowObject *)window;
2058 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
2059 GDK_WINDOW_HWND (window),
2060 _gdk_win32_color_to_string (color)));
2062 private->bg_color = *color;
2064 if (private->bg_pixmap &&
2065 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2066 private->bg_pixmap != GDK_NO_BG)
2068 g_object_unref (private->bg_pixmap);
2069 private->bg_pixmap = NULL;
2075 gdk_win32_window_set_back_pixmap (GdkWindow *window,
2078 GdkWindowObject *private = (GdkWindowObject *)window;
2080 if (pixmap == GDK_PARENT_RELATIVE_BG || pixmap == GDK_NO_BG)
2082 private->bg_pixmap = pixmap;
2087 gdk_win32_window_set_cursor (GdkWindow *window,
2090 GdkWindowImplWin32 *impl;
2091 GdkCursorPrivate *cursor_private;
2092 GdkWindowObject *parent_window;
2094 HCURSOR hprevcursor;
2096 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2097 cursor_private = (GdkCursorPrivate*) cursor;
2099 if (GDK_WINDOW_DESTROYED (window))
2105 hcursor = cursor_private->hcursor;
2107 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
2108 GDK_WINDOW_HWND (window),
2111 /* First get the old cursor, if any (we wait to free the old one
2112 * since it may be the current cursor set in the Win32 API right
2115 hprevcursor = impl->hcursor;
2117 if (hcursor == NULL)
2118 impl->hcursor = NULL;
2121 /* We must copy the cursor as it is OK to destroy the GdkCursor
2122 * while still in use for some window. See for instance
2123 * gimp_change_win_cursor() which calls gdk_window_set_cursor
2124 * (win, cursor), and immediately afterwards gdk_cursor_destroy
2127 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
2128 WIN32_API_FAILED ("CopyCursor");
2129 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
2130 hcursor, impl->hcursor));
2133 if (impl->hcursor != NULL)
2135 /* If the pointer is over our window, set new cursor */
2136 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
2137 if (curr_window == window)
2138 SetCursor (impl->hcursor);
2141 /* Climb up the tree and find whether our window is the
2142 * first ancestor that has cursor defined, and if so, set
2145 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
2146 while (curr_window_obj &&
2147 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
2149 curr_window_obj = curr_window_obj->parent;
2150 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
2152 SetCursor (impl->hcursor);
2159 /* Destroy the previous cursor: Need to make sure it's no longer in
2160 * use before we destroy it, in case we're not over our window but
2161 * the cursor is still set to our old one.
2163 if (hprevcursor != NULL)
2165 if (GetCursor () == hprevcursor)
2167 /* Look for a suitable cursor to use instead */
2169 parent_window = GDK_WINDOW_OBJECT (window)->parent;
2170 while (hcursor == NULL)
2174 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
2175 hcursor = impl->hcursor;
2176 parent_window = parent_window->parent;
2180 hcursor = LoadCursor (NULL, IDC_ARROW);
2183 SetCursor (hcursor);
2186 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
2188 API_CALL (DestroyCursor, (hprevcursor));
2193 gdk_win32_window_get_geometry (GdkWindow *window,
2203 if (!GDK_WINDOW_DESTROYED (window))
2207 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
2209 if (window != _gdk_root)
2212 GdkWindow *parent = gdk_window_get_parent (window);
2216 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2217 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2223 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2224 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2228 if (parent == _gdk_root)
2230 rect.left += _gdk_offset_x;
2231 rect.top += _gdk_offset_y;
2232 rect.right += _gdk_offset_x;
2233 rect.bottom += _gdk_offset_y;
2242 *width = rect.right - rect.left;
2244 *height = rect.bottom - rect.top;
2246 *depth = gdk_drawable_get_visual (window)->depth;
2248 GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
2249 GDK_WINDOW_HWND (window),
2250 rect.right - rect.left, rect.bottom - rect.top,
2251 gdk_drawable_get_visual (window)->depth,
2252 rect.left, rect.top));
2257 gdk_win32_window_get_origin (GdkWindow *window,
2265 if (!GDK_WINDOW_DESTROYED (window))
2271 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2280 *x = tx + _gdk_offset_x;
2282 *y = ty + _gdk_offset_y;
2284 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: %+d%+d\n",
2285 GDK_WINDOW_HWND (window),
2291 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2295 return gdk_window_get_origin (window, x, y);
2299 gdk_win32_window_restack_under (GdkWindow *window,
2300 GList *native_siblings)
2306 gdk_window_get_root_origin (GdkWindow *window,
2312 g_return_if_fail (GDK_IS_WINDOW (window));
2314 gdk_window_get_frame_extents (window, &rect);
2322 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2323 GDK_WINDOW_HWND (window), rect.x, rect.y));
2327 gdk_window_get_frame_extents (GdkWindow *window,
2330 GdkWindowObject *private;
2334 g_return_if_fail (GDK_IS_WINDOW (window));
2335 g_return_if_fail (rect != NULL);
2337 private = GDK_WINDOW_OBJECT (window);
2344 if (GDK_WINDOW_DESTROYED (window))
2347 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2348 * necessary to walk its parent chain?
2350 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2351 private = (GdkWindowObject*) private->parent;
2353 hwnd = GDK_WINDOW_HWND (window);
2354 API_CALL (GetWindowRect, (hwnd, &r));
2356 rect->x = r.left + _gdk_offset_x;
2357 rect->y = r.top + _gdk_offset_y;
2358 rect->width = r.right - r.left;
2359 rect->height = r.bottom - r.top;
2361 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2362 GDK_WINDOW_HWND (window),
2363 r.right - r.left, r.bottom - r.top,
2368 _gdk_windowing_window_get_pointer (GdkDisplay *display,
2372 GdkModifierType *mask)
2374 GdkWindow *return_val;
2375 POINT screen_point, point;
2379 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2382 GetCursorPos (&screen_point);
2383 point = screen_point;
2384 ScreenToClient (GDK_WINDOW_HWND (window), &point);
2389 if (window == _gdk_root)
2391 *x += _gdk_offset_x;
2392 *y += _gdk_offset_y;
2395 hwnd = WindowFromPoint (screen_point);
2398 gboolean done = FALSE;
2402 point = screen_point;
2403 ScreenToClient (hwnd, &point);
2404 hwndc = ChildWindowFromPoint (hwnd, point);
2407 else if (hwndc == hwnd)
2413 return_val = gdk_window_lookup ((GdkNativeWindow) hwnd);
2418 GetKeyboardState (kbd);
2420 if (kbd[VK_SHIFT] & 0x80)
2421 *mask |= GDK_SHIFT_MASK;
2422 if (kbd[VK_CAPITAL] & 0x80)
2423 *mask |= GDK_LOCK_MASK;
2424 if (kbd[VK_CONTROL] & 0x80)
2425 *mask |= GDK_CONTROL_MASK;
2426 if (kbd[VK_MENU] & 0x80)
2427 *mask |= GDK_MOD1_MASK;
2428 if (kbd[VK_LBUTTON] & 0x80)
2429 *mask |= GDK_BUTTON1_MASK;
2430 if (kbd[VK_MBUTTON] & 0x80)
2431 *mask |= GDK_BUTTON2_MASK;
2432 if (kbd[VK_RBUTTON] & 0x80)
2433 *mask |= GDK_BUTTON3_MASK;
2439 _gdk_windowing_get_pointer (GdkDisplay *display,
2443 GdkModifierType *mask)
2445 g_return_if_fail (display == _gdk_display);
2447 *screen = _gdk_screen;
2448 _gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask);
2452 gdk_display_warp_pointer (GdkDisplay *display,
2457 g_return_if_fail (display == _gdk_display);
2458 g_return_if_fail (screen == _gdk_screen);
2460 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2464 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2467 GdkModifierType *mask)
2470 POINT point, pointc;
2474 GetCursorPos (&pointc);
2476 hwnd = WindowFromPoint (point);
2481 *win_x = pointc.x + _gdk_offset_x;
2482 *win_y = pointc.y + _gdk_offset_y;
2486 ScreenToClient (hwnd, &point);
2489 hwndc = ChildWindowFromPoint (hwnd, point);
2490 ClientToScreen (hwnd, &point);
2491 ScreenToClient (hwndc, &point);
2492 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2494 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2496 if (window && (win_x || win_y))
2498 GetClientRect (hwnd, &rect);
2499 *win_x = point.x - rect.left;
2500 *win_y = point.y - rect.top;
2503 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2506 (window == NULL ? " NULL" : "")));
2512 gdk_win32_window_get_events (GdkWindow *window)
2514 if (GDK_WINDOW_DESTROYED (window))
2517 return GDK_WINDOW_OBJECT (window)->event_mask;
2521 gdk_win32_window_set_events (GdkWindow *window,
2522 GdkEventMask event_mask)
2524 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2525 * set it here, too. Not that I know or remember why it is
2526 * necessary, will have to test some day.
2528 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2532 do_shape_combine_region (GdkWindow *window,
2538 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2539 _gdk_win32_adjust_client_rect (window, &rect);
2541 OffsetRgn (hrgn, -rect.left, -rect.top);
2542 OffsetRgn (hrgn, x, y);
2544 /* If this is a top-level window, add the title bar to the region */
2545 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2547 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2548 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2552 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2556 gdk_win32_window_shape_combine_mask (GdkWindow *window,
2560 GdkWindowObject *private = (GdkWindowObject *)window;
2564 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2565 GDK_WINDOW_HWND (window)));
2566 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2568 private->shaped = FALSE;
2574 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2575 GDK_WINDOW_HWND (window),
2576 GDK_WINDOW_HWND (mask)));
2578 /* Convert mask bitmap to region */
2579 hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2581 do_shape_combine_region (window, hrgn, x, y);
2583 private->shaped = TRUE;
2588 gdk_window_set_override_redirect (GdkWindow *window,
2589 gboolean override_redirect)
2591 g_return_if_fail (GDK_IS_WINDOW (window));
2593 g_warning ("gdk_window_set_override_redirect not implemented");
2597 gdk_window_set_accept_focus (GdkWindow *window,
2598 gboolean accept_focus)
2600 GdkWindowObject *private;
2602 g_return_if_fail (GDK_IS_WINDOW (window));
2604 private = (GdkWindowObject *)window;
2606 accept_focus = accept_focus != FALSE;
2608 if (private->accept_focus != accept_focus)
2609 private->accept_focus = accept_focus;
2613 gdk_window_set_focus_on_map (GdkWindow *window,
2614 gboolean focus_on_map)
2616 GdkWindowObject *private;
2618 g_return_if_fail (GDK_IS_WINDOW (window));
2620 private = (GdkWindowObject *)window;
2622 focus_on_map = focus_on_map != FALSE;
2624 if (private->focus_on_map != focus_on_map)
2625 private->focus_on_map = focus_on_map;
2629 gdk_window_set_icon_list (GdkWindow *window,
2632 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2633 gint big_diff, small_diff;
2634 gint big_w, big_h, small_w, small_h;
2637 HICON small_hicon, big_hicon;
2638 GdkWindowImplWin32 *impl;
2639 gint i, big_i, small_i;
2641 g_return_if_fail (GDK_IS_WINDOW (window));
2643 if (GDK_WINDOW_DESTROYED (window))
2646 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2648 /* ideal sizes for small and large icons */
2649 big_w = GetSystemMetrics (SM_CXICON);
2650 big_h = GetSystemMetrics (SM_CYICON);
2651 small_w = GetSystemMetrics (SM_CXSMICON);
2652 small_h = GetSystemMetrics (SM_CYSMICON);
2654 /* find closest sized icons in the list */
2656 small_pixbuf = NULL;
2662 pixbuf = (GdkPixbuf*) pixbufs->data;
2663 w = gdk_pixbuf_get_width (pixbuf);
2664 h = gdk_pixbuf_get_height (pixbuf);
2666 dw = ABS (w - big_w);
2667 dh = ABS (h - big_h);
2668 diff = dw*dw + dh*dh;
2669 if (big_pixbuf == NULL || diff < big_diff)
2671 big_pixbuf = pixbuf;
2676 dw = ABS (w - small_w);
2677 dh = ABS (h - small_h);
2678 diff = dw*dw + dh*dh;
2679 if (small_pixbuf == NULL || diff < small_diff)
2681 small_pixbuf = pixbuf;
2686 pixbufs = g_list_next (pixbufs);
2690 /* Create the icons */
2691 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2692 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2695 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2697 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2698 (LPARAM)small_hicon);
2700 /* Store the icons, destroying any previous icons */
2701 if (impl->hicon_big)
2702 GDI_CALL (DestroyIcon, (impl->hicon_big));
2703 impl->hicon_big = big_hicon;
2704 if (impl->hicon_small)
2705 GDI_CALL (DestroyIcon, (impl->hicon_small));
2706 impl->hicon_small = small_hicon;
2710 gdk_window_set_icon (GdkWindow *window,
2711 GdkWindow *icon_window,
2715 g_return_if_fail (GDK_IS_WINDOW (window));
2717 /* do nothing, use gdk_window_set_icon_list instead */
2721 gdk_window_set_icon_name (GdkWindow *window,
2724 /* In case I manage to confuse this again (or somebody else does):
2725 * Please note that "icon name" here really *does* mean the name or
2726 * title of an window minimized as an icon on the desktop, or in the
2727 * taskbar. It has nothing to do with the freedesktop.org icon
2731 g_return_if_fail (GDK_IS_WINDOW (window));
2733 if (GDK_WINDOW_DESTROYED (window))
2737 /* This is not the correct thing to do. We should keep both the
2738 * "normal" window title, and the icon name. When the window is
2739 * minimized, call SetWindowText() with the icon name, and when the
2740 * window is restored, with the normal window title. Also, the name
2741 * is in UTF-8, so we should do the normal conversion to either wide
2742 * chars or system codepage, and use either the W or A version of
2743 * SetWindowText(), depending on Windows version.
2745 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2750 gdk_window_get_group (GdkWindow *window)
2752 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2753 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2755 if (GDK_WINDOW_DESTROYED (window))
2758 g_warning ("gdk_window_get_group not yet implemented");
2764 gdk_window_set_group (GdkWindow *window,
2767 g_return_if_fail (GDK_IS_WINDOW (window));
2768 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2769 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2771 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2774 g_warning ("gdk_window_set_group not implemented");
2778 update_single_bit (LONG *style,
2783 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2784 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2785 * bit indicate whether style_bit is on
2787 if ((!all && gdk_bit) || (all && !gdk_bit))
2788 *style |= style_bit;
2790 *style &= ~style_bit;
2794 update_style_bits (GdkWindow *window)
2796 GdkWindowObject *private = (GdkWindowObject *)window;
2797 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2798 GdkWMDecoration decorations;
2799 LONG old_style, new_style, old_exstyle, new_exstyle;
2801 RECT rect, before, after;
2803 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2804 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2806 GetClientRect (GDK_WINDOW_HWND (window), &before);
2808 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2810 new_style = old_style;
2811 new_exstyle = old_exstyle;
2813 if (private->window_type == GDK_WINDOW_TEMP ||
2814 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2815 new_exstyle |= WS_EX_TOOLWINDOW;
2817 new_exstyle &= ~WS_EX_TOOLWINDOW;
2819 if (get_effective_window_decorations (window, &decorations))
2821 all = (decorations & GDK_DECOR_ALL);
2822 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2823 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2824 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2825 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2826 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2827 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2830 if (old_style == new_style && old_exstyle == new_exstyle )
2832 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2833 GDK_WINDOW_HWND (window)));
2837 if (old_style != new_style)
2839 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2840 GDK_WINDOW_HWND (window),
2841 _gdk_win32_window_style_to_string (old_style),
2842 _gdk_win32_window_style_to_string (new_style)));
2844 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2847 if (old_exstyle != new_exstyle)
2849 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2850 GDK_WINDOW_HWND (window),
2851 _gdk_win32_window_exstyle_to_string (old_exstyle),
2852 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2854 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2857 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2859 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2860 rect.left += after.left - before.left;
2861 rect.top += after.top - before.top;
2862 rect.right += after.right - before.right;
2863 rect.bottom += after.bottom - before.bottom;
2865 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2866 rect.left, rect.top,
2867 rect.right - rect.left, rect.bottom - rect.top,
2868 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2869 SWP_NOREPOSITION | SWP_NOZORDER);
2874 update_single_system_menu_entry (HMENU hmenu,
2879 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2880 * gdk_bit indicates whether menu entry is disabled; if all is
2881 * FALSE, gdk bit indicate whether menu entry is enabled
2883 if ((!all && gdk_bit) || (all && !gdk_bit))
2884 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2886 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2890 update_system_menu (GdkWindow *window)
2892 GdkWMFunction functions;
2895 if (_gdk_window_get_functions (window, &functions))
2897 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2899 all = (functions & GDK_FUNC_ALL);
2900 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2901 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2902 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2903 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2904 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2909 get_decorations_quark ()
2911 static GQuark quark = 0;
2914 quark = g_quark_from_static_string ("gdk-window-decorations");
2920 gdk_window_set_decorations (GdkWindow *window,
2921 GdkWMDecoration decorations)
2923 GdkWMDecoration* decorations_copy;
2925 g_return_if_fail (GDK_IS_WINDOW (window));
2927 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2928 GDK_WINDOW_HWND (window),
2929 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2930 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2931 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2932 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2933 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2934 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2935 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2937 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2938 *decorations_copy = decorations;
2939 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2941 update_style_bits (window);
2945 gdk_window_get_decorations (GdkWindow *window,
2946 GdkWMDecoration *decorations)
2948 GdkWMDecoration* decorations_set;
2950 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2952 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2953 if (decorations_set)
2954 *decorations = *decorations_set;
2956 return (decorations_set != NULL);
2960 get_functions_quark ()
2962 static GQuark quark = 0;
2965 quark = g_quark_from_static_string ("gdk-window-functions");
2971 gdk_window_set_functions (GdkWindow *window,
2972 GdkWMFunction functions)
2974 GdkWMFunction* functions_copy;
2976 g_return_if_fail (GDK_IS_WINDOW (window));
2978 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2979 GDK_WINDOW_HWND (window),
2980 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2981 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2982 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2983 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2984 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2985 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2987 functions_copy = g_malloc (sizeof (GdkWMFunction));
2988 *functions_copy = functions;
2989 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2991 update_system_menu (window);
2995 _gdk_window_get_functions (GdkWindow *window,
2996 GdkWMFunction *functions)
2998 GdkWMDecoration* functions_set;
3000 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
3002 *functions = *functions_set;
3004 return (functions_set != NULL);
3008 QueryTree (HWND hwnd,
3018 child = GetWindow (hwnd, GW_CHILD);
3020 child = GetWindow (child, GW_HWNDNEXT);
3023 } while (child != NULL);
3027 *children = g_new (HWND, n);
3028 for (i = 0; i < n; i++)
3031 child = GetWindow (hwnd, GW_CHILD);
3033 child = GetWindow (child, GW_HWNDNEXT);
3034 *children[i] = child;
3040 gdk_propagate_shapes (HANDLE win,
3044 HRGN region, childRegion;
3048 SetRectEmpty (&emptyRect);
3049 region = CreateRectRgnIndirect (&emptyRect);
3051 GetWindowRgn (win, region);
3053 QueryTree (win, &list, &num);
3056 WINDOWPLACEMENT placement;
3058 placement.length = sizeof (WINDOWPLACEMENT);
3059 /* go through all child windows and combine regions */
3060 for (i = 0; i < num; i++)
3062 GetWindowPlacement (list[i], &placement);
3063 if (placement.showCmd == SW_SHOWNORMAL)
3065 childRegion = CreateRectRgnIndirect (&emptyRect);
3066 GetWindowRgn (list[i], childRegion);
3067 CombineRgn (region, region, childRegion, RGN_OR);
3068 DeleteObject (childRegion);
3071 SetWindowRgn (win, region, TRUE);
3075 DeleteObject (region);
3079 gdk_win32_window_set_child_shapes (GdkWindow *window)
3081 if (GDK_WINDOW_DESTROYED (window))
3084 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
3088 gdk_win32_window_merge_child_shapes (GdkWindow *window)
3090 if (GDK_WINDOW_DESTROYED (window))
3093 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
3098 gdk_window_set_child_input_shapes (GdkWindow *window)
3100 g_return_if_fail (GDK_IS_WINDOW (window));
3102 /* Not yet implemented. See comment in
3103 * gdk_window_input_shape_combine_mask().
3110 gdk_window_merge_child_input_shapes (GdkWindow *window)
3112 g_return_if_fail (GDK_IS_WINDOW (window));
3114 /* Not yet implemented. See comment in
3115 * gdk_window_input_shape_combine_mask().
3121 gdk_win32_window_set_static_gravities (GdkWindow *window,
3122 gboolean use_static)
3124 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3130 gdk_window_begin_resize_drag (GdkWindow *window,
3139 g_return_if_fail (GDK_IS_WINDOW (window));
3141 if (GDK_WINDOW_DESTROYED (window))
3144 /* Tell Windows to start interactively resizing the window by pretending that
3145 * the left pointer button was clicked in the suitable edge or corner. This
3146 * will only work if the button is down when this function is called, and
3147 * will only work with button 1 (left), since Windows only allows window
3148 * dragging using the left mouse button.
3153 /* Must break the automatic grab that occured when the button was
3154 * pressed, otherwise it won't work.
3156 gdk_display_pointer_ungrab (_gdk_display, 0);
3160 case GDK_WINDOW_EDGE_NORTH_WEST:
3161 winedge = HTTOPLEFT;
3164 case GDK_WINDOW_EDGE_NORTH:
3168 case GDK_WINDOW_EDGE_NORTH_EAST:
3169 winedge = HTTOPRIGHT;
3172 case GDK_WINDOW_EDGE_WEST:
3176 case GDK_WINDOW_EDGE_EAST:
3180 case GDK_WINDOW_EDGE_SOUTH_WEST:
3181 winedge = HTBOTTOMLEFT;
3184 case GDK_WINDOW_EDGE_SOUTH:
3188 case GDK_WINDOW_EDGE_SOUTH_EAST:
3190 winedge = HTBOTTOMRIGHT;
3194 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
3195 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3199 gdk_window_begin_move_drag (GdkWindow *window,
3205 g_return_if_fail (GDK_IS_WINDOW (window));
3207 if (GDK_WINDOW_DESTROYED (window))
3210 /* Tell Windows to start interactively moving the window by pretending that
3211 * the left pointer button was clicked in the titlebar. This will only work
3212 * if the button is down when this function is called, and will only work
3213 * with button 1 (left), since Windows only allows window dragging using the
3214 * left mouse button.
3219 /* Must break the automatic grab that occured when the button was pressed,
3220 * otherwise it won't work.
3222 gdk_display_pointer_ungrab (_gdk_display, 0);
3224 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
3225 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3230 * Setting window states
3233 gdk_window_iconify (GdkWindow *window)
3235 HWND old_active_window;
3237 g_return_if_fail (GDK_IS_WINDOW (window));
3239 if (GDK_WINDOW_DESTROYED (window))
3242 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
3243 GDK_WINDOW_HWND (window),
3244 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3246 if (GDK_WINDOW_IS_MAPPED (window))
3248 old_active_window = GetActiveWindow ();
3249 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
3250 if (old_active_window != GDK_WINDOW_HWND (window))
3251 SetActiveWindow (old_active_window);
3255 gdk_synthesize_window_state (window,
3257 GDK_WINDOW_STATE_ICONIFIED);
3262 gdk_window_deiconify (GdkWindow *window)
3264 g_return_if_fail (GDK_IS_WINDOW (window));
3266 if (GDK_WINDOW_DESTROYED (window))
3269 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
3270 GDK_WINDOW_HWND (window),
3271 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3273 if (GDK_WINDOW_IS_MAPPED (window))
3275 show_window_internal (window, FALSE, TRUE);
3279 gdk_synthesize_window_state (window,
3280 GDK_WINDOW_STATE_ICONIFIED,
3286 gdk_window_stick (GdkWindow *window)
3288 g_return_if_fail (GDK_IS_WINDOW (window));
3290 if (GDK_WINDOW_DESTROYED (window))
3293 /* FIXME: Do something? */
3297 gdk_window_unstick (GdkWindow *window)
3299 g_return_if_fail (GDK_IS_WINDOW (window));
3301 if (GDK_WINDOW_DESTROYED (window))
3304 /* FIXME: Do something? */
3308 gdk_window_maximize (GdkWindow *window)
3310 g_return_if_fail (GDK_IS_WINDOW (window));
3312 if (GDK_WINDOW_DESTROYED (window))
3315 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
3316 GDK_WINDOW_HWND (window),
3317 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3319 if (GDK_WINDOW_IS_MAPPED (window))
3320 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
3322 gdk_synthesize_window_state (window,
3324 GDK_WINDOW_STATE_MAXIMIZED);
3328 gdk_window_unmaximize (GdkWindow *window)
3330 g_return_if_fail (GDK_IS_WINDOW (window));
3332 if (GDK_WINDOW_DESTROYED (window))
3335 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
3336 GDK_WINDOW_HWND (window),
3337 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3339 if (GDK_WINDOW_IS_MAPPED (window))
3340 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
3342 gdk_synthesize_window_state (window,
3343 GDK_WINDOW_STATE_MAXIMIZED,
3347 typedef struct _FullscreenInfo FullscreenInfo;
3349 struct _FullscreenInfo
3357 gdk_window_fullscreen (GdkWindow *window)
3359 gint x, y, width, height;
3361 GdkWindowObject *private = (GdkWindowObject *) window;
3365 g_return_if_fail (GDK_IS_WINDOW (window));
3367 fi = g_new (FullscreenInfo, 1);
3369 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3373 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3375 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
3376 mi.cbSize = sizeof (mi);
3377 if (monitor && GetMonitorInfo (monitor, &mi))
3379 x = mi.rcMonitor.left;
3380 y = mi.rcMonitor.top;
3381 width = mi.rcMonitor.right - x;
3382 height = mi.rcMonitor.bottom - y;
3387 width = GetSystemMetrics (SM_CXSCREEN);
3388 height = GetSystemMetrics (SM_CYSCREEN);
3391 /* remember for restoring */
3392 fi->hint_flags = impl->hint_flags;
3393 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3394 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3395 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3397 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3398 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3400 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3401 x, y, width, height,
3402 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3404 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3409 gdk_window_unfullscreen (GdkWindow *window)
3412 GdkWindowObject *private = (GdkWindowObject *) window;
3414 g_return_if_fail (GDK_IS_WINDOW (window));
3416 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3419 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3421 impl->hint_flags = fi->hint_flags;
3422 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3423 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3424 fi->r.left, fi->r.top,
3425 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3426 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3428 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3431 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3436 gdk_window_set_keep_above (GdkWindow *window,
3439 g_return_if_fail (GDK_IS_WINDOW (window));
3441 if (GDK_WINDOW_DESTROYED (window))
3444 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3445 GDK_WINDOW_HWND (window),
3446 setting ? "YES" : "NO"));
3448 if (GDK_WINDOW_IS_MAPPED (window))
3450 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3451 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3453 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3456 gdk_synthesize_window_state (window,
3457 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3458 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3462 gdk_window_set_keep_below (GdkWindow *window,
3465 g_return_if_fail (GDK_IS_WINDOW (window));
3467 if (GDK_WINDOW_DESTROYED (window))
3470 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3471 GDK_WINDOW_HWND (window),
3472 setting ? "YES" : "NO"));
3474 if (GDK_WINDOW_IS_MAPPED (window))
3476 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3477 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3479 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3482 gdk_synthesize_window_state (window,
3483 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3484 setting ? GDK_WINDOW_STATE_BELOW : 0);
3488 gdk_window_focus (GdkWindow *window,
3491 g_return_if_fail (GDK_IS_WINDOW (window));
3493 if (GDK_WINDOW_DESTROYED (window))
3496 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3497 GDK_WINDOW_HWND (window),
3498 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3500 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3501 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3503 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3504 SetFocus (GDK_WINDOW_HWND (window));
3508 gdk_window_set_modal_hint (GdkWindow *window,
3511 GdkWindowObject *private;
3513 g_return_if_fail (GDK_IS_WINDOW (window));
3515 if (GDK_WINDOW_DESTROYED (window))
3518 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3519 GDK_WINDOW_HWND (window),
3520 modal ? "YES" : "NO"));
3522 private = (GdkWindowObject*) window;
3524 if (modal == private->modal_hint)
3527 private->modal_hint = modal;
3530 /* Not sure about this one.. -- Cody */
3531 if (GDK_WINDOW_IS_MAPPED (window))
3532 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3533 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3535 SWP_NOMOVE | SWP_NOSIZE));
3540 _gdk_push_modal_window (window);
3541 gdk_window_raise (window);
3545 _gdk_remove_modal_window (window);
3552 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3553 gboolean skips_taskbar)
3555 static GdkWindow *owner = NULL;
3558 g_return_if_fail (GDK_IS_WINDOW (window));
3560 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3561 GDK_WINDOW_HWND (window),
3562 skips_taskbar ? "YES" : "NO"));
3564 // ### TODO: Need to figure out what to do here.
3572 wa.window_type = GDK_WINDOW_TEMP;
3573 wa.wclass = GDK_INPUT_OUTPUT;
3574 wa.width = wa.height = 1;
3576 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3580 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3582 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3583 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3584 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3585 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3587 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3588 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3593 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3598 gdk_window_set_skip_pager_hint (GdkWindow *window,
3599 gboolean skips_pager)
3601 g_return_if_fail (GDK_IS_WINDOW (window));
3603 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3604 GDK_WINDOW_HWND (window),
3605 skips_pager ? "YES" : "NO"));
3609 gdk_window_set_type_hint (GdkWindow *window,
3610 GdkWindowTypeHint hint)
3612 g_return_if_fail (GDK_IS_WINDOW (window));
3614 if (GDK_WINDOW_DESTROYED (window))
3619 static GEnumClass *class = NULL;
3621 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3622 g_print ("gdk_window_set_type_hint: %p: %s\n",
3623 GDK_WINDOW_HWND (window),
3624 g_enum_get_value (class, hint)->value_name);
3627 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3629 update_style_bits (window);
3633 gdk_window_get_type_hint (GdkWindow *window)
3635 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3637 if (GDK_WINDOW_DESTROYED (window))
3638 return GDK_WINDOW_TYPE_HINT_NORMAL;
3640 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3644 gdk_win32_window_shape_combine_region (GdkWindow *window,
3645 const GdkRegion *shape_region,
3649 GdkWindowObject *private = (GdkWindowObject *)window;
3651 if (GDK_WINDOW_DESTROYED (window))
3656 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n",
3657 GDK_WINDOW_HWND (window)));
3658 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3660 private->shaped = FALSE;
3666 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3668 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: %p\n",
3669 GDK_WINDOW_HWND (window),
3672 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3674 private->shaped = TRUE;
3679 gdk_window_lookup_for_display (GdkDisplay *display,
3680 GdkNativeWindow anid)
3682 g_return_val_if_fail (display == _gdk_display, NULL);
3684 return gdk_window_lookup (anid);
3688 gdk_window_enable_synchronized_configure (GdkWindow *window)
3690 g_return_if_fail (GDK_IS_WINDOW (window));
3694 gdk_window_configure_finished (GdkWindow *window)
3696 g_return_if_fail (GDK_IS_WINDOW (window));
3700 gdk_window_beep (GdkWindow *window)
3702 gdk_display_beep (_gdk_display);
3706 gdk_window_set_opacity (GdkWindow *window,
3710 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3711 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3713 g_return_if_fail (GDK_IS_WINDOW (window));
3714 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3716 if (GDK_WINDOW_DESTROYED (window))
3721 else if (opacity > 1)
3724 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3726 if (!(exstyle & WS_EX_LAYERED))
3727 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3729 exstyle | WS_EX_LAYERED));
3731 setLayeredWindowAttributes =
3732 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3734 if (setLayeredWindowAttributes)
3736 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3744 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3751 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3756 _gdk_windowing_window_get_shape (GdkWindow *window)
3762 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3768 _gdk_win32_window_destroy (GdkWindow *window,
3770 gboolean foreign_destroy)
3775 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3778 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3780 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3781 GDK_WINDOW_HWND (window),
3782 _gdk_win32_gdkregion_to_string (area)));
3784 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3786 DeleteObject (hrgn);
3792 _gdk_win32_window_queue_translation (GdkWindow *window,
3797 g_print ("queue_translation\n");
3801 gdk_win32_input_shape_combine_region (GdkWindow *window,
3802 const GdkRegion *shape_region,
3809 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3812 _gdk_window_process_updates_recurse (window, region);
3816 _gdk_windowing_before_process_all_updates (void)
3821 _gdk_windowing_after_process_all_updates (void)
3826 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3828 iface->show = gdk_win32_window_show;
3829 iface->hide = gdk_win32_window_hide;
3830 iface->withdraw = gdk_win32_window_withdraw;
3831 iface->set_events = gdk_win32_window_set_events;
3832 iface->get_events = gdk_win32_window_get_events;
3833 iface->raise = gdk_win32_window_raise;
3834 iface->lower = gdk_win32_window_lower;
3835 iface->restack_under = gdk_win32_window_restack_under;
3836 iface->move_resize = gdk_win32_window_move_resize;
3837 iface->set_background = gdk_win32_window_set_background;
3838 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3839 iface->reparent = gdk_win32_window_reparent;
3840 iface->set_cursor = gdk_win32_window_set_cursor;
3841 iface->get_geometry = gdk_win32_window_get_geometry;
3842 iface->get_origin = gdk_win32_window_get_origin;
3843 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3844 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3845 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3846 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3847 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3848 iface->queue_translation = _gdk_win32_window_queue_translation;
3849 iface->destroy = _gdk_win32_window_destroy;