Some questions regarding _gdk_window_impl_new() (csw, win32, patch)
- From: Hans Breuer <hans breuer org>
- To: Gtk-Devel <gtk-devel-list gnome org>
- Subject: Some questions regarding _gdk_window_impl_new() (csw, win32, patch)
- Date: Sat, 21 Aug 2010 14:09:18 +0200
while trying to fix _gdk_window_impl_new() for win32 some more,
quite some questions arose around that (apparently undocumented;)) API:
- if the information given to _gdk_window_impl_new() is redundant,
as with GDK_WA_VISUAL set and visual given by parameter, which one
has precedence?
- when turning a csw into a native window, shouldn't the new window
position be calculated against the native parent? If so: should
the caller do it and give GDK_WA_(X|Y)?
- how to get back default OS/window-manager placment of toplevel
windows? (The old implementation used to place toplevel windows
with CW_USEDEFAULT, my new implementation is doing similar)
- what's the (visual) depth of a GDK_INPUT_ONLY window?
( Dia(win32) with gtk>=2.18 is crashing on it's Navigation popup,
which can be fixed by setting the visual depth to something
reasonable, but it used to be 0 before csw. Maybe this is hiding
a bug elsewhere, e.g. returning the wrong window when forced to
be native? )
Another question is regarding "GDK_NATIVE_WINDOWS". With my current
patch at least the drawing seems to work reasonable again, but the
(ENTER|LEAVE)_NOTIFY handling is not, so the mouse pointer is almost
useless. Is it necessary to ressurect most of the original code (pre-csw)
to make it work again, or should there be an easier way?
Thanks,
Hans
-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it. -- Dilbert
D:\Devel\from-git\gtk-2-2x\gdk>d:\Devel\Git\bin\git diff win32
diff --git a/gdk/win32/gdkgeometry-win32.c b/gdk/win32/gdkgeometry-win32.c
index 6cdb860..47fcc12 100644
--- a/gdk/win32/gdkgeometry-win32.c
+++ b/gdk/win32/gdkgeometry-win32.c
@@ -70,9 +70,14 @@ _gdk_window_move_resize_child (GdkWindow *window,
obj = GDK_WINDOW_OBJECT (window);
impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
+#if 0 /* the values are already set by caller, so this calculation is flawed */
is_move = (x - obj->x != 0) && (y - obj->y != 0);
is_resize = obj->width != width && obj->height != height;
-
+#else
+ is_move = TRUE;
+ is_resize = TRUE;
+#endif
+
GDK_NOTE (MISC, g_print ("_gdk_window_move_resize_child: %s %+d%+d %dx%d %+d%+d\n",
_gdk_win32_drawable_description (window),
obj->x, obj->y, width, height, x, y));
@@ -92,8 +97,8 @@ _gdk_window_move_resize_child (GdkWindow *window,
obj->width = width;
obj->height = height;
- _gdk_win32_window_tmp_unset_parent_bg (window);
- _gdk_win32_window_tmp_unset_bg (window, TRUE);
+ //_gdk_win32_window_tmp_unset_parent_bg (window);
+ //_gdk_win32_window_tmp_unset_bg (window, TRUE);
GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%d,%d,"
"NOACTIVATE|NOZORDER%s%s)\n",
@@ -111,7 +116,7 @@ _gdk_window_move_resize_child (GdkWindow *window,
(is_resize ? 0 : SWP_NOSIZE)));
//_gdk_win32_window_tmp_reset_parent_bg (window);
- _gdk_win32_window_tmp_reset_bg (window, TRUE);
+ //_gdk_win32_window_tmp_reset_bg (window, TRUE);
}
void
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 598d291..8711cdc 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -474,7 +474,6 @@ _gdk_window_impl_new (GdkWindow *window,
ATOM klass = 0;
DWORD dwStyle = 0, dwExStyle;
RECT rect;
- GdkWindow *orig_parent;
GdkWindowObject *private;
GdkWindowImplWin32 *impl;
GdkDrawableImplWin32 *draw_impl;
@@ -482,11 +481,10 @@ _gdk_window_impl_new (GdkWindow *window,
wchar_t *wtitle;
gint window_width, window_height;
gint offset_x = 0, offset_y = 0;
+ gint x, y;
private = (GdkWindowObject *)window;
- orig_parent = real_parent;
-
GDK_NOTE (MISC,
g_print ("_gdk_window_impl_new: %s\n",
(attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
@@ -502,19 +500,9 @@ _gdk_window_impl_new (GdkWindow *window,
draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
draw_impl->wrapper = GDK_DRAWABLE (window);
- // XXX: xattributes_mask = 0
-
-#if 0
if (attributes_mask & GDK_WA_VISUAL)
visual = attributes->visual;
- else
- visual = gdk_visual_get_system ();
-#endif
-#if 0
- impl->width = (attributes->width > 1) ? (attributes->width) : (1);
- impl->height = (attributes->height > 1) ? (attributes->height) : (1);
-#endif
impl->extension_events_selected = FALSE;
// XXX ?
@@ -543,7 +531,7 @@ _gdk_window_impl_new (GdkWindow *window,
* to work well enough for the actual use cases in gtk.
*/
dwExStyle = WS_EX_TRANSPARENT;
- private->depth = 0;
+ private->depth = visual->depth; /* xxx: was 0 for years */
private->input_only = TRUE;
draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
g_object_ref (draw_impl->colormap);
@@ -560,7 +548,7 @@ _gdk_window_impl_new (GdkWindow *window,
hparent = GetDesktopWindow ();
}
/* Children of foreign windows aren't toplevel windows */
- if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
+ if (GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
{
dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
}
@@ -601,13 +589,29 @@ _gdk_window_impl_new (GdkWindow *window,
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+ /* non child windows are placed by the OS/window manager */
+ if (!private->x && !private->y && !offset_x && !offset_y)
+ x = y = CW_USEDEFAULT;
window_width = rect.right - rect.left;
window_height = rect.bottom - rect.top;
}
else
{
+ /* adjust position relative to real_parent */
+ GdkWindowObject *parent = private->parent;
+
+ while (parent && !_gdk_window_has_impl (parent))
+ {
+ offset_x -= parent->x;
+ offset_y -= parent->y;
+ parent = parent->parent;
+ }
+
window_width = private->width;
window_height = private->height;
+ /* use given position for initial placement */
+ x = private->x - offset_x;
+ y = private->y - offset_y;
}
if (attributes_mask & GDK_WA_TITLE)
@@ -620,9 +624,7 @@ _gdk_window_impl_new (GdkWindow *window,
private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
if (attributes_mask & GDK_WA_TYPE_HINT)
- impl->type_hint = attributes->type_hint;
- else
- impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+ gdk_window_set_type_hint (window, attributes->type_hint);
if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
dwExStyle |= WS_EX_TOOLWINDOW;
@@ -638,9 +640,8 @@ _gdk_window_impl_new (GdkWindow *window,
MAKEINTRESOURCEW (klass),
wtitle,
dwStyle,
- ((attributes_mask & GDK_WA_X) ?
- private->x - offset_x : CW_USEDEFAULT),
- private->y - offset_y,
+ x,
+ y,
window_width, window_height,
hparent,
NULL,
@@ -674,8 +675,7 @@ _gdk_window_impl_new (GdkWindow *window,
GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d %+d%+d %p = %p\n",
title,
window_width, window_height,
- ((attributes_mask & GDK_WA_X) ?
- private->x - offset_x: CW_USEDEFAULT),
+ private->x - offset_x,
private->y - offset_y,
hparent,
GDK_WINDOW_HWND (window)));
@@ -857,7 +857,8 @@ gdk_window_destroy_notify (GdkWindow *window)
}
gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
- g_object_unref (window);
+ // crash on GDK_NATIVE_WINDOWS:
+ // g_object_unref (window);
}
static void
@@ -1096,7 +1097,7 @@ static void
gdk_win32_window_show (GdkWindow *window,
gboolean already_mapped)
{
- show_window_internal (window, FALSE, FALSE);
+ show_window_internal (window, already_mapped, FALSE);
}
static void
@@ -1423,6 +1424,202 @@ gdk_win32_window_reparent (GdkWindow *window,
}
static void
+erase_background (GdkWindow *window,
+ HDC hdc)
+{
+ HDC bgdc = NULL;
+ HBRUSH hbr = NULL;
+ HPALETTE holdpal = NULL;
+ RECT rect;
+ COLORREF bg;
+ GdkColormap *colormap;
+ GdkColormapPrivateWin32 *colormap_private;
+ int x, y;
+ int x_offset, y_offset;
+
+ if (((GdkWindowObject *) window)->input_only ||
+ ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG)
+ {
+ return;
+ }
+
+ colormap = gdk_drawable_get_colormap (window);
+
+ if (colormap &&
+ (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
+ colormap->visual->type == GDK_VISUAL_STATIC_COLOR))
+ {
+ int k;
+
+ colormap_private = GDK_WIN32_COLORMAP_DATA (colormap);
+
+ if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE)))
+ WIN32_GDI_FAILED ("SelectPalette");
+ else if ((k = RealizePalette (hdc)) == GDI_ERROR)
+ WIN32_GDI_FAILED ("RealizePalette");
+ else if (k > 0)
+ GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n",
+ colormap_private->hpal, k));
+ }
+
+ x_offset = y_offset = 0;
+ while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
+ {
+ /* If this window should have the same background as the parent,
+ * fetch the parent. (And if the same goes for the parent, fetch
+ * the grandparent, etc.)
+ */
+ x_offset += ((GdkWindowObject *) window)->x;
+ y_offset += ((GdkWindowObject *) window)->y;
+ window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
+ }
+
+ GetClipBox (hdc, &rect);
+
+ if (((GdkWindowObject *) window)->bg_pixmap == NULL)
+ {
+ bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap,
+ ((GdkWindowObject *) window)->bg_color.pixel);
+
+ if (!(hbr = CreateSolidBrush (bg)))
+ WIN32_GDI_FAILED ("CreateSolidBrush");
+ else if (!FillRect (hdc, &rect, hbr))
+ WIN32_GDI_FAILED ("FillRect");
+ if (hbr != NULL)
+ DeleteObject (hbr);
+ }
+ else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG)
+ {
+ GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap;
+ GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
+
+ if (x_offset == 0 && y_offset == 0 &&
+ pixmap_impl->width <= 8 && pixmap_impl->height <= 8)
+ {
+ if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap))))
+ WIN32_GDI_FAILED ("CreatePatternBrush");
+ else if (!FillRect (hdc, &rect, hbr))
+ WIN32_GDI_FAILED ("FillRect");
+ if (hbr != NULL)
+ DeleteObject (hbr);
+ }
+ else
+ {
+ HGDIOBJ oldbitmap;
+
+ if (!(bgdc = CreateCompatibleDC (hdc)))
+ {
+ WIN32_GDI_FAILED ("CreateCompatibleDC");
+ return;
+ }
+ if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap))))
+ {
+ WIN32_GDI_FAILED ("SelectObject");
+ DeleteDC (bgdc);
+ return;
+ }
+ x = -x_offset;
+ while (x < rect.right)
+ {
+ if (x + pixmap_impl->width >= rect.left)
+ {
+ y = -y_offset;
+ while (y < rect.bottom)
+ {
+ if (y + pixmap_impl->height >= rect.top)
+ {
+ if (!BitBlt (hdc, x, y,
+ pixmap_impl->width, pixmap_impl->height,
+ bgdc, 0, 0, SRCCOPY))
+ {
+ WIN32_GDI_FAILED ("BitBlt");
+ SelectObject (bgdc, oldbitmap);
+ DeleteDC (bgdc);
+ return;
+ }
+ }
+ y += pixmap_impl->height;
+ }
+ }
+ x += pixmap_impl->width;
+ }
+ SelectObject (bgdc, oldbitmap);
+ DeleteDC (bgdc);
+ }
+ }
+}
+
+static void
+gdk_win32_window_clear_area (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ gboolean send_expose)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ HDC hdc;
+ RECT rect;
+
+ hdc = GetDC (GDK_WINDOW_HWND (window));
+
+ if (!send_expose)
+ {
+ if (width == 0)
+ width = private->width - x;
+ if (height == 0)
+ height = private->height - y;
+ GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: "
+ "%dx%d %+d%+d\n",
+ GDK_WINDOW_HWND (window),
+ width, height, x, y));
+ IntersectClipRect (hdc, x, y, x + width, y + height);
+ erase_background (window, hdc);
+ GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
+ }
+ else
+ {
+ /* The background should be erased before the expose event is
+ generated */
+ IntersectClipRect (hdc, x, y, x + width, y + height);
+ erase_background (window, hdc);
+ GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
+
+ rect.left = x;
+ rect.right = x + width;
+ rect.top = y;
+ rect.bottom = y + height;
+
+ GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
+ UpdateWindow (GDK_WINDOW_HWND (window));
+ }
+ }
+}
+
+static void
+gdk_window_win32_clear_region (GdkWindow *window,
+ GdkRegion *region,
+ gboolean send_expose)
+{
+ GdkRectangle *rectangles;
+ int n_rectangles, i;
+
+ gdk_region_get_rectangles (region,
+ &rectangles,
+ &n_rectangles);
+
+ for (i = 0; i < n_rectangles; i++)
+ gdk_win32_window_clear_area (window,
+ rectangles[i].x, rectangles[i].y,
+ rectangles[i].width, rectangles[i].height,
+ send_expose);
+
+ g_free (rectangles);
+}
+static void
gdk_win32_window_raise (GdkWindow *window)
{
if (!GDK_WINDOW_DESTROYED (window))
@@ -1865,13 +2062,46 @@ gdk_win32_window_set_background (GdkWindow *window,
_gdk_win32_color_to_string (color)));
private->bg_color = *color;
+
+ if (private->bg_pixmap &&
+ private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
+ private->bg_pixmap != GDK_NO_BG)
+ {
+ g_object_unref (private->bg_pixmap);
+ private->bg_pixmap = NULL;
+ }
}
static void
gdk_win32_window_set_back_pixmap (GdkWindow *window,
GdkPixmap *pixmap)
{
- /* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ if (pixmap != GDK_PARENT_RELATIVE_BG &&
+ pixmap != GDK_NO_BG &&
+ pixmap && !gdk_drawable_get_colormap (pixmap))
+ {
+ g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
+ return;
+ }
+
+ if (private->bg_pixmap &&
+ private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
+ private->bg_pixmap != GDK_NO_BG)
+ g_object_unref (private->bg_pixmap);
+
+ if (pixmap != GDK_PARENT_RELATIVE_BG &&
+ pixmap != GDK_NO_BG &&
+ pixmap)
+ {
+ g_object_ref (pixmap);
+ private->bg_pixmap = pixmap;
+ }
+ else
+ {
+ private->bg_pixmap = pixmap;
+ }
}
static void
@@ -2086,7 +2316,21 @@ static void
gdk_win32_window_restack_under (GdkWindow *window,
GList *native_siblings)
{
- // ### TODO
+ GList *list;
+
+ /* input order is bottom-most first */
+ for (list = native_siblings;;)
+ {
+ HWND lower = list->data, upper;
+
+ list = list->next;
+ if (!list)
+ break;
+ upper = list->data;
+ API_CALL (SetWindowPos, (upper, lower, 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW));
+ }
+
}
static void
@@ -2094,7 +2338,11 @@ gdk_win32_window_restack_toplevel (GdkWindow *window,
GdkWindow *sibling,
gboolean above)
{
- // ### TODO
+ HWND lower = above ? GDK_WINDOW_HWND (sibling) : GDK_WINDOW_HWND (window);
+ HWND upper = above ? GDK_WINDOW_HWND (window) : GDK_WINDOW_HWND (sibling);
+
+ API_CALL (SetWindowPos, (upper, lower, 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW));
}
void
@@ -2352,6 +2600,38 @@ do_shape_combine_region (GdkWindow *window,
SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
}
+static void
+gdk_win32_window_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x, gint y)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ if (!mask)
+ {
+ GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
+ GDK_WINDOW_HWND (window)));
+ SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
+
+ private->shaped = FALSE;
+ }
+ else
+ {
+ HRGN hrgn;
+
+ GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
+ GDK_WINDOW_HWND (window),
+ GDK_WINDOW_HWND (mask)));
+
+ /* Convert mask bitmap to region */
+ hrgn = _gdk_win32_bitmap_to_hrgn (mask);
+
+ do_shape_combine_region (window, hrgn, x, y);
+
+ private->shaped = TRUE;
+ }
+}
+
void
gdk_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)
@@ -3531,17 +3811,20 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->set_background = gdk_win32_window_set_background;
iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
iface->reparent = gdk_win32_window_reparent;
+ iface->clear_region = gdk_window_win32_clear_region;
iface->set_cursor = gdk_win32_window_set_cursor;
iface->get_geometry = gdk_win32_window_get_geometry;
- iface->get_pointer = gdk_window_win32_get_pointer;
iface->get_root_coords = gdk_win32_window_get_root_coords;
+ iface->get_pointer = gdk_window_win32_get_pointer;
+ iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
iface->shape_combine_region = gdk_win32_window_shape_combine_region;
iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
- iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
iface->set_static_gravities = gdk_win32_window_set_static_gravities;
iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
iface->queue_translation = _gdk_win32_window_queue_translation;
iface->destroy = _gdk_win32_window_destroy;
iface->input_window_destroy = _gdk_input_window_destroy;
iface->input_window_crossing = _gdk_input_crossing_event;
+ /* CHECK: we may not need set_pixmap anymore if setting FALSE */
+ iface->supports_native_bg = TRUE;
}
diff --git a/gdk/win32/makefile.msc b/gdk/win32/makefile.msc
index 5a4fa41..7a88284 100644
--- a/gdk/win32/makefile.msc
+++ b/gdk/win32/makefile.msc
@@ -21,7 +21,8 @@ DEFINES = \
-DGDK_COMPILATION -DG_LOG_DOMAIN=\"Gdk\"
INCLUDES = -FImsvc_recommended_pragmas.h \
- -I. -I.. -I..\.. $(GLIB_CFLAGS) $(PANGO_CFLAGS) $(CAIRO_CFLAGS) \
+ -I. -I.. -I..\.. $(GLIB_CFLAGS) $(GDK_PIXBUF_CFLAGS) \
+ $(PANGO_CFLAGS) $(CAIRO_CFLAGS) \
-I$(WTKIT)\include -I$(GLIB) \
all: \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]