summaryrefslogtreecommitdiff
path: root/gdk/win32/gdkwindow-win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/win32/gdkwindow-win32.c')
-rw-r--r--gdk/win32/gdkwindow-win32.c2560
1 files changed, 2560 insertions, 0 deletions
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
new file mode 100644
index 000000000..02bbace8f
--- /dev/null
+++ b/gdk/win32/gdkwindow-win32.c
@@ -0,0 +1,2560 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1998-1999 Tor Lillqvist
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gdk.h"
+#include "gdkprivate.h"
+#include "gdkinput.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* The Win API function AdjustWindowRect may return negative values
+ * resulting in obscured title bars. This helper function is coreccting it.
+ */
+BOOL AdjustWindowRectEx2(RECT* lpRect,
+ DWORD dwStyle,
+ BOOL bMenu,
+ DWORD dwExStyle)
+{
+ if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
+ return FALSE;
+ if (lpRect->left < 0)
+ {
+ lpRect->right -= lpRect->left;
+ lpRect->left = 0;
+ }
+ if (lpRect->top < 0)
+ {
+ lpRect->bottom -= lpRect->top;
+ lpRect->top = 0;
+ }
+ return TRUE;
+}
+/* HB: now use it */
+#define AdjustWindowRectEx AdjustWindowRectEx2
+
+/* Forward declarations */
+static gboolean gdk_window_gravity_works (void);
+static void gdk_window_set_static_win_gravity (GdkWindow *window,
+ gboolean on);
+
+/*
+ * The following fucntion by The Rasterman <raster@redhat.com>
+ * This function returns the X Window ID in which the x y location is in
+ * (x and y being relative to the root window), excluding any windows listed
+ * in the GList excludes (this is a list of X Window ID's - gpointer being
+ * the Window ID).
+ *
+ * This is primarily designed for internal gdk use - for DND for example
+ * when using a shaped icon window as the drag object - you exclude the
+ * X Window ID of the "icon" (perhaps more if excludes may be needed) and
+ * You can get back an X Window ID as to what X Window ID is infact under
+ * those X,Y co-ordinates.
+ */
+HWND
+gdk_window_xid_at_coords (gint x,
+ gint y,
+ GList *excludes,
+ gboolean excl_child)
+{
+ POINT pt;
+ gboolean warned = FALSE;
+
+ pt.x = x;
+ pt.y = y;
+ /* This is probably not correct, just a quick hack */
+
+ if (!warned)
+ {
+ g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
+ warned = TRUE;
+ }
+
+ /* XXX */
+ return WindowFromPoint (pt);
+}
+
+void
+gdk_window_init (void)
+{
+ unsigned int width;
+ unsigned int height;
+#if 0
+ width = GetSystemMetrics (SM_CXSCREEN);
+ height = GetSystemMetrics (SM_CYSCREEN);
+#else
+ { RECT r; /* //HB: don't obscure tray window (task bar) */
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+ width = r.right - r.left;
+ height = r.bottom - r.top;
+ }
+#endif
+
+ gdk_root_parent.xwindow = gdk_root_window;
+ gdk_root_parent.window_type = GDK_WINDOW_ROOT;
+ gdk_root_parent.window.user_data = NULL;
+ gdk_root_parent.width = width;
+ gdk_root_parent.height = height;
+ gdk_root_parent.children = NULL;
+ gdk_root_parent.colormap = NULL;
+ gdk_root_parent.ref_count = 1;
+
+ gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
+}
+
+GdkWindow*
+gdk_window_new (GdkWindow *parent,
+ GdkWindowAttr *attributes,
+ gint attributes_mask)
+{
+ GdkWindow *window;
+ GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
+ GdkVisual *visual;
+ HANDLE xparent;
+ Visual *xvisual;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ WNDCLASSEX wcl;
+ ATOM klass;
+ char wcl_name_buf[20];
+ static int wcl_cnt = 0;
+#else
+ static WNDCLASSEX wcl;
+ static ATOM klass = 0;
+#endif
+ static HICON hAppIcon = NULL;
+ DWORD dwStyle, dwExStyle;
+ RECT rect;
+ int width, height;
+ int x, y;
+ char *title;
+
+ g_return_val_if_fail (attributes != NULL, NULL);
+
+ if (!parent)
+ parent = (GdkWindow*) &gdk_root_parent;
+
+ parent_private = (GdkWindowPrivate*) parent;
+ if (parent_private->destroyed)
+ return NULL;
+
+ xparent = parent_private->xwindow;
+
+ private = g_new (GdkWindowPrivate, 1);
+ window = (GdkWindow*) private;
+
+ private->parent = parent;
+
+ private->destroyed = FALSE;
+ private->mapped = FALSE;
+ private->guffaw_gravity = FALSE;
+ private->resize_count = 0;
+ private->ref_count = 1;
+
+ if (attributes_mask & GDK_WA_X)
+ x = attributes->x;
+ else
+ x = 0;
+
+ if (attributes_mask & GDK_WA_Y)
+ y = attributes->y;
+ else
+ y = 0;
+
+ private->x = x;
+ private->y = y;
+ private->width = (attributes->width > 1) ? (attributes->width) : (1);
+ private->height = (attributes->height > 1) ? (attributes->height) : (1);
+ private->window_type = attributes->window_type;
+ private->extension_events = 0;
+ private->extension_events_selected = FALSE;
+
+ private->filters = NULL;
+ private->children = NULL;
+
+ window->user_data = NULL;
+
+ if (attributes_mask & GDK_WA_VISUAL)
+ visual = attributes->visual;
+ else
+ visual = gdk_visual_get_system ();
+ xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+ if (attributes_mask & GDK_WA_TITLE)
+ title = attributes->title;
+ else
+ title = g_get_prgname ();
+
+ private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
+ private->bg_type = GDK_WIN32_BG_NORMAL;
+ private->hint_flags = 0;
+
+#ifndef MULTIPLE_WINDOW_CLASSES
+ if (klass == 0)
+ {
+#endif
+ wcl.cbSize = sizeof (WNDCLASSEX);
+#if 1
+ wcl.style = CS_HREDRAW | CS_VREDRAW;
+#else
+ wcl.style = 0;
+#endif
+ wcl.lpfnWndProc = gdk_WindowProc;
+ wcl.cbClsExtra = 0;
+ wcl.cbWndExtra = 0;
+ wcl.hInstance = gdk_ProgInstance;
+ wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
+
+#if 0 /* tml: orig -> generates SetClassLong errors in set background */
+ wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
+ wcl.hbrBackground = NULL;
+#else
+ /* initialize once! */
+ if (0 == hAppIcon)
+ {
+ gchar sLoc [_MAX_PATH+1];
+ HINSTANCE hInst = GetModuleHandle(NULL);
+
+ if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
+ {
+ hAppIcon = ExtractIcon(hInst, sLoc, 0);
+ if (0 == hAppIcon)
+ {
+ char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
+
+ hAppIcon = ExtractIcon(hInst, gdklibname, 0);
+ g_free (gdklibname);
+ }
+
+ if (0 == hAppIcon)
+ hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
+ }
+ }
+ wcl.hIcon = CopyIcon (hAppIcon);
+ wcl.hIconSm = CopyIcon (hAppIcon);
+ /* HB: starting with black to have something to release ... */
+ wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0));
+#endif
+
+ wcl.lpszMenuName = NULL;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ sprintf (wcl_name_buf, "gdk-wcl-%d", wcl_cnt++);
+ wcl.lpszClassName = g_strdup (wcl_name_buf);
+ /* wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); */
+#else
+ wcl.lpszClassName = "GDK-window-class";
+ klass = RegisterClassEx (&wcl);
+ if (!klass)
+ g_error ("RegisterClassEx failed");
+ }
+
+ private->xcursor = NULL;
+#endif
+
+ if (parent_private && parent_private->guffaw_gravity)
+ {
+ /* XXX ??? */
+ }
+
+ if (attributes->wclass == GDK_INPUT_OUTPUT)
+ {
+ dwExStyle = 0;
+ if (attributes_mask & GDK_WA_COLORMAP)
+ private->colormap = attributes->colormap;
+ else
+ private->colormap = gdk_colormap_get_system ();
+ }
+ else
+ {
+ dwExStyle = WS_EX_TRANSPARENT;
+ private->colormap = NULL;
+ private->bg_type = GDK_WIN32_BG_TRANSPARENT;
+ private->bg_pixmap = NULL;
+ }
+
+ if (attributes_mask & GDK_WA_X)
+ x = attributes->x;
+ else
+ x = CW_USEDEFAULT;
+
+ if (attributes_mask & GDK_WA_Y)
+ y = attributes->y;
+ else if (attributes_mask & GDK_WA_X)
+ y = 100; /* ??? We must put it somewhere... */
+ else
+ y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
+
+ if (parent_private)
+ parent_private->children = g_list_prepend (parent_private->children, window);
+
+ switch (private->window_type)
+ {
+ case GDK_WINDOW_TOPLEVEL:
+ dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
+ xparent = gdk_root_window;
+ break;
+ case GDK_WINDOW_CHILD:
+ dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+ break;
+ case GDK_WINDOW_DIALOG:
+ dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
+ xparent = gdk_root_window;
+ break;
+ case GDK_WINDOW_TEMP:
+ dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ wcl.style |= CS_SAVEBITS;
+#endif
+ dwExStyle |= WS_EX_TOOLWINDOW;
+ break;
+ case GDK_WINDOW_ROOT:
+ g_error ("cannot make windows of type GDK_WINDOW_ROOT");
+ break;
+ case GDK_WINDOW_PIXMAP:
+ g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
+ break;
+ }
+
+#ifdef MULTIPLE_WINDOW_CLASSES
+ klass = RegisterClassEx (&wcl);
+ if (!klass)
+ g_error ("RegisterClassEx failed");
+#endif
+
+ if (private->window_type != GDK_WINDOW_CHILD)
+ {
+ if (x == CW_USEDEFAULT)
+ {
+ rect.left = 100;
+ rect.top = 100;
+ }
+ else
+ {
+ rect.left = x;
+ rect.top = y;
+ }
+
+ rect.right = rect.left + private->width;
+ rect.bottom = rect.top + private->height;
+
+ if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
+ g_warning ("gdk_window_new: AdjustWindowRectEx failed");
+
+ if (x != CW_USEDEFAULT)
+ {
+ x = rect.left;
+ y = rect.top;
+ }
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ }
+ else
+ {
+ width = private->width;
+ height = private->height;
+ }
+
+ private->xwindow =
+ CreateWindowEx (dwExStyle,
+ wcl.lpszClassName,
+ title,
+ dwStyle,
+ x, y,
+ width, height,
+ xparent,
+ NULL,
+ gdk_ProgInstance,
+ NULL);
+ GDK_NOTE (MISC,
+ g_print ("gdk_window_create: %s %s %#x %dx%d@+%d+%d %#x = %#x\n",
+ (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
+ (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
+ (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
+ (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
+ "???")))),
+ title,
+ dwStyle,
+ width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
+ xparent,
+ private->xwindow));
+
+ gdk_window_ref (window);
+ gdk_xid_table_insert (&private->xwindow, window);
+
+ if (private->colormap)
+ gdk_colormap_ref (private->colormap);
+
+ gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
+ (attributes->cursor) :
+ NULL));
+
+ return window;
+}
+
+GdkWindow *
+gdk_window_foreign_new (guint32 anid)
+{
+ GdkWindow *window;
+ GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
+ HANDLE parent;
+ RECT rect;
+ POINT point;
+
+ private = g_new (GdkWindowPrivate, 1);
+ window = (GdkWindow*) private;
+
+ parent = GetParent ((HWND) anid);
+ private->parent = gdk_xid_table_lookup (parent);
+
+ parent_private = (GdkWindowPrivate *)private->parent;
+
+ if (parent_private)
+ parent_private->children = g_list_prepend (parent_private->children, window);
+
+ private->xwindow = (HWND) anid;
+ GetClientRect ((HWND) anid, &rect);
+ point.x = rect.left;
+ point.y = rect.right;
+ ClientToScreen ((HWND) anid, &point);
+ if (parent != HWND_DESKTOP)
+ ScreenToClient (parent, &point);
+ private->x = point.x;
+ private->y = point.y;
+ private->width = rect.right - rect.left;
+ private->height = rect.bottom - rect.top;
+ private->resize_count = 0;
+ private->ref_count = 1;
+ private->window_type = GDK_WINDOW_FOREIGN;
+ private->destroyed = FALSE;
+ private->mapped = IsWindowVisible (private->xwindow);
+ private->guffaw_gravity = FALSE;
+ private->extension_events = 0;
+ private->extension_events_selected = FALSE;
+
+ private->colormap = NULL;
+
+ private->filters = NULL;
+ private->children = NULL;
+
+ window->user_data = NULL;
+
+ gdk_window_ref (window);
+ gdk_xid_table_insert (&private->xwindow, window);
+
+ return window;
+}
+
+/* Call this function when you want a window and all its children to
+ * disappear. When xdestroy is true, a request to destroy the XWindow
+ * is sent out. When it is false, it is assumed that the XWindow has
+ * been or will be destroyed by destroying some ancestor of this
+ * window.
+ */
+static void
+gdk_window_internal_destroy (GdkWindow *window,
+ gboolean xdestroy,
+ gboolean our_destroy)
+{
+ GdkWindowPrivate *private;
+ GdkWindowPrivate *temp_private;
+ GdkWindow *temp_window;
+ GList *children;
+ GList *tmp;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
+ private->xwindow));
+
+ switch (private->window_type)
+ {
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_CHILD:
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TEMP:
+ case GDK_WINDOW_FOREIGN:
+ if (!private->destroyed)
+ {
+ if (private->parent)
+ {
+ GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
+ if (parent_private->children)
+ parent_private->children = g_list_remove (parent_private->children, window);
+ }
+
+ if (private->window_type != GDK_WINDOW_FOREIGN)
+ {
+ children = tmp = private->children;
+ private->children = NULL;
+
+ while (tmp)
+ {
+ temp_window = tmp->data;
+ tmp = tmp->next;
+
+ temp_private = (GdkWindowPrivate*) temp_window;
+ if (temp_private)
+ gdk_window_internal_destroy (temp_window, FALSE,
+ our_destroy);
+ }
+
+ g_list_free (children);
+ }
+
+ if (private->extension_events != 0)
+ gdk_input_window_destroy (window);
+
+ if (private->filters)
+ {
+ tmp = private->filters;
+
+ while (tmp)
+ {
+ g_free (tmp->data);
+ tmp = tmp->next;
+ }
+
+ g_list_free (private->filters);
+ private->filters = NULL;
+ }
+
+ if (private->window_type == GDK_WINDOW_FOREIGN)
+ {
+ if (our_destroy && (private->parent != NULL))
+ {
+ /* It's somebody elses window, but in our hierarchy,
+ * so reparent it to the root window, and then send
+ * it a delete event, as if we were a WM
+ */
+ gdk_window_hide (window);
+ gdk_window_reparent (window, NULL, 0, 0);
+
+ /* Is this too drastic? Many (most?) applications
+ * quit if any window receives WM_QUIT I think.
+ * OTOH, I don't think foreign windows are much
+ * used, so the question is maybe academic.
+ */
+ PostMessage (private->xwindow, WM_QUIT, 0, 0);
+ }
+ }
+ else if (xdestroy)
+ DestroyWindow (private->xwindow);
+
+ if (private->colormap)
+ gdk_colormap_unref (private->colormap);
+
+ private->mapped = FALSE;
+ private->destroyed = TRUE;
+ }
+ break;
+
+ case GDK_WINDOW_ROOT:
+ g_error ("attempted to destroy root window");
+ break;
+
+ case GDK_WINDOW_PIXMAP:
+ g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
+ break;
+ }
+}
+
+/* Like internal_destroy, but also destroys the reference created by
+ gdk_window_new. */
+
+void
+gdk_window_destroy (GdkWindow *window)
+{
+ gdk_window_internal_destroy (window, TRUE, TRUE);
+ gdk_window_unref (window);
+}
+
+/* This function is called when the XWindow is really gone. */
+
+void
+gdk_window_destroy_notify (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
+ private->xwindow, private->destroyed));
+
+ if (!private->destroyed)
+ {
+ if (private->window_type == GDK_WINDOW_FOREIGN)
+ gdk_window_internal_destroy (window, FALSE, FALSE);
+ else
+ g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
+ }
+
+ gdk_xid_table_remove (private->xwindow);
+ gdk_window_unref (window);
+}
+
+GdkWindow*
+gdk_window_ref (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+ g_return_val_if_fail (window != NULL, NULL);
+
+ private->ref_count += 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
+ private->xwindow, private->ref_count));
+
+ return window;
+}
+
+void
+gdk_window_unref (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+ g_return_if_fail (window != NULL);
+
+ private->ref_count -= 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
+ private->xwindow, private->ref_count,
+ (private->ref_count == 0 ? " freeing" : "")));
+
+ if (private->ref_count == 0)
+ {
+ if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
+ gdk_pixmap_unref (private->bg_pixmap);
+
+ if (!private->destroyed)
+ {
+ if (private->window_type == GDK_WINDOW_FOREIGN)
+ gdk_xid_table_remove (private->xwindow);
+ else
+ g_warning ("losing last reference to undestroyed window");
+ }
+ g_dataset_destroy (window);
+ g_free (window);
+ }
+}
+
+void
+gdk_window_show (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
+
+ private->mapped = TRUE;
+ if (private->window_type == GDK_WINDOW_TEMP)
+ {
+ ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
+ SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+#if 0
+ ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
+#endif
+ }
+ else
+ {
+ ShowWindow (private->xwindow, SW_SHOWNORMAL);
+ ShowWindow (private->xwindow, SW_RESTORE);
+ SetForegroundWindow (private->xwindow);
+#if 0
+ ShowOwnedPopups (private->xwindow, TRUE);
+#endif
+ }
+ }
+}
+
+void
+gdk_window_hide (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
+
+ private->mapped = FALSE;
+ if (private->window_type == GDK_WINDOW_TOPLEVEL)
+ ShowOwnedPopups (private->xwindow, FALSE);
+#if 1
+ ShowWindow (private->xwindow, SW_HIDE);
+#elif 0
+ ShowWindow (private->xwindow, SW_MINIMIZE);
+#else
+ CloseWindow (private->xwindow);
+#endif
+ }
+}
+
+void
+gdk_window_withdraw (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
+
+ gdk_window_hide (window); /* XXX */
+ }
+}
+
+void
+gdk_window_move (GdkWindow *window,
+ gint x,
+ gint y)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ RECT rect;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
+ private->xwindow, x, y));
+ GetClientRect (private->xwindow, &rect);
+
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
+ g_warning ("gdk_window_move: AdjustWindowRectEx failed");
+ if (private->window_type == GDK_WINDOW_CHILD)
+ {
+ private->x = x;
+ private->y = y;
+ }
+ GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
+ private->xwindow,
+ rect.right - rect.left, rect.bottom - rect.top,
+ x + rect.left, y + rect.top));
+ if (!MoveWindow (private->xwindow,
+ x + rect.left, y + rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ TRUE))
+ g_warning ("gdk_window_move: MoveWindow failed");
+ }
+}
+
+void
+gdk_window_resize (GdkWindow *window,
+ gint width,
+ gint height)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ if ((gint16) width < 1)
+ width = 1;
+ if ((gint16) height < 1)
+ height = 1;
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed &&
+ ((private->resize_count > 0) ||
+ (private->width != (guint16) width) ||
+ (private->height != (guint16) height)))
+ {
+ RECT rect;
+ POINT pt;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+ int x, y;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
+ private->xwindow, width, height));
+
+ pt.x = 0;
+ pt.y = 0;
+ ClientToScreen (private->xwindow, &pt);
+ rect.left = pt.x;
+ rect.top = pt.y;
+ rect.right = pt.x + width;
+ rect.bottom = pt.y + height;
+
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
+ g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
+ if (private->window_type != GDK_WINDOW_CHILD)
+ {
+ x = rect.left;
+ y = rect.top;
+ }
+ else
+ {
+ x = private->x;
+ y = private->y;
+ }
+
+ private->resize_count += 1;
+
+ if (private->window_type == GDK_WINDOW_CHILD)
+ {
+ private->width = width;
+ private->height = height;
+ }
+ GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
+ private->xwindow,
+ rect.right - rect.left, rect.bottom - rect.top,
+ x, y));
+ if (!MoveWindow (private->xwindow,
+ x, y,
+ rect.right - rect.left, rect.bottom - rect.top,
+ TRUE))
+ g_warning ("gdk_window_resize: MoveWindow failed");
+ }
+}
+
+void
+gdk_window_move_resize (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ if ((gint16) width < 1)
+ width = 1;
+ if ((gint16) height < 1)
+ height = 1;
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ RECT rect;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
+ private->xwindow, width, height, x, y));
+
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
+ g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
+
+ if (private->window_type == GDK_WINDOW_CHILD)
+ {
+ private->x = x;
+ private->y = y;
+ private->width = width;
+ private->height = height;
+ }
+ GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
+ private->xwindow,
+ rect.right - rect.left, rect.bottom - rect.top,
+ rect.left, rect.top));
+ if (!MoveWindow (private->xwindow,
+ rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ TRUE))
+ g_warning ("gdk_window_move_resize: MoveWindow failed");
+
+ if (private->guffaw_gravity)
+ {
+ GList *tmp_list = private->children;
+ while (tmp_list)
+ {
+ GdkWindowPrivate *child_private = tmp_list->data;
+
+ child_private->x -= x - private->x;
+ child_private->y -= y - private->y;
+
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ }
+}
+
+void
+gdk_window_reparent (GdkWindow *window,
+ GdkWindow *new_parent,
+ gint x,
+ gint y)
+{
+ GdkWindowPrivate *window_private;
+ GdkWindowPrivate *parent_private;
+ GdkWindowPrivate *old_parent_private;
+
+ g_return_if_fail (window != NULL);
+
+ if (!new_parent)
+ new_parent = (GdkWindow*) &gdk_root_parent;
+
+ window_private = (GdkWindowPrivate*) window;
+ old_parent_private = (GdkWindowPrivate*)window_private->parent;
+ parent_private = (GdkWindowPrivate*) new_parent;
+
+ if (!window_private->destroyed && !parent_private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
+ window_private->xwindow,
+ parent_private->xwindow));
+ if (!SetParent (window_private->xwindow, parent_private->xwindow))
+ g_warning ("gdk_window_reparent: SetParent failed");
+
+ if (!MoveWindow (window_private->xwindow,
+ x, y,
+ window_private->width, window_private->height,
+ TRUE))
+ g_warning ("gdk_window_reparent: MoveWindow failed");
+ }
+
+ window_private->parent = new_parent;
+
+ if (old_parent_private)
+ old_parent_private->children = g_list_remove (old_parent_private->children, window);
+
+ if ((old_parent_private &&
+ (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
+ (!old_parent_private && parent_private->guffaw_gravity))
+ gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
+
+ parent_private->children = g_list_prepend (parent_private->children, window);
+}
+
+void
+gdk_window_clear (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ gdk_window_clear_area (window, 0, 0, private->width, private->height);
+ }
+}
+
+
+void
+gdk_window_clear_area (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ HDC hdc;
+
+ if (width == -1)
+ width = G_MAXSHORT/2; /* Yeah, right */
+ if (height == -1)
+ height = G_MAXSHORT/2;
+ GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
+ private->xwindow, width, height, x, y));
+ hdc = GetDC (private->xwindow);
+ IntersectClipRect (hdc, x, y, x + width, y + height);
+ SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
+ ReleaseDC (private->xwindow, hdc);
+ }
+}
+
+void
+gdk_window_clear_area_e (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ RECT rect;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
+ private->xwindow, width, height, x, y));
+
+ rect.left = x;
+ rect.right = x + width;
+ rect.top = y;
+ rect.bottom = y + height;
+ if (!InvalidateRect (private->xwindow, &rect, TRUE))
+ g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
+ UpdateWindow (private->xwindow);
+ }
+}
+
+void
+gdk_window_copy_area (GdkWindow *window,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ GdkWindow *source_window,
+ gint source_x,
+ gint source_y,
+ gint width,
+ gint height)
+{
+ GdkWindowPrivate *src_private;
+ GdkWindowPrivate *dest_private;
+ GdkGCPrivate *gc_private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (gc != NULL);
+
+ if (source_window == NULL)
+ source_window = window;
+
+ src_private = (GdkWindowPrivate*) source_window;
+ dest_private = (GdkWindowPrivate*) window;
+ gc_private = (GdkGCPrivate*) gc;
+
+ if (!src_private->destroyed && !dest_private->destroyed)
+ {
+ HDC hdcDest, hdcSrc;
+
+ if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
+ g_warning ("gdk_window_copy_area: GetDC failed");
+
+ if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
+ g_warning ("gdk_window_copy_area: GetDC failed");
+
+ if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
+ g_warning ("gdk_window_copy_area: BitBlt failed");
+
+ ReleaseDC (dest_private->xwindow, hdcDest);
+ ReleaseDC (src_private->xwindow, hdcSrc);
+ }
+}
+
+void
+gdk_window_raise (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
+
+ if (!BringWindowToTop (private->xwindow))
+ g_warning ("gdk_window_raise: BringWindowToTop failed");
+ }
+}
+
+void
+gdk_window_lower (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
+
+ if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
+ g_warning ("gdk_window_lower: SetWindowPos failed");
+ }
+}
+
+void
+gdk_window_set_user_data (GdkWindow *window,
+ gpointer user_data)
+{
+ g_return_if_fail (window != NULL);
+
+ window->user_data = user_data;
+}
+
+void
+gdk_window_set_hints (GdkWindow *window,
+ gint x,
+ gint y,
+ gint min_width,
+ gint min_height,
+ gint max_width,
+ gint max_height,
+ gint flags)
+{
+ GdkWindowPrivate *private;
+ WINDOWPLACEMENT size_hints;
+ RECT rect;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+ int diff;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
+ private->xwindow,
+ min_width, min_height, max_width, max_height,
+ x, y));
+
+ private->hint_flags = flags;
+ size_hints.length = sizeof (size_hints);
+
+ if (flags)
+ {
+ if (flags & GDK_HINT_POS)
+ if (!GetWindowPlacement (private->xwindow, &size_hints))
+ g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
+ else
+ {
+ GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
+ " (%d,%d)--(%d,%d)\n",
+ size_hints.rcNormalPosition.left,
+ size_hints.rcNormalPosition.top,
+ size_hints.rcNormalPosition.right,
+ size_hints.rcNormalPosition.bottom));
+ /* What are the corresponding window coordinates for client
+ * area coordinates x, y
+ */
+ rect.left = x;
+ rect.top = y;
+ rect.right = rect.left + 200; /* dummy */
+ rect.bottom = rect.top + 200;
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ size_hints.flags = 0;
+ size_hints.showCmd = SW_SHOWNA;
+
+ /* Set the normal position hint to that location, with unchanged
+ * width and height.
+ */
+ diff = size_hints.rcNormalPosition.left - rect.left;
+ size_hints.rcNormalPosition.left = rect.left;
+ size_hints.rcNormalPosition.right -= diff;
+ diff = size_hints.rcNormalPosition.top - rect.top;
+ size_hints.rcNormalPosition.top = rect.top;
+ size_hints.rcNormalPosition.bottom -= diff;
+ GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
+ size_hints.rcNormalPosition.left,
+ size_hints.rcNormalPosition.top,
+ size_hints.rcNormalPosition.right,
+ size_hints.rcNormalPosition.bottom));
+ if (!SetWindowPlacement (private->xwindow, &size_hints))
+ g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
+ private->hint_x = rect.left;
+ private->hint_y = rect.top;
+ }
+
+ if (flags & GDK_HINT_MIN_SIZE)
+ {
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = min_width;
+ rect.bottom = min_height;
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ private->hint_min_width = rect.right - rect.left;
+ private->hint_min_height = rect.bottom - rect.top;
+
+ /* Also chek if he current size of the window is in bounds. */
+ GetClientRect (private->xwindow, &rect);
+ if (rect.right < min_width && rect.bottom < min_height)
+ gdk_window_resize (window, min_width, min_height);
+ else if (rect.right < min_width)
+ gdk_window_resize (window, min_width, rect.bottom);
+ else if (rect.bottom < min_height)
+ gdk_window_resize (window, rect.right, min_height);
+ }
+ if (flags & GDK_HINT_MAX_SIZE)
+ {
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = max_width;
+ rect.bottom = max_height;
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ private->hint_max_width = rect.right - rect.left;
+ private->hint_max_height = rect.bottom - rect.top;
+ /* Again, check if the window is too large currently. */
+ GetClientRect (private->xwindow, &rect);
+ if (rect.right > max_width && rect.bottom > max_height)
+ gdk_window_resize (window, max_width, max_height);
+ else if (rect.right > max_width)
+ gdk_window_resize (window, max_width, rect.bottom);
+ else if (rect.bottom > max_height)
+ gdk_window_resize (window, rect.right, max_height);
+ }
+ }
+}
+
+void
+gdk_window_set_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints geom_mask)
+{
+ GdkWindowPrivate *private;
+ WINDOWPLACEMENT size_hints;
+ RECT rect;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+ int diff;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ size_hints.length = sizeof (size_hints);
+
+ private->hint_flags = geom_mask;
+
+ if (geom_mask & GDK_HINT_POS)
+ ; /* XXX */
+
+ if (geom_mask & GDK_HINT_MIN_SIZE)
+ {
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = geometry->min_width;
+ rect.bottom = geometry->min_height;
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ private->hint_min_width = rect.right - rect.left;
+ private->hint_min_height = rect.bottom - rect.top;
+
+ /* Also check if he current size of the window is in bounds */
+ GetClientRect (private->xwindow, &rect);
+ if (rect.right < geometry->min_width
+ && rect.bottom < geometry->min_height)
+ gdk_window_resize (window, geometry->min_width, geometry->min_height);
+ else if (rect.right < geometry->min_width)
+ gdk_window_resize (window, geometry->min_width, rect.bottom);
+ else if (rect.bottom < geometry->min_height)
+ gdk_window_resize (window, rect.right, geometry->min_height);
+ }
+
+ if (geom_mask & GDK_HINT_MAX_SIZE)
+ {
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = geometry->max_width;
+ rect.bottom = geometry->max_height;
+ dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ private->hint_max_width = rect.right - rect.left;
+ private->hint_max_height = rect.bottom - rect.top;
+
+ /* Again, check if the window is too large currently. */
+ GetClientRect (private->xwindow, &rect);
+ if (rect.right > geometry->max_width
+ && rect.bottom > geometry->max_height)
+ gdk_window_resize (window, geometry->max_width, geometry->max_height);
+ else if (rect.right > geometry->max_width)
+ gdk_window_resize (window, geometry->max_width, rect.bottom);
+ else if (rect.bottom > geometry->max_height)
+ gdk_window_resize (window, rect.right, geometry->max_height);
+ }
+
+ /* I don't know what to do when called with zero base_width and height. */
+ if (geom_mask & GDK_HINT_BASE_SIZE
+ && geometry->base_width > 0
+ && geometry->base_height > 0)
+ if (!GetWindowPlacement (private->xwindow, &size_hints))
+ g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
+ else
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
+ " rcNormalPosition: (%d,%d)--(%d,%d)\n",
+ size_hints.rcNormalPosition.left,
+ size_hints.rcNormalPosition.top,
+ size_hints.rcNormalPosition.right,
+ size_hints.rcNormalPosition.bottom));
+ size_hints.rcNormalPosition.right =
+ size_hints.rcNormalPosition.left + geometry->base_width;
+ size_hints.rcNormalPosition.bottom =
+ size_hints.rcNormalPosition.top + geometry->base_height;
+ GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
+ size_hints.rcNormalPosition.left,
+ size_hints.rcNormalPosition.top,
+ size_hints.rcNormalPosition.right,
+ size_hints.rcNormalPosition.bottom));
+ if (!SetWindowPlacement (private->xwindow, &size_hints))
+ g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
+ }
+
+ if (geom_mask & GDK_HINT_RESIZE_INC)
+ {
+ /* XXX */
+ }
+
+ if (geom_mask & GDK_HINT_ASPECT)
+ {
+ /* XXX */
+ }
+}
+
+void
+gdk_window_set_title (GdkWindow *window,
+ const gchar *title)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ if (!SetWindowText (private->xwindow, title))
+ g_warning ("gdk_window_set_title: SetWindowText failed");
+ }
+}
+
+void
+gdk_window_set_role (GdkWindow *window,
+ const gchar *role)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
+ private->xwindow, (role ? role : "NULL")));
+ /* XXX */
+}
+
+void
+gdk_window_set_transient_for (GdkWindow *window,
+ GdkWindow *parent)
+{
+ GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ parent_private = (GdkWindowPrivate*) parent;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
+ private->xwindow, parent_private->xwindow));
+ /* XXX */
+}
+
+void
+gdk_window_set_background (GdkWindow *window,
+ GdkColor *color)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (!private->destroyed)
+ {
+ GdkColormapPrivate *colormap_private =
+ (GdkColormapPrivate *) private->colormap;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
+ private->xwindow,
+ gdk_color_to_string (color)));
+
+ if (private->bg_type == GDK_WIN32_BG_PIXMAP)
+ {
+ if (private->bg_pixmap != NULL)
+ {
+ gdk_pixmap_unref (private->bg_pixmap);
+ private->bg_pixmap = NULL;
+ }
+ private->bg_type = GDK_WIN32_BG_NORMAL;
+ }
+#ifdef MULTIPLE_WINDOW_CLASSES
+ if (colormap_private != NULL
+ && colormap_private->xcolormap->rc_palette)
+ {
+ /* If we are on a palettized display we can't use the window
+ * class background brush, but must handle WM_ERASEBKGND.
+ * At least, I think so.
+ */
+#endif
+ private->bg_type = GDK_WIN32_BG_PIXEL;
+ private->bg_pixel = *color;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ }
+ else
+ {
+ /* Non-palettized display; just set the window class background
+ brush. */
+ HBRUSH hbr;
+ HGDIOBJ oldbrush;
+ COLORREF background;
+
+ background = RGB (color->red >> 8,
+ color->green >> 8,
+ color->blue >> 8);
+
+ if ((hbr = CreateSolidBrush (GetNearestColor (gdk_DC,
+ background))) == NULL)
+ {
+ g_warning ("gdk_window_set_background: CreateSolidBrush failed");
+ return;
+ }
+
+ oldbrush = (HGDIOBJ) GetClassLong (private->xwindow,
+ GCL_HBRBACKGROUND);
+
+ if (SetClassLong (private->xwindow, GCL_HBRBACKGROUND,
+ (LONG) hbr) == 0)
+ g_warning ("gdk_window_set_background: SetClassLong failed");
+
+ if (!DeleteObject (oldbrush))
+ g_warning ("gdk_window_set_background: DeleteObject failed");
+ }
+#endif
+ }
+}
+
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+ GdkPixmap *pixmap,
+ gint parent_relative)
+{
+ GdkWindowPrivate *window_private;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ GdkPixmapPrivate *pixmap_private;
+#endif
+
+ g_return_if_fail (window != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+#ifdef MULTIPLE_WINDOW_CLASSES
+ pixmap_private = (GdkPixmapPrivate*) pixmap;
+#endif
+
+ if (!window_private->destroyed)
+ {
+ GdkColormapPrivate *colormap_private =
+ (GdkColormapPrivate *) window_private->colormap;
+ if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
+ {
+ if (window_private->bg_pixmap != NULL)
+ {
+ gdk_pixmap_unref (window_private->bg_pixmap);
+ window_private->bg_pixmap = NULL;
+ }
+ window_private->bg_type = GDK_WIN32_BG_NORMAL;
+ }
+ if (parent_relative)
+ {
+ window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
+ }
+ else if (!pixmap)
+ {
+#ifdef MULTIPLE_WINDOW_CLASSES
+ SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
+ (LONG) GetStockObject (BLACK_BRUSH));
+#endif
+ }
+#ifdef MULTIPLE_WINDOW_CLASSES
+ else if (colormap_private->xcolormap->rc_palette)
+ {
+ /* Must do the background painting in the
+ * WM_ERASEBKGND handler.
+ */
+ window_private->bg_type = GDK_WIN32_BG_PIXMAP;
+ window_private->bg_pixmap = pixmap;
+ gdk_pixmap_ref (pixmap);
+ }
+ else if (pixmap_private->width <= 8
+ && pixmap_private->height <= 8)
+ {
+ /* We can use small pixmaps directly as background brush */
+ SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
+ (LONG) CreatePatternBrush (pixmap_private->xwindow));
+ }
+#endif
+ else
+ {
+ /* We must cache the pixmap in the WindowPrivate and
+ * paint it each time we get WM_ERASEBKGND
+ */
+ window_private->bg_type = GDK_WIN32_BG_PIXMAP;
+ window_private->bg_pixmap = pixmap;
+ gdk_pixmap_ref (pixmap);
+ }
+ }
+}
+
+void
+gdk_window_set_cursor (GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkWindowPrivate *window_private;
+ GdkCursorPrivate *cursor_private;
+ HCURSOR xcursor;
+
+ g_return_if_fail (window != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+ cursor_private = (GdkCursorPrivate*) cursor;
+
+ if (!window_private->destroyed)
+ {
+ if (!cursor)
+ xcursor = LoadCursor (NULL, IDC_ARROW);
+ else
+ xcursor = cursor_private->xcursor;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
+ window_private->xwindow, xcursor));
+#ifdef MULTIPLE_WINDOW_CLASSES
+ if (!SetClassLong (window_private->xwindow, GCL_HCURSOR, (LONG) xcursor))
+ g_warning ("gdk_window_set_cursor: SetClassLong failed");
+#else
+ window_private->xcursor = xcursor;
+#endif
+ SetCursor (xcursor);
+ }
+}
+
+void
+gdk_window_set_colormap (GdkWindow *window,
+ GdkColormap *colormap)
+{
+ GdkWindowPrivate *window_private;
+ GdkColormapPrivate *colormap_private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (colormap != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+ colormap_private = (GdkColormapPrivate*) colormap;
+
+ if (!window_private->destroyed)
+ {
+ /* XXX ??? */
+ GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
+ window_private->xwindow,
+ colormap_private->xcolormap));
+ if (window_private->colormap)
+ gdk_colormap_unref (window_private->colormap);
+ window_private->colormap = colormap;
+ gdk_colormap_ref (window_private->colormap);
+
+ if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
+ gdk_window_add_colormap_windows (window);
+ }
+}
+
+void
+gdk_window_get_user_data (GdkWindow *window,
+ gpointer *data)
+{
+ g_return_if_fail (window != NULL);
+
+ *data = window->user_data;
+}
+
+void
+gdk_window_get_geometry (GdkWindow *window,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ gint *depth)
+{
+ GdkWindowPrivate *window_private;
+
+ if (!window)
+ window = (GdkWindow*) &gdk_root_parent;
+
+ window_private = (GdkWindowPrivate*) window;
+
+ if (!window_private->destroyed)
+ {
+ RECT rect;
+
+ if (!GetClientRect (window_private->xwindow, &rect))
+ g_warning ("gdk_window_get_geometry: GetClientRect failed");
+
+ if (x)
+ *x = rect.left;
+ if (y)
+ *y = rect.top;
+ if (width)
+ *width = rect.right - rect.left;
+ if (height)
+ *height = rect.bottom - rect.top;
+ if (depth)
+ *depth = gdk_window_get_visual (window)->depth;
+ }
+}
+
+void
+gdk_window_get_position (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_if_fail (window != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+
+ if (x)
+ *x = window_private->x;
+ if (y)
+ *y = window_private->y;
+}
+
+void
+gdk_window_get_size (GdkWindow *window,
+ gint *width,
+ gint *height)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_if_fail (window != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+
+ if (width)
+ *width = window_private->width;
+ if (height)
+ *height = window_private->height;
+}
+
+GdkVisual*
+gdk_window_get_visual (GdkWindow *window)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+ /* Huh? ->parent is never set for a pixmap. We should just return
+ * null immeditately
+ */
+ while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
+ window_private = (GdkWindowPrivate*) window_private->parent;
+
+ if (window_private && !window_private->destroyed)
+ {
+ if (window_private->colormap == NULL)
+ {
+ return gdk_visual_get_system (); /* XXX ??? */
+ }
+ else
+ return ((GdkColormapPrivate *)window_private->colormap)->visual;
+ }
+
+ return NULL;
+}
+
+GdkColormap*
+gdk_window_get_colormap (GdkWindow *window)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_val_if_fail (window != NULL, NULL);
+ window_private = (GdkWindowPrivate*) window;
+
+ g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
+ if (!window_private->destroyed)
+ {
+ if (window_private->colormap == NULL)
+ {
+ return gdk_colormap_get_system (); /* XXX ??? */
+ }
+ else
+ return window_private->colormap;
+ }
+
+ return NULL;
+}
+
+GdkWindowType
+gdk_window_get_type (GdkWindow *window)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
+
+ window_private = (GdkWindowPrivate*) window;
+ return window_private->window_type;
+}
+
+gint
+gdk_window_get_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkWindowPrivate *private;
+ gint return_val;
+ gint tx = 0;
+ gint ty = 0;
+
+ g_return_val_if_fail (window != NULL, 0);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ POINT pt;
+
+ pt.x = 0;
+ pt.y = 0;
+ ClientToScreen (private->xwindow, &pt);
+ tx = pt.x;
+ ty = pt.y;
+ return_val = 1;
+ }
+ else
+ return_val = 0;
+
+ if (x)
+ *x = tx;
+ if (y)
+ *y = ty;
+
+ return return_val;
+}
+
+gboolean
+gdk_window_get_deskrelative_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ return gdk_window_get_origin (window, x, y);
+}
+
+void
+gdk_window_get_root_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkWindowPrivate *private;
+ POINT pt;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ if (private->destroyed)
+ return;
+
+ while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
+ private = (GdkWindowPrivate*) private->parent;
+ if (private->destroyed)
+ return;
+
+ pt.x = 0;
+ pt.y = 0;
+ ClientToScreen (private->xwindow, &pt);
+ if (x)
+ *x = pt.x;
+ if (y)
+ *y = pt.y;
+}
+
+GdkWindow*
+gdk_window_get_pointer (GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkWindowPrivate *private;
+ GdkWindow *return_val;
+ POINT pointc, point;
+ HWND hwnd, hwndc;
+
+ if (!window)
+ window = (GdkWindow*) &gdk_root_parent;
+
+ private = (GdkWindowPrivate*) window;
+
+ return_val = NULL;
+ GetCursorPos (&pointc);
+ point = pointc;
+ ScreenToClient (private->xwindow, &point);
+
+ if (x)
+ *x = point.x;
+ if (y)
+ *y = point.y;
+
+ hwnd = WindowFromPoint (point);
+ point = pointc;
+ ScreenToClient (hwnd, &point);
+
+ do {
+ hwndc = ChildWindowFromPoint (hwnd, point);
+ ClientToScreen (hwnd, &point);
+ ScreenToClient (hwndc, &point);
+ } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
+
+ return_val = gdk_window_lookup (hwnd);
+
+ if (mask)
+ {
+ BYTE kbd[256];
+
+ GetKeyboardState (kbd);
+ *mask = 0;
+ if (kbd[VK_SHIFT] & 0x80)
+ *mask |= GDK_SHIFT_MASK;
+ if (kbd[VK_CAPITAL] & 0x80)
+ *mask |= GDK_LOCK_MASK;
+ if (kbd[VK_CONTROL] & 0x80)
+ *mask |= GDK_CONTROL_MASK;
+ if (kbd[VK_MENU] & 0x80)
+ *mask |= GDK_MOD1_MASK;
+ if (kbd[VK_LBUTTON] & 0x80)
+ *mask |= GDK_BUTTON1_MASK;
+ if (kbd[VK_MBUTTON] & 0x80)
+ *mask |= GDK_BUTTON2_MASK;
+ if (kbd[VK_RBUTTON] & 0x80)
+ *mask |= GDK_BUTTON3_MASK;
+ }
+
+ return return_val;
+}
+
+GdkWindow*
+gdk_window_at_pointer (gint *win_x,
+ gint *win_y)
+{
+ GdkWindowPrivate *private;
+ GdkWindow *window;
+ POINT point, pointc;
+ HWND hwnd, hwndc;
+ RECT rect;
+
+ private = &gdk_root_parent;
+
+ GetCursorPos (&pointc);
+ point = pointc;
+ hwnd = WindowFromPoint (point);
+
+ if (hwnd == NULL)
+ {
+ window = (GdkWindow *) &gdk_root_parent;
+ if (win_x)
+ *win_x = pointc.x;
+ if (win_y)
+ *win_y = pointc.y;
+ return window;
+ }
+
+ ScreenToClient (hwnd, &point);
+
+ do {
+ hwndc = ChildWindowFromPoint (hwnd, point);
+ ClientToScreen (hwnd, &point);
+ ScreenToClient (hwndc, &point);
+ } while (hwndc != hwnd && (hwnd = hwndc, 1));
+
+ window = gdk_window_lookup (hwnd);
+
+ if (window && (win_x || win_y))
+ {
+ GetClientRect (hwnd, &rect);
+ if (win_x)
+ *win_x = point.x - rect.left;
+ if (win_y)
+ *win_y = point.y - rect.top;
+ }
+
+ GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
+ point.x, point.y, hwnd,
+ (window == NULL ? " NULL" : "")));
+
+ return window;
+}
+
+GdkWindow*
+gdk_window_get_parent (GdkWindow *window)
+{
+ g_return_val_if_fail (window != NULL, NULL);
+
+ return ((GdkWindowPrivate*) window)->parent;
+}
+
+GdkWindow*
+gdk_window_get_toplevel (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ while (private->window_type == GDK_WINDOW_CHILD)
+ {
+ window = ((GdkWindowPrivate*) window)->parent;
+ private = (GdkWindowPrivate*) window;
+ }
+
+ return window;
+}
+
+GList*
+gdk_window_get_children (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+ GList *children;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return NULL;
+
+ /* XXX ??? */
+ g_warning ("gdk_window_get_children ???");
+ children = NULL;
+
+ return children;
+}
+
+GdkEventMask
+gdk_window_get_events (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+ GdkEventMask event_mask;
+
+ g_return_val_if_fail (window != NULL, 0);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return 0;
+
+ event_mask = 0;
+
+ event_mask = private->event_mask;
+
+ return event_mask;
+}
+
+void
+gdk_window_set_events (GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ private->event_mask = event_mask;
+}
+
+void
+gdk_window_add_colormap_windows (GdkWindow *window)
+{
+ g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
+}
+
+/*
+ * This needs the X11 shape extension.
+ * If not available, shaped windows will look
+ * ugly, but programs still work. Stefan Wille
+ */
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x, gint y)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_if_fail (window != NULL);
+
+ window_private = (GdkWindowPrivate*) window;
+
+ if (!mask)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
+ window_private->xwindow));
+ SetWindowRgn (window_private->xwindow, NULL, TRUE);
+ }
+ else
+ {
+ GdkPixmapPrivate *pixmap_private;
+ HRGN hrgn;
+ DWORD dwStyle;
+ DWORD dwExStyle;
+ RECT rect;
+
+ /* Convert mask bitmap to region */
+ pixmap_private = (GdkPixmapPrivate*) mask;
+ hrgn = BitmapToRegion (pixmap_private->xwindow);
+
+ GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
+ window_private->xwindow,
+ pixmap_private->xwindow));
+
+ /* SetWindowRgn wants window (not client) coordinates */
+ dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
+ dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
+ GetClientRect (window_private->xwindow, &rect);
+ AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ OffsetRgn (hrgn, -rect.left, -rect.top);
+
+ OffsetRgn (hrgn, x, y);
+
+ /* If this is a top-level window, add the title bar to the region */
+ if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
+ {
+ CombineRgn (hrgn, hrgn,
+ CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
+ RGN_OR);
+ }
+
+ SetWindowRgn (window_private->xwindow, hrgn, TRUE);
+ }
+}
+
+void
+gdk_window_add_filter (GdkWindow *window,
+ GdkFilterFunc function,
+ gpointer data)
+{
+ GdkWindowPrivate *private;
+ GList *tmp_list;
+ GdkEventFilter *filter;
+
+ private = (GdkWindowPrivate*) window;
+ if (private && private->destroyed)
+ return;
+
+ if (private)
+ tmp_list = private->filters;
+ else
+ tmp_list = gdk_default_filters;
+
+ while (tmp_list)
+ {
+ filter = (GdkEventFilter *)tmp_list->data;
+ if ((filter->function == function) && (filter->data == data))
+ return;
+ tmp_list = tmp_list->next;
+ }
+
+ filter = g_new (GdkEventFilter, 1);
+ filter->function = function;
+ filter->data = data;
+
+ if (private)
+ private->filters = g_list_append (private->filters, filter);
+ else
+ gdk_default_filters = g_list_append (gdk_default_filters, filter);
+}
+
+void
+gdk_window_remove_filter (GdkWindow *window,
+ GdkFilterFunc function,
+ gpointer data)
+{
+ GdkWindowPrivate *private;
+ GList *tmp_list, *node;
+ GdkEventFilter *filter;
+
+ private = (GdkWindowPrivate*) window;
+
+ if(private)
+ tmp_list = private->filters;
+ else
+ tmp_list = gdk_default_filters;
+
+ while (tmp_list)
+ {
+ filter = (GdkEventFilter *)tmp_list->data;
+ node = tmp_list;
+ tmp_list = tmp_list->next;
+
+ if ((filter->function == function) && (filter->data == data))
+ {
+ if(private)
+ private->filters = g_list_remove_link (private->filters, node);
+ else
+ gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
+ g_list_free_1 (node);
+ g_free (filter);
+
+ return;
+ }
+ }
+}
+
+void
+gdk_window_set_override_redirect (GdkWindow *window,
+ gboolean override_redirect)
+{
+ g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
+}
+
+void
+gdk_window_set_icon (GdkWindow *window,
+ GdkWindow *icon_window,
+ GdkPixmap *pixmap,
+ GdkBitmap *mask)
+{
+ g_warning ("gdk_window_set_icon not implemented"); /* XXX */
+}
+
+void
+gdk_window_set_icon_name (GdkWindow *window,
+ gchar *name)
+{
+ GdkWindowPrivate *window_private;
+
+ g_return_if_fail (window != NULL);
+ window_private = (GdkWindowPrivate*) window;
+ if (window_private->destroyed)
+ return;
+
+ if (!SetWindowText (window_private->xwindow, name))
+ g_warning ("gdk_window_set_icon_name: SetWindowText failed");
+}
+
+void
+gdk_window_set_group (GdkWindow *window,
+ GdkWindow *leader)
+{
+ g_warning ("gdk_window_set_group not implemented"); /* XXX */
+}
+
+void
+gdk_window_set_decorations (GdkWindow *window,
+ GdkWMDecoration decorations)
+{
+ GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
+ LONG style, exstyle;
+
+ style = GetWindowLong (window_private->xwindow, GWL_STYLE);
+ exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
+
+ style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
+ |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
+
+ exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
+
+ if (decorations & GDK_DECOR_ALL)
+ style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
+ if (decorations & GDK_DECOR_BORDER)
+ style |= (WS_BORDER);
+ if (decorations & GDK_DECOR_RESIZEH)
+ style |= (WS_THICKFRAME);
+ if (decorations & GDK_DECOR_TITLE)
+ style |= (WS_CAPTION);
+ if (decorations & GDK_DECOR_MENU)
+ style |= (WS_SYSMENU);
+ if (decorations & GDK_DECOR_MINIMIZE)
+ style |= (WS_MINIMIZEBOX);
+ if (decorations & GDK_DECOR_MAXIMIZE)
+ style |= (WS_MAXIMIZEBOX);
+
+ SetWindowLong (window_private->xwindow, GWL_STYLE, style);
+}
+
+void
+gdk_window_set_functions (GdkWindow *window,
+ GdkWMFunction functions)
+{
+ GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
+ LONG style, exstyle;
+
+ style = GetWindowLong (window_private->xwindow, GWL_STYLE);
+ exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
+
+ style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
+ |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
+ |WS_SYSMENU);
+
+ exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
+
+ if (functions & GDK_FUNC_ALL)
+ style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
+ if (functions & GDK_FUNC_RESIZE)
+ style |= (WS_THICKFRAME);
+ if (functions & GDK_FUNC_MOVE)
+ style |= (WS_THICKFRAME);
+ if (functions & GDK_FUNC_MINIMIZE)
+ style |= (WS_MINIMIZEBOX);
+ if (functions & GDK_FUNC_MAXIMIZE)
+ style |= (WS_MAXIMIZEBOX);
+
+ SetWindowLong (window_private->xwindow, GWL_STYLE, style);
+}
+
+GList *
+gdk_window_get_toplevels (void)
+{
+ GList *new_list = NULL;
+ GList *tmp_list;
+
+ tmp_list = gdk_root_parent.children;
+ while (tmp_list)
+ {
+ new_list = g_list_prepend (new_list, tmp_list->data);
+ tmp_list = tmp_list->next;
+ }
+
+ return new_list;
+}
+
+/*
+ * propagate the shapes from all child windows of a GDK window to the parent
+ * window. Shamelessly ripped from Enlightenment's code
+ *
+ * - Raster
+ */
+
+static void
+QueryTree (HWND hwnd,
+ HWND **children,
+ gint *nchildren)
+{
+ guint i, n;
+ HWND child;
+
+ n = 0;
+ do {
+ if (n == 0)
+ child = GetWindow (hwnd, GW_CHILD);
+ else
+ child = GetWindow (child, GW_HWNDNEXT);
+ if (child != NULL)
+ n++;
+ } while (child != NULL);
+
+ if (n > 0)
+ {
+ *children = g_new (HWND, n);
+ for (i = 0; i < n; i++)
+ {
+ if (i == 0)
+ child = GetWindow (hwnd, GW_CHILD);
+ else
+ child = GetWindow (child, GW_HWNDNEXT);
+ *children[i] = child;
+ }
+ }
+}
+
+static void
+gdk_propagate_shapes (HANDLE win,
+ gboolean merge)
+{
+ RECT emptyRect;
+ HRGN region, childRegion;
+ RECT rect;
+ HWND *list = NULL;
+ gint i, num;
+
+ SetRectEmpty (&emptyRect);
+ region = CreateRectRgnIndirect (&emptyRect);
+ if (merge)
+ GetWindowRgn (win, region);
+
+ QueryTree (win, &list, &num);
+ if (list != NULL)
+ {
+ WINDOWPLACEMENT placement;
+
+ placement.length = sizeof (WINDOWPLACEMENT);
+ /* go through all child windows and create/insert spans */
+ for (i = 0; i < num; i++)
+ {
+ GetWindowPlacement (list[i], &placement);
+ if (placement.showCmd = SW_SHOWNORMAL)
+ {
+ childRegion = CreateRectRgnIndirect (&emptyRect);
+ GetWindowRgn (list[i], childRegion);
+ CombineRgn (region, region, childRegion, RGN_OR);
+ }
+ }
+ SetWindowRgn (win, region, TRUE);
+ }
+}
+
+void
+gdk_window_set_child_shapes (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ gdk_propagate_shapes ( private->xwindow, FALSE);
+}
+
+void
+gdk_window_merge_child_shapes (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ gdk_propagate_shapes (private->xwindow, TRUE);
+}
+
+/*************************************************************
+ * gdk_window_is_visible:
+ * Check if the given window is mapped.
+ * arguments:
+ * window:
+ * results:
+ * is the window mapped
+ *************************************************************/
+
+gboolean
+gdk_window_is_visible (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ return private->mapped;
+}
+
+/*************************************************************
+ * gdk_window_is_viewable:
+ * Check if the window and all ancestors of the window
+ * are mapped. (This is not necessarily "viewable" in
+ * the X sense, since we only check as far as we have
+ * GDK window parents, not to the root window)
+ * arguments:
+ * window:
+ * results:
+ * is the window viewable
+ *************************************************************/
+
+gboolean
+gdk_window_is_viewable (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ while (private &&
+ (private != &gdk_root_parent) &&
+ (private->window_type != GDK_WINDOW_FOREIGN))
+ {
+ if (!private->mapped)
+ return FALSE;
+
+ private = (GdkWindowPrivate *)private->parent;
+ }
+
+ return TRUE;
+}
+
+void
+gdk_drawable_set_data (GdkDrawable *drawable,
+ const gchar *key,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_dataset_set_data_full (drawable, key, data, destroy_func);
+}
+
+
+/* Support for windows that can be guffaw-scrolled
+ * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
+ */
+
+static gboolean
+gdk_window_gravity_works (void)
+{
+ enum { UNKNOWN, NO, YES };
+ static gint gravity_works = UNKNOWN;
+
+ if (gravity_works == UNKNOWN)
+ {
+ GdkWindowAttr attr;
+ GdkWindow *parent;
+ GdkWindow *child;
+ gint y;
+
+ attr.window_type = GDK_WINDOW_TEMP;
+ attr.wclass = GDK_INPUT_OUTPUT;
+ attr.x = 0;
+ attr.y = 0;
+ attr.width = 100;
+ attr.height = 100;
+ attr.event_mask = 0;
+
+ parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
+
+ attr.window_type = GDK_WINDOW_CHILD;
+ child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
+
+ gdk_window_set_static_win_gravity (child, TRUE);
+
+ gdk_window_resize (parent, 100, 110);
+ gdk_window_move (parent, 0, -10);
+ gdk_window_move_resize (parent, 0, 0, 100, 100);
+
+ gdk_window_resize (parent, 100, 110);
+ gdk_window_move (parent, 0, -10);
+ gdk_window_move_resize (parent, 0, 0, 100, 100);
+
+ gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
+
+ gdk_window_destroy (parent);
+ gdk_window_destroy (child);
+
+ gravity_works = ((y == -20) ? YES : NO);
+ }
+
+ return (gravity_works == YES);
+}
+
+static void
+gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_if_fail (window != NULL);
+
+ GDK_NOTE (MISC,
+ g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
+}
+
+static void
+gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_if_fail (window != NULL);
+
+ GDK_NOTE (MISC,
+ g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
+}
+
+/*************************************************************
+ * gdk_window_set_static_gravities:
+ * Set the bit gravity of the given window to static,
+ * and flag it so all children get static subwindow
+ * gravity.
+ * arguments:
+ * window: window for which to set static gravity
+ * use_static: Whether to turn static gravity on or off.
+ * results:
+ * Does the XServer support static gravity?
+ *************************************************************/
+
+gboolean
+gdk_window_set_static_gravities (GdkWindow *window,
+ gboolean use_static)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+ GList *tmp_list;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ if (!use_static == !private->guffaw_gravity)
+ return TRUE;
+
+ if (use_static && !gdk_window_gravity_works ())
+ return FALSE;
+
+ private->guffaw_gravity = use_static;
+
+ gdk_window_set_static_bit_gravity (window, use_static);
+
+ tmp_list = private->children;
+ while (tmp_list)
+ {
+ gdk_window_set_static_win_gravity (window, use_static);
+
+ tmp_list = tmp_list->next;
+ }
+
+ return TRUE;
+}