1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdk.h" /* gdk_rectangle_intersect */
31 #include "gdkevents.h"
32 #include "gdkpixmap.h"
33 #include "gdkwindow.h"
34 #include "gdkinternals.h"
35 #include "gdkprivate-win32.h"
36 #include "gdkinput-win32.h"
38 static gboolean gdk_window_gravity_works (void);
39 static void gdk_window_set_static_win_gravity (GdkWindow *window,
42 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
43 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
45 static void gdk_window_impl_win32_get_size (GdkDrawable *drawable,
48 static GdkRegion* gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
49 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
50 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
51 static void gdk_window_impl_win32_finalize (GObject *object);
53 static gpointer parent_class = NULL;
56 gdk_window_impl_win32_get_type (void)
58 static GType object_type = 0;
62 static const GTypeInfo object_info =
64 sizeof (GdkWindowImplWin32Class),
66 (GBaseFinalizeFunc) NULL,
67 (GClassInitFunc) gdk_window_impl_win32_class_init,
68 NULL, /* class_finalize */
69 NULL, /* class_data */
70 sizeof (GdkWindowImplWin32),
72 (GInstanceInitFunc) gdk_window_impl_win32_init,
75 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
84 _gdk_window_impl_get_type (void)
86 return gdk_window_impl_win32_get_type ();
90 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
98 impl->extension_events_selected = FALSE;
99 impl->input_locale = GetKeyboardLayout (0);
100 TranslateCharsetInfo ((DWORD FAR *) GetACP (), &impl->charset_info,
105 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
107 GObjectClass *object_class = G_OBJECT_CLASS (klass);
108 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
110 parent_class = g_type_class_peek_parent (klass);
112 object_class->finalize = gdk_window_impl_win32_finalize;
114 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
115 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
116 drawable_class->get_size = gdk_window_impl_win32_get_size;
118 /* Visible and clip regions are the same */
119 drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
120 drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
124 gdk_window_impl_win32_finalize (GObject *object)
126 GdkWindowObject *wrapper;
127 GdkDrawableImplWin32 *draw_impl;
128 GdkWindowImplWin32 *window_impl;
130 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
132 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
133 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
135 wrapper = (GdkWindowObject*) draw_impl->wrapper;
137 if (!GDK_WINDOW_DESTROYED (wrapper))
139 gdk_win32_handle_table_remove (draw_impl->handle);
142 if (window_impl->hcursor != NULL)
144 if (!DestroyCursor (window_impl->hcursor))
145 WIN32_GDI_FAILED("DestroyCursor");
146 window_impl->hcursor = NULL;
149 G_OBJECT_CLASS (parent_class)->finalize (object);
153 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
155 GdkDrawableImplWin32 *drawable_impl;
156 GdkWindowImplWin32 *window_impl;
158 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
160 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
161 window_impl = GDK_WINDOW_IMPL_WIN32 (drawable);
163 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
164 drawable_impl->colormap == NULL)
166 drawable_impl->colormap = gdk_colormap_get_system ();
167 gdk_colormap_ref (drawable_impl->colormap);
170 return drawable_impl->colormap;
174 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
177 GdkWindowImplWin32 *impl;
178 GdkDrawableImplWin32 *draw_impl;
180 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
181 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
183 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
184 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
186 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
189 g_print("gdk_window_impl_win32_set_colormap: XXX\n");
193 gdk_window_impl_win32_get_size (GdkDrawable *drawable,
197 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
200 *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
202 *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
206 gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
208 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
209 GdkRectangle result_rect;
213 result_rect.width = impl->width;
214 result_rect.height = impl->height;
216 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
218 return gdk_region_rectangle (&result_rect);
222 _gdk_windowing_window_init (void)
224 GdkWindowObject *private;
225 GdkWindowImplWin32 *impl;
226 GdkDrawableImplWin32 *draw_impl;
231 g_assert (gdk_parent_root == NULL);
233 SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
234 width = rect.right - rect.left;
235 height = rect.bottom - rect.top;
237 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
238 private = (GdkWindowObject *)gdk_parent_root;
239 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
240 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
242 draw_impl->handle = gdk_root_window;
243 draw_impl->wrapper = GDK_DRAWABLE (private);
245 private->window_type = GDK_WINDOW_ROOT;
246 private->depth = gdk_visual_get_system ()->depth;
248 impl->height = height;
250 gdk_win32_handle_table_insert (&gdk_root_window, gdk_parent_root);
253 /* The Win API function AdjustWindowRect may return negative values
254 * resulting in obscured title bars. This helper function is coreccting it.
257 SafeAdjustWindowRectEx (RECT* lpRect,
262 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
264 WIN32_API_FAILED ("AdjustWindowRectEx");
267 if (lpRect->left < 0)
269 lpRect->right -= lpRect->left;
274 lpRect->bottom -= lpRect->top;
281 * is a wrapper function for RegisterWindowClassEx.
282 * It creates at least one unique class for every
283 * GdkWindowType. If support for single window-specific icons
284 * is ever needed (e.g Dialog specific), every such window should
288 RegisterGdkClass (GdkWindowType wtype)
290 static ATOM klassTOPLEVEL = 0;
291 static ATOM klassDIALOG = 0;
292 static ATOM klassCHILD = 0;
293 static ATOM klassTEMP = 0;
294 static HICON hAppIcon = NULL;
295 static WNDCLASSEX wcl;
298 wcl.cbSize = sizeof(WNDCLASSEX);
299 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
300 * on WM_SIZE and WM_MOVE. Flicker, Performance!
302 wcl.lpfnWndProc = gdk_window_procedure;
305 wcl.hInstance = gdk_app_hmodule;
307 /* initialize once! */
310 gchar sLoc [_MAX_PATH+1];
312 if (0 != GetModuleFileName (gdk_app_hmodule, sLoc, _MAX_PATH))
314 hAppIcon = ExtractIcon (gdk_app_hmodule, sLoc, 0);
317 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
319 hAppIcon = ExtractIcon (gdk_app_hmodule, gdklibname, 0);
324 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
328 wcl.lpszMenuName = NULL;
331 /* initialize once per class */
332 #define ONCE_PER_CLASS() \
333 wcl.hIcon = CopyIcon (hAppIcon); \
334 wcl.hIconSm = CopyIcon (hAppIcon); \
335 wcl.hbrBackground = CreateSolidBrush (RGB (0,0,0)); \
336 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
340 case GDK_WINDOW_TOPLEVEL:
341 if (0 == klassTOPLEVEL)
343 wcl.lpszClassName = "gdkWindowToplevel";
346 klassTOPLEVEL = RegisterClassEx (&wcl);
348 klass = klassTOPLEVEL;
351 case GDK_WINDOW_CHILD:
354 wcl.lpszClassName = "gdkWindowChild";
356 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
358 klassCHILD = RegisterClassEx (&wcl);
363 case GDK_WINDOW_DIALOG:
364 if (0 == klassDIALOG)
366 wcl.lpszClassName = "gdkWindowDialog";
367 wcl.style |= CS_SAVEBITS;
369 klassDIALOG = RegisterClassEx (&wcl);
374 case GDK_WINDOW_TEMP:
377 wcl.lpszClassName = "gdkWindowTemp";
378 wcl.style |= CS_SAVEBITS;
380 klassTEMP = RegisterClassEx (&wcl);
386 g_assert_not_reached ();
392 WIN32_API_FAILED ("RegisterClassEx");
393 g_error ("That is a fatal error");
399 gdk_window_new (GdkWindow *parent,
400 GdkWindowAttr *attributes,
401 gint attributes_mask)
404 GdkWindowObject *private;
405 GdkWindowObject *parent_private;
406 GdkWindowImplWin32 *impl;
407 GdkDrawableImplWin32 *draw_impl;
413 DWORD dwStyle, dwExStyle;
422 g_return_val_if_fail (attributes != NULL, NULL);
425 parent = gdk_parent_root;
427 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
430 g_print ("gdk_window_new: %s\n",
431 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
432 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
433 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
434 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
437 parent_private = (GdkWindowObject*) parent;
438 if (GDK_WINDOW_DESTROYED (parent))
441 hparent = GDK_WINDOW_HWND (parent);
443 window = g_object_new (GDK_TYPE_WINDOW, NULL);
444 private = (GdkWindowObject *)window;
445 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
446 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
447 draw_impl->wrapper = GDK_DRAWABLE (window);
449 private->parent = (GdkWindowObject *)parent;
451 if (attributes_mask & GDK_WA_X)
456 if (attributes_mask & GDK_WA_Y)
458 else if (attributes_mask & GDK_WA_X)
459 y = 100; /* ??? We must put it somewhere... */
461 y = 0; /* x is CW_USEDEFAULT, y doesn't matter then */
465 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
466 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
467 impl->extension_events_selected = FALSE;
468 private->window_type = attributes->window_type;
470 _gdk_window_init_position (GDK_WINDOW (private));
471 if (impl->position_info.big)
472 private->guffaw_gravity = TRUE;
474 if (attributes_mask & GDK_WA_VISUAL)
475 visual = attributes->visual;
477 visual = gdk_visual_get_system ();
478 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
480 if (attributes_mask & GDK_WA_TITLE)
481 title = attributes->title;
483 title = g_get_prgname ();
484 if (!title || !*title)
485 title = "GDK client window";
487 impl->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
489 if (parent_private && parent_private->guffaw_gravity)
494 if (attributes->wclass == GDK_INPUT_OUTPUT)
498 private->input_only = FALSE;
499 private->depth = visual->depth;
501 if (attributes_mask & GDK_WA_COLORMAP)
503 draw_impl->colormap = attributes->colormap;
504 gdk_colormap_ref (attributes->colormap);
508 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
510 draw_impl->colormap = gdk_colormap_get_system ();
511 gdk_colormap_ref (draw_impl->colormap);
512 GDK_NOTE (MISC, g_print ("...using system colormap %p\n",
513 draw_impl->colormap));
517 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
518 GDK_NOTE (MISC, g_print ("...using new colormap %p\n",
519 draw_impl->colormap));
525 dwExStyle = WS_EX_TRANSPARENT;
527 private->input_only = TRUE;
528 draw_impl->colormap = NULL;
529 GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, NULL colormap\n"));
533 parent_private->children = g_list_prepend (parent_private->children, window);
535 switch (private->window_type)
537 case GDK_WINDOW_TOPLEVEL:
538 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
539 hparent = gdk_root_window;
542 case GDK_WINDOW_CHILD:
543 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
546 case GDK_WINDOW_DIALOG:
547 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
549 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
551 hparent = gdk_root_window;
554 case GDK_WINDOW_TEMP:
555 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
556 dwExStyle |= WS_EX_TOOLWINDOW;
559 case GDK_WINDOW_ROOT:
560 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
564 klass = RegisterGdkClass (private->window_type);
566 if (private->window_type != GDK_WINDOW_CHILD)
568 if (x == CW_USEDEFAULT)
579 rect.right = rect.left + impl->width;
580 rect.bottom = rect.top + impl->height;
582 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
584 if (x != CW_USEDEFAULT)
589 width = rect.right - rect.left;
590 height = rect.bottom - rect.top;
595 height = impl->height;
598 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
600 #ifdef WITHOUT_WM_CREATE
601 draw_impl->handle = CreateWindowEx (dwExStyle,
602 MAKEINTRESOURCE(klass),
614 CreateWindowEx (dwExStyle,
615 MAKEINTRESOURCE(klass),
624 if (GDK_WINDOW_HWND (window) != hwndNew)
626 g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%#x, %#x) HWND mismatch.",
627 (guint) GDK_WINDOW_HWND (window),
630 /* HB: IHMO due to a race condition the handle was increased by
631 * one, which causes much trouble. Because I can't find the
632 * real bug, try to workaround it ...
633 * To reproduce: compile with MSVC 5, DEBUG=1
636 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
637 GDK_WINDOW_HWND (window) = hwndNew;
638 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
640 /* the old behaviour, but with warning */
641 GDK_WINDOW_HWND (window) = hwndNew;
646 gdk_drawable_ref (window);
647 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
651 g_print ("... \"%s\" %dx%d@+%d+%d %#x = %#x\n"
652 "... locale %#x codepage %d\n",
654 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
656 (guint) GDK_WINDOW_HWND (window),
657 (guint) impl->input_locale,
658 (guint) impl->charset_info.ciACP));
662 if (draw_impl->handle == NULL)
664 WIN32_API_FAILED ("CreateWindowEx");
665 g_object_unref ((GObject *) window);
669 #ifdef WITHOUT_WM_CREATE
670 gdk_drawable_ref (window);
671 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
674 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
675 (attributes->cursor) :
682 gdk_window_foreign_new (GdkNativeWindow anid)
685 GdkWindowObject *private;
686 GdkWindowObject *parent_private;
687 GdkWindowImplWin32 *impl;
688 GdkDrawableImplWin32 *draw_impl;
694 window = g_object_new (GDK_TYPE_WINDOW, NULL);
695 private = (GdkWindowObject *)window;
696 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
697 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
698 draw_impl->wrapper = GDK_DRAWABLE (window);
699 parent = GetParent ((HWND)anid);
701 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
703 parent_private = (GdkWindowObject *)private->parent;
706 parent_private->children = g_list_prepend (parent_private->children, window);
708 draw_impl->handle = (HWND) anid;
709 GetClientRect ((HWND) anid, &rect);
711 point.y = rect.right;
712 ClientToScreen ((HWND) anid, &point);
713 if (parent != gdk_root_window)
714 ScreenToClient (parent, &point);
715 private->x = point.x;
716 private->y = point.y;
717 impl->width = rect.right - rect.left;
718 impl->height = rect.bottom - rect.top;
719 private->window_type = GDK_WINDOW_FOREIGN;
720 private->destroyed = FALSE;
721 private->mapped = IsWindowVisible ((HWND) anid);
722 private->depth = gdk_visual_get_system ()->depth;
724 gdk_drawable_ref (window);
725 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
731 _gdk_windowing_window_destroy (GdkWindow *window,
733 gboolean foreign_destroy)
735 GdkWindowObject *private = (GdkWindowObject *)window;
737 g_return_if_fail (GDK_IS_WINDOW (window));
739 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %#x\n",
740 (guint) GDK_WINDOW_HWND (window)));
742 if (private->extension_events != 0)
743 gdk_input_window_destroy (window);
745 if (private->window_type == GDK_WINDOW_FOREIGN)
747 if (!foreign_destroy && (private->parent != NULL))
749 /* It's somebody else's window, but in our hierarchy,
750 * so reparent it to the root window, and then call
751 * DestroyWindow() on it.
753 gdk_window_hide (window);
754 gdk_window_reparent (window, NULL, 0, 0);
756 /* Is this too drastic? Many (most?) applications
757 * quit if any window receives WM_QUIT I think.
758 * OTOH, I don't think foreign windows are much
759 * used, so the question is maybe academic.
761 PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
764 else if (!recursing && !foreign_destroy)
765 DestroyWindow (GDK_WINDOW_HWND (window));
768 /* This function is called when the window really gone.
771 gdk_window_destroy_notify (GdkWindow *window)
773 g_return_if_fail (window != NULL);
774 g_return_if_fail (GDK_IS_WINDOW (window));
777 g_print ("gdk_window_destroy_notify: %#x %s\n",
778 (guint) GDK_WINDOW_HWND (window),
779 (GDK_WINDOW_DESTROYED (window) ? "(destroyed)" : "")));
781 if (!GDK_WINDOW_DESTROYED (window))
783 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
784 g_warning ("window %#x unexpectedly destroyed",
785 (guint) GDK_WINDOW_HWND (window));
787 _gdk_window_destroy (window, TRUE);
790 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
791 gdk_drawable_unref (window);
795 gdk_window_show (GdkWindow *window)
797 GdkWindowObject *private;
799 g_return_if_fail (GDK_IS_WINDOW (window));
801 private = (GdkWindowObject*) window;
802 if (!private->destroyed)
804 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
805 (guint) GDK_WINDOW_HWND (window)));
807 private->mapped = TRUE;
808 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
810 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
811 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
812 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
814 /* Don't put on toolbar */
815 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
820 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
822 SetWindowPos(GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0,
823 SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE);
827 GdkWindow *parent = private->parent;
829 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
830 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
831 if (parent == gdk_parent_root)
832 SetForegroundWindow (GDK_WINDOW_HWND (window));
833 BringWindowToTop (GDK_WINDOW_HWND (window));
835 ShowOwnedPopups (GDK_WINDOW_HWND (window), TRUE);
843 gdk_window_hide (GdkWindow *window)
845 GdkWindowObject *private;
847 g_return_if_fail (window != NULL);
849 private = (GdkWindowObject*) window;
850 if (!private->destroyed)
852 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
853 (guint) GDK_WINDOW_HWND (window)));
855 private->mapped = FALSE;
856 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
857 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
859 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
861 SetWindowPos(GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
862 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
866 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
872 gdk_window_withdraw (GdkWindow *window)
874 GdkWindowObject *private;
876 g_return_if_fail (window != NULL);
878 private = (GdkWindowObject*) window;
879 if (!private->destroyed)
881 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
882 (guint) GDK_WINDOW_HWND (window)));
884 gdk_window_hide (window); /* ??? */
889 gdk_window_move (GdkWindow *window,
893 GdkWindowObject *private = (GdkWindowObject *)window;
894 GdkWindowImplWin32 *impl;
896 g_return_if_fail (window != NULL);
897 g_return_if_fail (GDK_IS_WINDOW (window));
899 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
901 gdk_window_move_resize (window, x, y, impl->width, impl->height);
905 gdk_window_resize (GdkWindow *window,
909 GdkWindowObject *private = (GdkWindowObject*) window;
910 GdkWindowImplWin32 *impl;
913 g_return_if_fail (window != NULL);
914 g_return_if_fail (GDK_IS_WINDOW (window));
921 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
923 if (!private->destroyed)
925 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
926 (guint) GDK_WINDOW_HWND (window),
929 if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
938 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
941 rect.right = pt.x + width;
942 rect.bottom = pt.y + height;
944 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
945 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
946 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
947 WIN32_API_FAILED ("AdjustWindowRectEx");
951 width = rect.right - rect.left;
952 height = rect.bottom - rect.top;
959 impl->height = height;
962 private->resize_count += 1;
964 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
965 (guint) GDK_WINDOW_HWND (window),
966 width, height, x, y));
967 if (!MoveWindow (GDK_WINDOW_HWND (window), x, y, width, height, TRUE))
968 WIN32_API_FAILED ("MoveWindow");
973 gdk_window_move_resize (GdkWindow *window,
979 GdkWindowObject *private = (GdkWindowObject*) window;
980 GdkWindowImplWin32 *impl;
982 g_return_if_fail (window != NULL);
983 g_return_if_fail (GDK_IS_WINDOW (window));
990 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
992 if (!private->destroyed)
998 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
999 (guint) GDK_WINDOW_HWND (window),
1000 width, height, x, y));
1002 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1003 _gdk_window_move_resize_child (window, x, y, width, height);
1008 rect.right = x + width;
1009 rect.bottom = y + height;
1011 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1012 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1013 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
1014 WIN32_API_FAILED ("AdjustWindowRectEx");
1016 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%ldx%ld@+%ld+%ld)\n",
1017 (guint) GDK_WINDOW_HWND (window),
1018 rect.right - rect.left, rect.bottom - rect.top,
1019 rect.left, rect.top));
1020 if (!MoveWindow (GDK_WINDOW_HWND (window),
1021 rect.left, rect.top,
1022 rect.right - rect.left, rect.bottom - rect.top,
1024 WIN32_API_FAILED ("MoveWindow");
1030 gdk_window_reparent (GdkWindow *window,
1031 GdkWindow *new_parent,
1035 GdkWindowObject *window_private;
1036 GdkWindowObject *parent_private;
1037 GdkWindowObject *old_parent_private;
1038 GdkWindowImplWin32 *impl;
1040 g_return_if_fail (window != NULL);
1043 new_parent = gdk_parent_root;
1045 window_private = (GdkWindowObject*) window;
1046 old_parent_private = (GdkWindowObject *) window_private->parent;
1047 parent_private = (GdkWindowObject*) new_parent;
1048 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1050 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1052 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1053 (guint) GDK_WINDOW_HWND (window),
1054 (guint) GDK_WINDOW_HWND (new_parent)));
1055 if (!SetParent (GDK_WINDOW_HWND (window),
1056 GDK_WINDOW_HWND (new_parent)))
1057 WIN32_API_FAILED ("SetParent");
1059 if (!MoveWindow (GDK_WINDOW_HWND (window),
1060 x, y, impl->width, impl->height, TRUE))
1061 WIN32_API_FAILED ("MoveWindow");
1064 window_private->parent = (GdkWindowObject *)new_parent;
1066 if (old_parent_private)
1067 old_parent_private->children =
1068 g_list_remove (old_parent_private->children, window);
1070 if ((old_parent_private &&
1071 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1072 (!old_parent_private && parent_private->guffaw_gravity))
1073 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1075 parent_private->children = g_list_prepend (parent_private->children, window);
1079 _gdk_windowing_window_clear_area (GdkWindow *window,
1085 GdkWindowImplWin32 *impl;
1087 g_return_if_fail (window != NULL);
1088 g_return_if_fail (GDK_IS_WINDOW (window));
1090 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1092 if (!GDK_WINDOW_DESTROYED (window))
1097 width = impl->width - x;
1099 height = impl->height - y;
1100 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: "
1101 "%#x %dx%d@+%d+%d\n",
1102 (guint) GDK_WINDOW_HWND (window),
1103 width, height, x, y));
1104 hdc = GetDC (GDK_WINDOW_HWND (window));
1105 IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
1106 SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1107 ReleaseDC (GDK_WINDOW_HWND (window), hdc);
1112 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1118 g_return_if_fail (window != NULL);
1119 g_return_if_fail (GDK_IS_WINDOW (window));
1121 if (!GDK_WINDOW_DESTROYED (window))
1125 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: "
1126 "%#x %dx%d@+%d+%d\n",
1127 (guint) GDK_WINDOW_HWND (window),
1128 width, height, x, y));
1131 rect.right = x + width + 1;
1133 rect.bottom = y + height + 1;
1134 if (!InvalidateRect (GDK_WINDOW_HWND (window), &rect, TRUE))
1135 WIN32_GDI_FAILED ("InvalidateRect");
1136 UpdateWindow (GDK_WINDOW_HWND (window));
1141 gdk_window_raise (GdkWindow *window)
1143 g_return_if_fail (window != NULL);
1144 g_return_if_fail (GDK_IS_WINDOW (window));
1146 if (!GDK_WINDOW_DESTROYED (window))
1148 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
1149 (guint) GDK_WINDOW_HWND (window)));
1151 if (!BringWindowToTop (GDK_WINDOW_HWND (window)))
1152 WIN32_API_FAILED ("BringWindowToTop");
1157 gdk_window_lower (GdkWindow *window)
1159 g_return_if_fail (window != NULL);
1160 g_return_if_fail (GDK_IS_WINDOW (window));
1162 if (!GDK_WINDOW_DESTROYED (window))
1164 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1165 (guint) GDK_WINDOW_HWND (window)));
1167 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1168 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1169 WIN32_API_FAILED ("SetWindowPos");
1174 gdk_window_set_hints (GdkWindow *window,
1183 GdkWindowImplWin32 *impl;
1184 WINDOWPLACEMENT size_hints;
1190 g_return_if_fail (window != NULL);
1191 g_return_if_fail (GDK_IS_WINDOW (window));
1193 if (GDK_WINDOW_DESTROYED (window))
1196 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1198 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1199 (guint) GDK_WINDOW_HWND (window),
1200 min_width, min_height, max_width, max_height,
1203 impl->hint_flags = flags;
1204 size_hints.length = sizeof (size_hints);
1208 if (flags & GDK_HINT_POS)
1210 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1211 WIN32_API_FAILED ("GetWindowPlacement");
1214 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1215 " (%ld,%ld)--(%ld,%ld)\n",
1216 size_hints.rcNormalPosition.left,
1217 size_hints.rcNormalPosition.top,
1218 size_hints.rcNormalPosition.right,
1219 size_hints.rcNormalPosition.bottom));
1220 /* What are the corresponding window coordinates for client
1221 * area coordinates x, y
1225 rect.right = rect.left + 200; /* dummy */
1226 rect.bottom = rect.top + 200;
1227 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1228 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1229 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1230 size_hints.flags = 0;
1231 size_hints.showCmd = SW_SHOWNA;
1233 /* Set the normal position hint to that location, with unchanged
1236 diff = size_hints.rcNormalPosition.left - rect.left;
1237 size_hints.rcNormalPosition.left = rect.left;
1238 size_hints.rcNormalPosition.right -= diff;
1239 diff = size_hints.rcNormalPosition.top - rect.top;
1240 size_hints.rcNormalPosition.top = rect.top;
1241 size_hints.rcNormalPosition.bottom -= diff;
1242 GDK_NOTE (MISC, g_print ("...setting: (%ld,%ld)--(%ld,%ld)\n",
1243 size_hints.rcNormalPosition.left,
1244 size_hints.rcNormalPosition.top,
1245 size_hints.rcNormalPosition.right,
1246 size_hints.rcNormalPosition.bottom));
1247 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1248 WIN32_API_FAILED ("SetWindowPlacement");
1249 impl->hint_x = rect.left;
1250 impl->hint_y = rect.top;
1254 if (flags & GDK_HINT_MIN_SIZE)
1258 rect.right = min_width;
1259 rect.bottom = min_height;
1260 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1261 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1262 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1263 impl->hint_min_width = rect.right - rect.left;
1264 impl->hint_min_height = rect.bottom - rect.top;
1266 /* Also chek if he current size of the window is in bounds. */
1267 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1268 if (rect.right < min_width && rect.bottom < min_height)
1269 gdk_window_resize (window, min_width, min_height);
1270 else if (rect.right < min_width)
1271 gdk_window_resize (window, min_width, rect.bottom);
1272 else if (rect.bottom < min_height)
1273 gdk_window_resize (window, rect.right, min_height);
1276 if (flags & GDK_HINT_MAX_SIZE)
1280 rect.right = max_width;
1281 rect.bottom = max_height;
1282 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1283 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1284 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1285 impl->hint_max_width = rect.right - rect.left;
1286 impl->hint_max_height = rect.bottom - rect.top;
1287 /* Again, check if the window is too large currently. */
1288 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1289 if (rect.right > max_width && rect.bottom > max_height)
1290 gdk_window_resize (window, max_width, max_height);
1291 else if (rect.right > max_width)
1292 gdk_window_resize (window, max_width, rect.bottom);
1293 else if (rect.bottom > max_height)
1294 gdk_window_resize (window, rect.right, max_height);
1300 gdk_window_set_geometry_hints (GdkWindow *window,
1301 GdkGeometry *geometry,
1302 GdkWindowHints geom_mask)
1304 GdkWindowImplWin32 *impl;
1305 WINDOWPLACEMENT size_hints;
1310 g_return_if_fail (window != NULL);
1311 g_return_if_fail (GDK_IS_WINDOW (window));
1313 if (GDK_WINDOW_DESTROYED (window))
1316 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1317 size_hints.length = sizeof (size_hints);
1319 impl->hint_flags = geom_mask;
1321 if (geom_mask & GDK_HINT_POS)
1324 if (geom_mask & GDK_HINT_MIN_SIZE)
1328 rect.right = geometry->min_width;
1329 rect.bottom = geometry->min_height;
1330 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1331 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1332 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1333 impl->hint_min_width = rect.right - rect.left;
1334 impl->hint_min_height = rect.bottom - rect.top;
1336 /* Also check if he current size of the window is in bounds */
1337 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1338 if (rect.right < geometry->min_width
1339 && rect.bottom < geometry->min_height)
1340 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1341 else if (rect.right < geometry->min_width)
1342 gdk_window_resize (window, geometry->min_width, rect.bottom);
1343 else if (rect.bottom < geometry->min_height)
1344 gdk_window_resize (window, rect.right, geometry->min_height);
1347 if (geom_mask & GDK_HINT_MAX_SIZE)
1351 rect.right = geometry->max_width;
1352 rect.bottom = geometry->max_height;
1353 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1354 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1355 /* HB: dont' know why AdjustWindowRectEx is called here, ... */
1356 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1357 impl->hint_max_width = rect.right - rect.left;
1358 impl->hint_max_height = rect.bottom - rect.top;
1359 /* ... but negative sizes are always wrong */
1360 if (impl->hint_max_width < 0) impl->hint_max_width = G_MAXSHORT;
1361 if (impl->hint_max_height < 0) impl->hint_max_height = G_MAXSHORT;
1363 /* Again, check if the window is too large currently. */
1364 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1365 if (rect.right > geometry->max_width
1366 && rect.bottom > geometry->max_height)
1367 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1368 else if (rect.right > geometry->max_width)
1369 gdk_window_resize (window, geometry->max_width, rect.bottom);
1370 else if (rect.bottom > geometry->max_height)
1371 gdk_window_resize (window, rect.right, geometry->max_height);
1374 /* I don't know what to do when called with zero base_width and height. */
1375 if (geom_mask & GDK_HINT_BASE_SIZE
1376 && geometry->base_width > 0
1377 && geometry->base_height > 0)
1379 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1380 WIN32_API_FAILED ("GetWindowPlacement");
1383 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1384 " rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
1385 size_hints.rcNormalPosition.left,
1386 size_hints.rcNormalPosition.top,
1387 size_hints.rcNormalPosition.right,
1388 size_hints.rcNormalPosition.bottom));
1389 size_hints.rcNormalPosition.right =
1390 size_hints.rcNormalPosition.left + geometry->base_width;
1391 size_hints.rcNormalPosition.bottom =
1392 size_hints.rcNormalPosition.top + geometry->base_height;
1393 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%ld,%ld)--(%ld,%ld)\n",
1394 size_hints.rcNormalPosition.left,
1395 size_hints.rcNormalPosition.top,
1396 size_hints.rcNormalPosition.right,
1397 size_hints.rcNormalPosition.bottom));
1398 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1399 WIN32_API_FAILED ("SetWindowPlacement");
1403 if (geom_mask & GDK_HINT_RESIZE_INC)
1408 if (geom_mask & GDK_HINT_ASPECT)
1415 gdk_window_set_title (GdkWindow *window,
1420 g_return_if_fail (window != NULL);
1421 g_return_if_fail (GDK_IS_WINDOW (window));
1422 g_return_if_fail (title != NULL);
1424 /* Empty window titles not allowed, so set it to just a period. */
1428 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1429 (guint) GDK_WINDOW_HWND (window), title));
1431 if (!GDK_WINDOW_DESTROYED (window))
1433 /* As the title is in UTF-8 we must translate it
1434 * to the system codepage.
1436 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
1437 if (!SetWindowText (GDK_WINDOW_HWND (window), mbtitle))
1438 WIN32_API_FAILED ("SetWindowText");
1445 gdk_window_set_role (GdkWindow *window,
1448 g_return_if_fail (window != NULL);
1449 g_return_if_fail (GDK_IS_WINDOW (window));
1451 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1452 (guint) GDK_WINDOW_HWND (window),
1453 (role ? role : "NULL")));
1458 gdk_window_set_transient_for (GdkWindow *window,
1461 g_return_if_fail (window != NULL);
1462 g_return_if_fail (GDK_IS_WINDOW (window));
1464 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1465 (guint) GDK_WINDOW_HWND (window),
1466 (guint) GDK_WINDOW_HWND (parent)));
1471 gdk_window_set_background (GdkWindow *window,
1474 GdkWindowObject *private = (GdkWindowObject *)window;
1476 g_return_if_fail (window != NULL);
1477 g_return_if_fail (GDK_IS_WINDOW (window));
1479 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1480 (guint) GDK_WINDOW_HWND (window),
1481 gdk_win32_color_to_string (color)));
1483 private->bg_color = *color;
1485 if (private->bg_pixmap &&
1486 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1487 private->bg_pixmap != GDK_NO_BG)
1489 gdk_drawable_unref (private->bg_pixmap);
1490 private->bg_pixmap = NULL;
1495 gdk_window_set_back_pixmap (GdkWindow *window,
1497 gint parent_relative)
1499 GdkWindowObject *private = (GdkWindowObject *)window;
1501 g_return_if_fail (window != NULL);
1502 g_return_if_fail (GDK_IS_WINDOW (window));
1503 g_return_if_fail (pixmap == NULL || !parent_relative);
1505 if (private->bg_pixmap &&
1506 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1507 private->bg_pixmap != GDK_NO_BG)
1508 gdk_drawable_unref (private->bg_pixmap);
1510 if (parent_relative)
1512 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1518 gdk_drawable_ref (pixmap);
1519 private->bg_pixmap = pixmap;
1523 private->bg_pixmap = GDK_NO_BG;
1529 gdk_window_set_cursor (GdkWindow *window,
1532 GdkWindowImplWin32 *impl;
1533 GdkCursorPrivate *cursor_private;
1535 HCURSOR hprevcursor;
1538 g_return_if_fail (window != NULL);
1539 g_return_if_fail (GDK_IS_WINDOW (window));
1541 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1542 cursor_private = (GdkCursorPrivate*) cursor;
1544 if (!GDK_WINDOW_DESTROYED (window))
1549 hcursor = cursor_private->hcursor;
1551 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1552 (guint) GDK_WINDOW_HWND (window),
1554 hprevcursor = impl->hcursor;
1555 if (hcursor == NULL)
1556 impl->hcursor = NULL;
1559 /* We must copy the cursor as it is OK to destroy the GdkCursor
1560 * while still in use for some window. See for instance
1561 * gimp_change_win_cursor() which calls
1562 * gdk_window_set_cursor (win, cursor), and immediately
1563 * afterwards gdk_cursor_destroy (cursor).
1565 impl->hcursor = CopyCursor (hcursor);
1566 GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
1567 (guint) hcursor, (guint) impl->hcursor));
1570 if (ChildWindowFromPoint (GDK_WINDOW_HWND (window), pt) == GDK_WINDOW_HWND (window))
1571 SetCursor (impl->hcursor);
1573 if (hprevcursor != NULL)
1575 GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n",
1576 (guint) hprevcursor));
1578 if (!DestroyCursor (hprevcursor))
1579 WIN32_API_FAILED ("DestroyCursor");
1580 impl->hcursor = NULL;
1587 gdk_window_get_geometry (GdkWindow *window,
1594 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1597 window = gdk_parent_root;
1599 if (!GDK_WINDOW_DESTROYED (window))
1603 if (!GetClientRect (GDK_WINDOW_HWND (window), &rect))
1604 WIN32_API_FAILED ("GetClientRect");
1611 *width = rect.right - rect.left;
1613 *height = rect.bottom - rect.top;
1615 *depth = gdk_drawable_get_visual (window)->depth;
1620 gdk_window_get_origin (GdkWindow *window,
1628 g_return_val_if_fail (window != NULL, 0);
1630 if (!GDK_WINDOW_DESTROYED (window))
1636 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1649 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1650 (guint) GDK_WINDOW_HWND (window),
1656 gdk_window_get_deskrelative_origin (GdkWindow *window,
1660 return gdk_window_get_origin (window, x, y);
1664 gdk_window_get_root_origin (GdkWindow *window,
1668 GdkWindowObject *rover;
1671 g_return_if_fail (window != NULL);
1672 g_return_if_fail (GDK_IS_WINDOW (window));
1674 rover = (GdkWindowObject*) window;
1680 if (GDK_WINDOW_DESTROYED (window))
1683 while (rover->parent && ((GdkWindowObject*) rover->parent)->parent)
1684 rover = (GdkWindowObject *) rover->parent;
1685 if (rover->destroyed)
1690 ClientToScreen (GDK_WINDOW_HWND (rover), &pt);
1696 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%ld+%ld\n",
1697 (guint) GDK_WINDOW_HWND (window),
1698 (guint) GDK_WINDOW_HWND (rover),
1703 gdk_window_get_pointer (GdkWindow *window,
1706 GdkModifierType *mask)
1708 GdkWindow *return_val;
1709 POINT pointc, point;
1712 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1715 window = gdk_parent_root;
1718 GetCursorPos (&pointc);
1720 ScreenToClient (GDK_WINDOW_HWND (window), &point);
1727 hwnd = WindowFromPoint (point);
1729 ScreenToClient (hwnd, &point);
1732 hwndc = ChildWindowFromPoint (hwnd, point);
1733 ClientToScreen (hwnd, &point);
1734 ScreenToClient (hwndc, &point);
1735 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1737 return_val = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1743 GetKeyboardState (kbd);
1745 if (kbd[VK_SHIFT] & 0x80)
1746 *mask |= GDK_SHIFT_MASK;
1747 if (kbd[VK_CAPITAL] & 0x80)
1748 *mask |= GDK_LOCK_MASK;
1749 if (kbd[VK_CONTROL] & 0x80)
1750 *mask |= GDK_CONTROL_MASK;
1751 if (kbd[VK_MENU] & 0x80)
1752 *mask |= GDK_MOD1_MASK;
1753 if (kbd[VK_LBUTTON] & 0x80)
1754 *mask |= GDK_BUTTON1_MASK;
1755 if (kbd[VK_MBUTTON] & 0x80)
1756 *mask |= GDK_BUTTON2_MASK;
1757 if (kbd[VK_RBUTTON] & 0x80)
1758 *mask |= GDK_BUTTON3_MASK;
1765 gdk_window_at_pointer (gint *win_x,
1769 POINT point, pointc;
1773 GetCursorPos (&pointc);
1775 hwnd = WindowFromPoint (point);
1779 window = gdk_parent_root;
1787 ScreenToClient (hwnd, &point);
1790 hwndc = ChildWindowFromPoint (hwnd, point);
1791 ClientToScreen (hwnd, &point);
1792 ScreenToClient (hwndc, &point);
1793 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1795 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1797 if (window && (win_x || win_y))
1799 GetClientRect (hwnd, &rect);
1801 *win_x = point.x - rect.left;
1803 *win_y = point.y - rect.top;
1806 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%ld+%ld %#x%s\n",
1809 (window == NULL ? " NULL" : "")));
1815 gdk_window_get_events (GdkWindow *window)
1817 g_return_val_if_fail (window != NULL, 0);
1818 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1820 if (GDK_WINDOW_DESTROYED (window))
1823 return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask;
1827 gdk_window_set_events (GdkWindow *window,
1828 GdkEventMask event_mask)
1830 g_return_if_fail (window != NULL);
1831 g_return_if_fail (GDK_IS_WINDOW (window));
1833 if (GDK_WINDOW_DESTROYED (window))
1836 GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask = event_mask;
1840 gdk_window_shape_combine_mask (GdkWindow *window,
1844 g_return_if_fail (window != NULL);
1845 g_return_if_fail (GDK_IS_WINDOW (window));
1849 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1850 (guint) GDK_WINDOW_HWND (window)));
1851 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
1860 /* Convert mask bitmap to region */
1861 hrgn = BitmapToRegion (GDK_WINDOW_HWND (mask));
1863 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1864 (guint) GDK_WINDOW_HWND (window),
1865 (guint) GDK_WINDOW_HWND (mask)));
1867 /* SetWindowRgn wants window (not client) coordinates */
1868 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1869 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1870 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1871 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1872 OffsetRgn (hrgn, -rect.left, -rect.top);
1874 OffsetRgn (hrgn, x, y);
1876 /* If this is a top-level window, add the title bar to the region */
1877 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1879 CombineRgn (hrgn, hrgn,
1880 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1884 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
1889 gdk_window_set_override_redirect (GdkWindow *window,
1890 gboolean override_redirect)
1892 g_return_if_fail (window != NULL);
1893 g_return_if_fail (GDK_IS_WINDOW (window));
1895 g_warning ("gdk_window_set_override_redirect not implemented");
1899 gdk_window_set_icon (GdkWindow *window,
1900 GdkWindow *icon_window,
1904 g_return_if_fail (window != NULL);
1905 g_return_if_fail (GDK_IS_WINDOW (window));
1907 if (GDK_WINDOW_DESTROYED (window))
1910 /* Nothing to do, really. As we share window classes between windows
1911 * we can't have window-specific icons, sorry. Don't print any warning
1917 gdk_window_set_icon_name (GdkWindow *window,
1920 g_return_if_fail (window != NULL);
1921 g_return_if_fail (GDK_IS_WINDOW (window));
1923 if (GDK_WINDOW_DESTROYED (window))
1926 if (!SetWindowText (GDK_WINDOW_HWND (window), name))
1927 WIN32_API_FAILED ("SetWindowText");
1931 gdk_window_set_group (GdkWindow *window,
1934 g_return_if_fail (window != NULL);
1935 g_return_if_fail (GDK_IS_WINDOW (window));
1936 g_return_if_fail (leader != NULL);
1937 g_return_if_fail (GDK_IS_WINDOW (leader));
1939 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1942 g_warning ("gdk_window_set_group not implemented");
1946 gdk_window_set_decorations (GdkWindow *window,
1947 GdkWMDecoration decorations)
1949 LONG style, exstyle;
1951 g_return_if_fail (window != NULL);
1952 g_return_if_fail (GDK_IS_WINDOW (window));
1954 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1955 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1957 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1958 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
1960 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1962 if (decorations & GDK_DECOR_ALL)
1963 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
1964 if (decorations & GDK_DECOR_BORDER)
1965 style |= (WS_BORDER);
1966 if (decorations & GDK_DECOR_RESIZEH)
1967 style |= (WS_THICKFRAME);
1968 if (decorations & GDK_DECOR_TITLE)
1969 style |= (WS_CAPTION);
1970 if (decorations & GDK_DECOR_MENU)
1971 style |= (WS_SYSMENU);
1972 if (decorations & GDK_DECOR_MINIMIZE)
1973 style |= (WS_MINIMIZEBOX);
1974 if (decorations & GDK_DECOR_MAXIMIZE)
1975 style |= (WS_MAXIMIZEBOX);
1977 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1981 gdk_window_set_functions (GdkWindow *window,
1982 GdkWMFunction functions)
1984 LONG style, exstyle;
1986 g_return_if_fail (window != NULL);
1987 g_return_if_fail (GDK_IS_WINDOW (window));
1989 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1990 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1992 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1993 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
1996 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1998 if (functions & GDK_FUNC_ALL)
1999 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2000 if (functions & GDK_FUNC_RESIZE)
2001 style |= (WS_THICKFRAME);
2002 if (functions & GDK_FUNC_MOVE)
2003 style |= (WS_THICKFRAME);
2004 if (functions & GDK_FUNC_MINIMIZE)
2005 style |= (WS_MINIMIZEBOX);
2006 if (functions & GDK_FUNC_MAXIMIZE)
2007 style |= (WS_MAXIMIZEBOX);
2009 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2013 * propagate the shapes from all child windows of a GDK window to the parent
2014 * window. Shamelessly ripped from Enlightenment's code
2020 QueryTree (HWND hwnd,
2030 child = GetWindow (hwnd, GW_CHILD);
2032 child = GetWindow (child, GW_HWNDNEXT);
2035 } while (child != NULL);
2039 *children = g_new (HWND, n);
2040 for (i = 0; i < n; i++)
2043 child = GetWindow (hwnd, GW_CHILD);
2045 child = GetWindow (child, GW_HWNDNEXT);
2046 *children[i] = child;
2052 gdk_propagate_shapes (HANDLE win,
2056 HRGN region, childRegion;
2060 SetRectEmpty (&emptyRect);
2061 region = CreateRectRgnIndirect (&emptyRect);
2063 GetWindowRgn (win, region);
2065 QueryTree (win, &list, &num);
2068 WINDOWPLACEMENT placement;
2070 placement.length = sizeof (WINDOWPLACEMENT);
2071 /* go through all child windows and combine regions */
2072 for (i = 0; i < num; i++)
2074 GetWindowPlacement (list[i], &placement);
2075 if (placement.showCmd == SW_SHOWNORMAL)
2077 childRegion = CreateRectRgnIndirect (&emptyRect);
2078 GetWindowRgn (list[i], childRegion);
2079 CombineRgn (region, region, childRegion, RGN_OR);
2080 DeleteObject (childRegion);
2083 SetWindowRgn (win, region, TRUE);
2086 DeleteObject (region);
2090 gdk_window_set_child_shapes (GdkWindow *window)
2092 g_return_if_fail (window != NULL);
2093 g_return_if_fail (GDK_IS_WINDOW (window));
2095 if (GDK_WINDOW_DESTROYED (window))
2098 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2102 gdk_window_merge_child_shapes (GdkWindow *window)
2104 g_return_if_fail (window != NULL);
2105 g_return_if_fail (GDK_IS_WINDOW (window));
2107 if (GDK_WINDOW_DESTROYED (window))
2110 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2113 /* Support for windows that can be guffaw-scrolled
2114 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2118 gdk_window_gravity_works (void)
2120 enum { UNKNOWN, NO, YES };
2121 static gint gravity_works = UNKNOWN;
2123 if (gravity_works == UNKNOWN)
2130 attr.window_type = GDK_WINDOW_TEMP;
2131 attr.wclass = GDK_INPUT_OUTPUT;
2136 attr.event_mask = 0;
2138 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2140 attr.window_type = GDK_WINDOW_CHILD;
2141 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2143 gdk_window_set_static_win_gravity (child, TRUE);
2145 gdk_window_resize (parent, 100, 110);
2146 gdk_window_move (parent, 0, -10);
2147 gdk_window_move_resize (parent, 0, 0, 100, 100);
2149 gdk_window_resize (parent, 100, 110);
2150 gdk_window_move (parent, 0, -10);
2151 gdk_window_move_resize (parent, 0, 0, 100, 100);
2153 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2155 gdk_window_destroy (parent);
2156 gdk_window_destroy (child);
2158 gravity_works = ((y == -20) ? YES : NO);
2161 return (gravity_works == YES);
2165 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2167 g_return_if_fail (window != NULL);
2169 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2173 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2175 g_return_if_fail (window != NULL);
2178 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2181 /*************************************************************
2182 * gdk_window_set_static_gravities:
2183 * Set the bit gravity of the given window to static,
2184 * and flag it so all children get static subwindow
2187 * window: window for which to set static gravity
2188 * use_static: Whether to turn static gravity on or off.
2190 * Does the XServer support static gravity?
2191 *************************************************************/
2194 gdk_window_set_static_gravities (GdkWindow *window,
2195 gboolean use_static)
2197 GdkWindowObject *private = (GdkWindowObject *)window;
2200 g_return_val_if_fail (window != NULL, FALSE);
2201 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2203 if (!use_static == !private->guffaw_gravity)
2206 if (use_static && !gdk_window_gravity_works ())
2209 private->guffaw_gravity = use_static;
2211 if (!GDK_WINDOW_DESTROYED (window))
2213 gdk_window_set_static_bit_gravity (window, use_static);
2215 tmp_list = private->children;
2218 gdk_window_set_static_win_gravity (window, use_static);
2220 tmp_list = tmp_list->next;