Merge branch 'gtk-2-24-win32' into gtk-2-24

This commit is contained in:
Alexander Larsson 2011-11-07 15:07:01 +01:00
commit c3601481b7
29 changed files with 1703 additions and 1212 deletions

View File

@ -569,7 +569,7 @@ copy $(Configuration)\$(Platform)\bin\*-$(GtkApiVersion).lib $(CopyDir)\lib
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\..;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\include;$(GlibEtcInstallRoot)\include\cairo;$(GlibEtcInstallRoot)\include\atk-1.0;$(GlibEtcInstallRoot)\include\pango-1.0;$(GlibEtcInstallRoot)\include\GdkPixbuf-2.0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_CONFIG_H;G_DISABLE_DEPRECATED;G_DISABLE_SINGLE_INCLUDES;ATK_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_CONFIG_H;G_DISABLE_SINGLE_INCLUDES;ATK_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForcedIncludeFiles>msvc_recommended_pragmas.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
</ClCompile>
<Link>

View File

@ -9,7 +9,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\include;$(GlibEtcInstallRoot)\include\cairo;$(GlibEtcInstallRoot)\include\atk-1.0;$(GlibEtcInstallRoot)\include\pango-1.0;$(GlibEtcInstallRoot)\include\gdk-pixbuf-2.0"
PreprocessorDefinitions="HAVE_CONFIG_H;G_DISABLE_DEPRECATED;G_DISABLE_SINGLE_INCLUDES;ATK_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES"
PreprocessorDefinitions="HAVE_CONFIG_H;G_DISABLE_SINGLE_INCLUDES;ATK_DISABLE_SINGLE_INCLUDES;GDK_PIXBUF_DISABLE_SINGLE_INCLUDES;GTK_DISABLE_SINGLE_INCLUDES"
ForcedIncludeFiles="msvc_recommended_pragmas.h"
/>
<Tool

View File

@ -1550,6 +1550,9 @@ AC_ARG_ENABLE(test-print-backend,
[enable_test_print_backend=no])
AM_CONDITIONAL(TEST_PRINT_BACKEND, test "x$enable_test_print_backend" != "xno")
if test "$os_win32" = "yes"; then
AC_CHECK_TYPES([IPrintDialogCallback],[],[],[[#include <windows.h>]])
fi
################################################################
# Strip -export-dynamic from the link lines of various libraries

View File

@ -1237,6 +1237,7 @@ gdk_window_destroy_notify
#if IN_HEADER(__GDK_WIN32_H__)
#if IN_FILE(__GDK_WINDOW_WIN32_C__)
gdk_win32_window_is_win32
gdk_win32_window_get_impl_hwnd
gdk_win32_begin_direct_draw_libgtk_only
gdk_win32_end_direct_draw_libgtk_only
gdk_win32_window_lookup_for_display

View File

@ -672,6 +672,7 @@ gboolean _gdk_window_has_impl (GdkWindow *window);
GdkWindow * _gdk_window_get_impl_window (GdkWindow *window);
GdkWindow *_gdk_window_get_input_window_for_event (GdkWindow *native_window,
GdkEventType event_type,
GdkModifierType mask,
int x, int y,
gulong serial);
GdkRegion *_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, int n_rects);

View File

@ -10745,7 +10745,7 @@ proxy_button_event (GdkEvent *source_event,
_gdk_display_add_pointer_grab (display,
pointer_window,
toplevel_window,
event_window,
FALSE,
gdk_window_get_events (pointer_window),
serial,
@ -11100,6 +11100,7 @@ static GdkWindow *
get_extension_event_window (GdkDisplay *display,
GdkWindow *pointer_window,
GdkEventType type,
GdkModifierType mask,
gulong serial)
{
guint evmask;
@ -11112,6 +11113,7 @@ get_extension_event_window (GdkDisplay *display,
if (grab != NULL && !grab->owner_events)
{
evmask = grab->event_mask;
evmask = update_evmask_for_button_motion (evmask, mask);
grab_window = grab->window;
@ -11125,6 +11127,7 @@ get_extension_event_window (GdkDisplay *display,
while (w != NULL)
{
evmask = w->extension_events;
evmask = update_evmask_for_button_motion (evmask, mask);
if (evmask & type_masks[type])
return (GdkWindow *)w;
@ -11136,6 +11139,7 @@ get_extension_event_window (GdkDisplay *display,
grab->owner_events)
{
evmask = grab->event_mask;
evmask = update_evmask_for_button_motion (evmask, mask);
if (evmask & type_masks[type])
return grab->window;
@ -11150,6 +11154,7 @@ get_extension_event_window (GdkDisplay *display,
GdkWindow *
_gdk_window_get_input_window_for_event (GdkWindow *native_window,
GdkEventType event_type,
GdkModifierType mask,
int x, int y,
gulong serial)
{
@ -11171,6 +11176,7 @@ _gdk_window_get_input_window_for_event (GdkWindow *native_window,
event_win = get_extension_event_window (display,
pointer_window,
event_type,
mask,
serial);
return event_win;

View File

@ -370,7 +370,9 @@ inner_clipboard_window_procedure (HWND hwnd,
{
int success;
HWND hwndOwner;
#ifdef G_ENABLE_DEBUG
UINT nFormat = 0;
#endif
GdkEvent *event;
GdkWindow *owner;

View File

@ -1540,20 +1540,50 @@ blit_from_pixmap (gboolean use_fg_bg,
}
static void
blit_inside_drawable (HDC hdc,
GdkGCWin32 *gcwin32,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
blit_inside_drawable (HDC hdc,
GdkGCWin32 *gcwin32,
GdkDrawableImplWin32 *src,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GDK_NOTE (DRAW, g_print ("blit_inside_drawable\n"));
GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height,
hdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));
if GDK_IS_WINDOW_IMPL_WIN32 (src)
{
/* Simply calling BitBlt() instead of these ScrollDC() gymnastics might
* seem tempting, but we need to do this to prevent blitting garbage when
* scrolling a window that is partially obscured by another window. For
* example, GIMP's toolbox being over the editor window. */
RECT scrollRect, emptyRect;
HRGN updateRgn;
scrollRect.left = MIN (xsrc, xdest);
scrollRect.top = MIN (ysrc, ydest);
scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1);
scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1);
SetRectEmpty (&emptyRect);
updateRgn = CreateRectRgnIndirect (&emptyRect);
if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc, &scrollRect, NULL, updateRgn, NULL))
WIN32_GDI_FAILED ("ScrollDC");
else if (!InvalidateRgn (src->handle, updateRgn, FALSE))
WIN32_GDI_FAILED ("InvalidateRgn");
if (!DeleteObject (updateRgn))
WIN32_GDI_FAILED ("DeleteObject");
}
else
{
GDI_CALL (BitBlt, (hdc, xdest, ydest, width, height,
hdc, xsrc, ysrc, rop2_to_rop3 (gcwin32->rop2)));
}
}
static void
@ -1743,13 +1773,15 @@ _gdk_win32_blit (gboolean use_fg_bg,
}
if (draw_impl->handle == src_impl->handle)
blit_inside_drawable (hdc, GDK_GC_WIN32 (gc), xsrc, ysrc, xdest, ydest, width, height);
blit_inside_drawable (hdc, GDK_GC_WIN32 (gc), src_impl,
xsrc, ysrc, xdest, ydest, width, height);
else if (GDK_IS_PIXMAP_IMPL_WIN32 (src_impl))
blit_from_pixmap (use_fg_bg, draw_impl, hdc,
(GdkPixmapImplWin32 *) src_impl, gc,
xsrc, ysrc, xdest, ydest, width, height);
else
blit_from_window (hdc, GDK_GC_WIN32 (gc), src_impl, xsrc, ysrc, xdest, ydest, width, height);
blit_from_window (hdc, GDK_GC_WIN32 (gc), src_impl,
xsrc, ysrc, xdest, ydest, width, height);
gdk_win32_hdc_release (&draw_impl->parent_instance, gc, GDK_GC_FOREGROUND);
}

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,7 @@ gdk_font_hash_lookup (GdkFontType type,
}
}
#ifdef G_ENABLE_DEBUG
static const char *
charset_name (DWORD charset)
{
@ -122,6 +123,7 @@ charset_name (DWORD charset)
}
return "unknown";
}
#endif
/* This table classifies Unicode characters according to the Microsoft
* Unicode subset numbering. This is based on the table in "Developing
@ -366,6 +368,7 @@ static struct {
U_SPECIALS, "Specials" }
};
#ifdef G_ENABLE_DEBUG
static void
print_unicode_subranges (FONTSIGNATURE *fsp)
{
@ -387,6 +390,7 @@ print_unicode_subranges (FONTSIGNATURE *fsp)
g_print (" none!");
g_print ("\n");
}
#endif
static gboolean
check_unicode_subranges (UINT charset,

View File

@ -205,7 +205,9 @@ gdk_win32_gc_values_to_win32values (GdkGCValues *values,
GdkGCValuesMask mask,
GdkGCWin32 *win32_gc)
{
#ifdef G_ENABLE_DEBUG
char *s = "";
#endif
GDK_NOTE (GC, g_print ("{"));

View File

@ -79,6 +79,7 @@ gint _gdk_input_ignore_wintab = FALSE;
gint _gdk_max_colors = 0;
gboolean _modal_operation_in_progress = FALSE;
HWND _modal_move_resize_window = NULL;
gboolean _ignore_destroy_clipboard = FALSE;
HGLOBAL _delayed_rendering_data = NULL;

View File

@ -58,16 +58,14 @@ static GList *wintab_contexts = NULL;
static GdkWindow *wintab_window = NULL;
static GdkWindow *x_grab_window = NULL; /* Window that currently holds
* the extended inputs grab
*/
static GdkEventMask x_grab_mask;
static gboolean x_grab_owner_events;
static GdkDevicePrivate *_gdk_device_in_proximity;
typedef UINT (WINAPI *t_WTInfoA) (UINT a, UINT b, LPVOID c);
typedef UINT (WINAPI *t_WTInfoW) (UINT a, UINT b, LPVOID c);
typedef BOOL (WINAPI *t_WTEnable) (HCTX a, BOOL b);
typedef HCTX (WINAPI *t_WTOpenA) (HWND a, LPLOGCONTEXTA b, BOOL c);
typedef BOOL (WINAPI *t_WTGetA) (HCTX a, LPLOGCONTEXTA b);
typedef BOOL (WINAPI *t_WTSetA) (HCTX a, LPLOGCONTEXTA b);
typedef BOOL (WINAPI *t_WTOverlap) (HCTX a, BOOL b);
typedef BOOL (WINAPI *t_WTPacket) (HCTX a, UINT b, LPVOID c);
typedef int (WINAPI *t_WTQueueSizeSet) (HCTX a, int b);
@ -76,6 +74,8 @@ static t_WTInfoA p_WTInfoA;
static t_WTInfoW p_WTInfoW;
static t_WTEnable p_WTEnable;
static t_WTOpenA p_WTOpenA;
static t_WTGetA p_WTGetA;
static t_WTSetA p_WTSetA;
static t_WTOverlap p_WTOverlap;
static t_WTPacket p_WTPacket;
static t_WTQueueSizeSet p_WTQueueSizeSet;
@ -97,8 +97,10 @@ gdk_input_find_dev_from_ctx (HCTX hctx,
return NULL;
}
#if DEBUG_WINTAB
#ifdef G_ENABLE_DEBUG
static void
print_lc(LOGCONTEXT *lc)
{
@ -323,6 +325,7 @@ print_cursor (int index)
}
}
#endif
#endif
void
_gdk_input_wintab_init_check (void)
@ -384,6 +387,10 @@ _gdk_input_wintab_init_check (void)
return;
if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
return;
if ((p_WTGetA = (t_WTGetA) GetProcAddress (wintab32, "WTGetA")) == NULL)
return;
if ((p_WTSetA = (t_WTSetA) GetProcAddress (wintab32, "WTSetA")) == NULL)
return;
if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
return;
if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
@ -461,7 +468,7 @@ _gdk_input_wintab_init_check (void)
#if DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
#endif
lc.lcOptions |= CXO_MESSAGES;
lc.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
lc.lcStatus = 0;
lc.lcMsgBase = WT_DEFBASE;
lc.lcPktRate = 0;
@ -471,8 +478,8 @@ _gdk_input_wintab_init_check (void)
lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
lc.lcOutOrgX = axis_x.axMin;
lc.lcOutOrgY = axis_y.axMin;
lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
lc.lcOutExtX = axis_x.axMax - axis_x.axMin + 1;
lc.lcOutExtY = axis_y.axMax - axis_y.axMin + 1;
lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
#if DEBUG_WINTAB
GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
@ -488,9 +495,7 @@ _gdk_input_wintab_init_check (void)
devix, *hctx));
wintab_contexts = g_list_append (wintab_contexts, hctx);
#if 0
(*p_WTEnable) (*hctx, TRUE);
#endif
(*p_WTOverlap) (*hctx, TRUE);
#if DEBUG_WINTAB
@ -502,7 +507,7 @@ _gdk_input_wintab_init_check (void)
* with a smaller queue size.
*/
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
for (i = 32; i >= 1; i >>= 1)
for (i = 128; i >= 1; i >>= 1)
{
if ((*p_WTQueueSizeSet) (*hctx, i))
{
@ -615,8 +620,8 @@ _gdk_input_wintab_init_check (void)
gdkdev->axes[k].min_value = -1000;
gdkdev->axes[k].max_value = 1000;
gdkdev->info.axes[k].use = axis;
gdkdev->info.axes[k].min = -1000;
gdkdev->info.axes[k].max = 1000;
gdkdev->info.axes[k].min = -1.0;
gdkdev->info.axes[k].max = 1.0;
k++;
}
}
@ -663,41 +668,44 @@ decode_tilt (gint *axis_data,
static void
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
GdkInputWindow *input_window,
GdkWindow *window,
gint *axis_data,
gdouble *axis_out,
gdouble *x_out,
gdouble *y_out)
{
GdkWindowObject *priv, *impl_window;
GdkWindowImplWin32 *root_impl;
GdkWindowObject *window_object;
int i;
int x_axis = 0;
int y_axis = 0;
double device_width, device_height;
double device_width, device_height, x_min, y_min;
double x_offset, y_offset, x_scale, y_scale;
window_object = GDK_WINDOW_OBJECT (input_window);
priv = (GdkWindowObject *) window;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
for (i=0; i<gdkdev->info.num_axes; i++)
{
switch (gdkdev->info.axes[i].use)
{
case GDK_AXIS_X:
x_axis = i;
break;
case GDK_AXIS_Y:
y_axis = i;
break;
default:
break;
}
{
case GDK_AXIS_X:
x_axis = i;
break;
case GDK_AXIS_Y:
y_axis = i;
break;
default:
break;
}
}
device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
x_min = gdkdev->axes[x_axis].min_value;
device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
y_min = gdkdev->axes[y_axis].min_value;
if (gdkdev->info.mode == GDK_MODE_SCREEN)
{
@ -705,56 +713,56 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width;
y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height;
x_offset = - input_window->root_x;
y_offset = - input_window->root_y;
x_offset = - impl_window->input_window->root_x - priv->abs_x;
y_offset = - impl_window->input_window->root_y - priv->abs_y;
}
else /* GDK_MODE_WINDOW */
{
double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
(device_width*gdkdev->axes[x_axis].resolution);
double x_resolution = gdkdev->axes[x_axis].resolution;
double y_resolution = gdkdev->axes[y_axis].resolution;
double device_aspect = (device_height*y_resolution) / (device_width * x_resolution);
if (device_aspect * window_object->width >= window_object->height)
{
/* device taller than window */
x_scale = window_object->width / device_width;
y_scale = (x_scale * gdkdev->axes[x_axis].resolution) / gdkdev->axes[y_axis].resolution;
if (device_aspect * priv->width >= priv->height)
{
/* device taller than window */
x_scale = priv->width / device_width;
y_scale = (x_scale * x_resolution) / y_resolution;
x_offset = 0;
y_offset = -(device_height * y_scale - window_object->height) / 2;
}
x_offset = 0;
y_offset = -(device_height * y_scale - priv->height) / 2;
}
else
{
/* window taller than device */
y_scale = window_object->height / device_height;
x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
/ gdkdev->axes[x_axis].resolution;
{
/* window taller than device */
y_scale = priv->height / device_height;
x_scale = (y_scale * y_resolution) / x_resolution;
y_offset = 0;
x_offset = - (device_width * x_scale - window_object->width) / 2;
}
y_offset = 0;
x_offset = - (device_width * x_scale - priv->width) / 2;
}
}
for (i = 0; i < gdkdev->info.num_axes; i++)
{
switch (gdkdev->info.axes[i].use)
{
case GDK_AXIS_X:
axis_out[i] = x_offset + x_scale * axis_data[x_axis];
if (x_out)
*x_out = axis_out[i];
break;
case GDK_AXIS_Y:
axis_out[i] = y_offset + y_scale * axis_data[y_axis];
if (y_out)
*y_out = axis_out[i];
break;
default:
axis_out[i] =
(gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
break;
}
{
case GDK_AXIS_X:
axis_out[i] = x_offset + x_scale * axis_data[x_axis];
if (x_out)
*x_out = axis_out[i];
break;
case GDK_AXIS_Y:
axis_out[i] = y_offset + y_scale * axis_data[y_axis];
if (y_out)
*y_out = axis_out[i];
break;
default:
axis_out[i] =
(gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
break;
}
}
}
@ -763,25 +771,30 @@ gdk_input_get_root_relative_geometry (HWND w,
int *x_ret,
int *y_ret)
{
RECT rect;
POINT pt;
GetWindowRect (w, &rect);
pt.x = 0;
pt.y = 0;
ClientToScreen (w, &pt);
if (x_ret)
*x_ret = rect.left + _gdk_offset_x;
*x_ret = pt.x + _gdk_offset_x;
if (y_ret)
*y_ret = rect.top + _gdk_offset_y;
*y_ret = pt.y + _gdk_offset_y;
}
void
_gdk_input_configure_event (GdkWindow *window)
{
GdkInputWindow *input_window;
GdkWindowObject *impl_window;
int root_x, root_y;
input_window = _gdk_input_window_find (window);
g_return_if_fail (window != NULL);
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
input_window = impl_window->input_window;
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
&root_x, &root_y);
@ -789,21 +802,6 @@ _gdk_input_configure_event (GdkWindow *window)
input_window->root_y = root_y;
}
void
_gdk_input_enter_event (GdkWindow *window)
{
GdkInputWindow *input_window;
int root_x, root_y;
input_window = _gdk_input_window_find (window);
g_return_if_fail (window != NULL);
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &root_x, &root_y);
input_window->root_x = root_x;
input_window->root_y = root_y;
}
/*
* Get the currently active keyboard modifiers (ignoring the mouse buttons)
* We could use gdk_window_get_pointer but that function does a lot of other
@ -829,6 +827,7 @@ get_modifier_key_state (void)
return state;
}
#if 0
static guint ignore_core_timer = 0;
static gboolean
@ -867,18 +866,78 @@ set_ignore_core (gboolean ignore)
ignore_core_timefunc, NULL);
}
#endif
void
_gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev)
{
LOGCONTEXT lc;
if (gdkdev != _gdk_device_in_proximity)
return;
if (p_WTGetA (gdkdev->hctx, &lc))
{
if (gdkdev->info.mode == GDK_MODE_SCREEN &&
(lc.lcOptions & CXO_SYSTEM) == 0)
{
lc.lcOptions |= CXO_SYSTEM;
p_WTSetA (gdkdev->hctx, &lc);
}
else if (gdkdev->info.mode == GDK_MODE_WINDOW &&
(lc.lcOptions & CXO_SYSTEM) != 0)
{
lc.lcOptions &= ~CXO_SYSTEM;
p_WTSetA (gdkdev->hctx, &lc);
}
}
}
static GdkWindow *
find_window_for_input_event (MSG* msg, int *x, int *y)
{
POINT pt;
GdkWindow *window;
HWND hwnd;
RECT rect;
pt = msg->pt;
window = NULL;
hwnd = WindowFromPoint (pt);
if (hwnd != NULL)
{
POINT client_pt = pt;
ScreenToClient (hwnd, &client_pt);
GetClientRect (hwnd, &rect);
if (PtInRect (&rect, client_pt))
window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
}
/* need to also adjust the coordinates to the new window */
if (window)
ScreenToClient (GDK_WINDOW_HWND (window), &pt);
*x = pt.x;
*y = pt.y;
if (window)
return window;
return _gdk_root;
}
gboolean
_gdk_input_other_event (GdkEvent *event,
MSG *msg,
GdkWindow *window)
{
GdkDisplay *display;
GdkWindowObject *obj, *grab_obj;
GdkWindowObject *obj, *impl_window;
GdkWindow *native_window;
GdkInputWindow *input_window;
GdkDevicePrivate *gdkdev = NULL;
GdkEventMask masktest;
guint key_state;
POINT pt;
PACKET packet;
gint k;
@ -889,31 +948,24 @@ _gdk_input_other_event (GdkEvent *event,
*/
static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
if (event->any.window != wintab_window)
if (window != wintab_window)
{
g_warning ("_gdk_input_other_event: not wintab_window?");
return FALSE;
}
window = gdk_window_at_pointer (&x, &y);
if (window == NULL)
window = _gdk_root;
g_object_ref (window);
display = gdk_drawable_get_display (window);
native_window = find_window_for_input_event (msg, &x, &y);
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("_gdk_input_other_event: window=%p %+d%+d\n",
GDK_WINDOW_HWND (window), x, y));
if (msg->message == WT_PACKET)
g_print ("_gdk_input_other_event: native_window=%p %+d%+d\n",
GDK_WINDOW_HWND (native_window), x, y));
if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE)
{
if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet))
return FALSE;
}
obj = GDK_WINDOW_OBJECT (window);
switch (msg->message)
{
case WT_PACKET:
@ -925,11 +977,6 @@ _gdk_input_other_event (GdkEvent *event,
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
return FALSE;
}
if (window == _gdk_root && x_grab_window == NULL)
{
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n"));
return FALSE;
}
if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
packet.pkCursor)) == NULL)
@ -979,104 +1026,50 @@ _gdk_input_other_event (GdkEvent *event,
}
if (!(translated_buttons & button_mask))
{
event->any.type = GDK_BUTTON_RELEASE;
masktest = GDK_BUTTON_RELEASE_MASK;
}
event->any.type = GDK_BUTTON_RELEASE;
else
{
event->any.type = GDK_BUTTON_PRESS;
masktest = GDK_BUTTON_PRESS_MASK;
}
event->any.type = GDK_BUTTON_PRESS;
gdkdev->button_state ^= button_mask;
}
else
{
event->any.type = GDK_MOTION_NOTIFY;
masktest = GDK_POINTER_MOTION_MASK;
if (gdkdev->button_state & (1 << 0))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK;
if (gdkdev->button_state & (1 << 1))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK;
if (gdkdev->button_state & (1 << 2))
masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK;
}
/* See if input is grabbed */
/* FIXME: x_grab_owner_events should probably be handled somehow */
if (x_grab_window != NULL)
{
grab_obj = GDK_WINDOW_OBJECT (x_grab_window);
if (!GDK_WINDOW_IMPL_WIN32 (grab_obj->impl)->extension_events_selected
|| !(grab_obj->extension_events & masktest)
|| !(x_grab_mask && masktest))
{
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("... grabber doesn't want it\n"));
return FALSE;
}
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... to grabber\n"));
if (native_window == _gdk_root)
return FALSE;
g_object_ref(x_grab_window);
g_object_unref(window);
window = x_grab_window;
obj = grab_obj;
}
/* Now we can check if the window wants the event, and
* propagate if necessary.
*/
loop:
if (!GDK_WINDOW_IMPL_WIN32 (obj->impl)->extension_events_selected
|| !(obj->extension_events & masktest))
{
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n"));
window = _gdk_window_get_input_window_for_event (native_window,
event->any.type,
gdkdev->button_state << 8,
x, y, 0);
if (obj->parent == GDK_WINDOW_OBJECT (_gdk_root))
return FALSE;
obj = GDK_WINDOW_OBJECT (window);
/* It is not good to propagate the extended events up to the parent
* if this window wants normal (not extended) motion/button events */
if (obj->event_mask & masktest)
{
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("... wants ordinary event, ignoring this\n"));
return FALSE;
}
pt.x = x;
pt.y = y;
ClientToScreen (GDK_WINDOW_HWND (window), &pt);
g_object_unref (window);
window = (GdkWindow *) obj->parent;
obj = GDK_WINDOW_OBJECT (window);
g_object_ref (window);
ScreenToClient (GDK_WINDOW_HWND (window), &pt);
x = pt.x;
y = pt.y;
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n",
GDK_WINDOW_HWND (window), x, y));
goto loop;
}
input_window = _gdk_input_window_find (window);
if (window == NULL ||
obj->extension_events == 0)
return FALSE;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
input_window = impl_window->input_window;
g_assert (input_window != NULL);
if (gdkdev->info.mode == GDK_MODE_WINDOW
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
if (gdkdev->info.mode == GDK_MODE_WINDOW &&
(obj->extension_events & GDK_ALL_DEVICES_MASK) == 0)
return FALSE;
event->any.window = window;
key_state = get_modifier_key_state ();
if (event->any.type == GDK_BUTTON_PRESS
|| event->any.type == GDK_BUTTON_RELEASE)
if (event->any.type == GDK_BUTTON_PRESS ||
event->any.type == GDK_BUTTON_RELEASE)
{
event->button.time = _gdk_win32_get_next_tick (msg->time);
event->button.device = &gdkdev->info;
event->button.axes = g_new(gdouble, gdkdev->info.num_axes);
gdk_input_translate_coordinates (gdkdev, input_window,
gdk_input_translate_coordinates (gdkdev, window,
gdkdev->last_axis_data,
event->button.axes,
&event->button.x,
@ -1107,7 +1100,7 @@ _gdk_input_other_event (GdkEvent *event,
event->motion.axes = g_new(gdouble, gdkdev->info.num_axes);
gdk_input_translate_coordinates (gdkdev, input_window,
gdk_input_translate_coordinates (gdkdev, window,
gdkdev->last_axis_data,
event->motion.axes,
&event->motion.x,
@ -1130,49 +1123,104 @@ _gdk_input_other_event (GdkEvent *event,
}
return TRUE;
case WT_PROXIMITY:
if (LOWORD (msg->lParam) == 0)
{
event->proximity.type = GDK_PROXIMITY_OUT;
set_ignore_core (FALSE);
}
else
case WT_CSRCHANGE:
if ((gdkdev = gdk_input_find_dev_from_ctx ((HCTX) msg->lParam,
packet.pkCursor)) == NULL)
return FALSE;
_gdk_device_in_proximity = gdkdev;
_gdk_input_update_for_device_mode (gdkdev);
window = NULL;
if (native_window != _gdk_root)
window = _gdk_window_get_input_window_for_event (native_window,
GDK_PROXIMITY_IN,
0,
x, y, 0);
if (window)
{
event->proximity.type = GDK_PROXIMITY_IN;
set_ignore_core (TRUE);
event->proximity.window = window;
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
event->proximity.device = &_gdk_device_in_proximity->info;
}
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
event->proximity.device = &gdkdev->info;
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("WINTAB proximity %s\n",
(event->proximity.type == GDK_PROXIMITY_IN ?
"in" : "out")));
g_print ("WINTAB proximity in\n"));
return TRUE;
case WT_PROXIMITY:
/* TODO: Set ignore_core if in input_window */
if (LOWORD (msg->lParam) == 0)
{
_gdk_input_in_proximity = FALSE;
window = NULL;
if (native_window != _gdk_root)
window = _gdk_window_get_input_window_for_event (native_window,
GDK_PROXIMITY_IN,
0,
x, y, 0);
if (window)
{
event->proximity.type = GDK_PROXIMITY_OUT;
event->proximity.window = window;
event->proximity.time = _gdk_win32_get_next_tick (msg->time);
event->proximity.device = &_gdk_device_in_proximity->info;
}
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("WINTAB proximity out\n"));
return TRUE;
}
else
_gdk_input_in_proximity = TRUE;
_gdk_input_check_proximity ();
break;
}
return FALSE;
}
gboolean
_gdk_input_enable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev)
void
_gdk_input_select_events (GdkWindow *impl_window)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
guint event_mask;
GdkWindowObject *w;
GdkInputWindow *iw;
GList *l, *dev_list;
impl->extension_events_selected = TRUE;
iw = ((GdkWindowObject *)impl_window)->input_window;
return TRUE;
}
event_mask = 0;
for (dev_list = _gdk_input_devices; dev_list; dev_list = dev_list->next)
{
GdkDevicePrivate *gdkdev = dev_list->data;
gboolean
_gdk_input_disable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
if (!GDK_IS_CORE (gdkdev) &&
gdkdev->info.mode != GDK_MODE_DISABLED &&
iw != NULL)
{
for (l = iw->windows; l != NULL; l = l->next)
{
w = l->data;
if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
event_mask |= w->extension_events;
}
}
}
event_mask &= ~GDK_ALL_DEVICES_MASK;
if (event_mask)
event_mask |=
GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
impl->extension_events_selected = FALSE;
return TRUE;
GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *)impl_window)->impl)->extension_events_mask = event_mask;
}
gint
@ -1182,131 +1230,20 @@ _gdk_input_grab_pointer (GdkWindow *window,
GdkWindow *confine_to,
guint32 time)
{
GdkInputWindow *input_window, *new_window;
gboolean need_ungrab;
GdkDevicePrivate *gdkdev;
GList *tmp_list;
tmp_list = _gdk_input_windows;
new_window = NULL;
need_ungrab = FALSE;
GDK_NOTE (INPUT, g_print ("_gdk_input_grab_pointer: %p %d %p\n",
GDK_WINDOW_HWND (window),
owner_events,
(confine_to ? GDK_WINDOW_HWND (confine_to) : 0)));
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->window == window)
new_window = input_window;
else if (input_window->grabbed)
{
input_window->grabbed = FALSE;
need_ungrab = TRUE;
}
tmp_list = tmp_list->next;
}
if (new_window)
{
new_window->grabbed = TRUE;
x_grab_window = window;
x_grab_mask = event_mask;
x_grab_owner_events = owner_events;
/* FIXME: Do we need to handle confine_to and time? */
tmp_list = _gdk_input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx)
{
#if 0
/* XXX */
gdk_input_common_find_events (window, gdkdev,
event_mask,
event_classes, &num_classes);
result = XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
GDK_WINDOW_XWINDOW (window),
owner_events, num_classes, event_classes,
GrabModeAsync, GrabModeAsync, time);
/* FIXME: if failure occurs on something other than the first
device, things will be badly inconsistent */
if (result != Success)
return result;
#endif
}
tmp_list = tmp_list->next;
}
}
else
{
x_grab_window = NULL;
#if 0
tmp_list = _gdk_input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->hctx &&
((gdkdev->button_state != 0) || need_ungrab))
{
#if 0
/* XXX */
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
#endif
gdkdev->button_state = 0;
}
tmp_list = tmp_list->next;
}
#endif
}
return GDK_GRAB_SUCCESS;
}
void
_gdk_input_ungrab_pointer (guint32 time)
{
GdkInputWindow *input_window;
GdkDevicePrivate *gdkdev;
GList *tmp_list;
GDK_NOTE (INPUT, g_print ("_gdk_input_ungrab_pointer\n"));
tmp_list = _gdk_input_windows;
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->grabbed)
break;
tmp_list = tmp_list->next;
}
if (tmp_list) /* we found a grabbed window */
{
input_window->grabbed = FALSE;
tmp_list = _gdk_input_devices;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
#if 0
/* XXX */
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
XUngrabDevice (gdk_display, gdkdev->xdevice, time);
#endif
tmp_list = tmp_list->next;
}
}
x_grab_window = NULL;
}
gboolean
@ -1344,7 +1281,6 @@ gdk_device_get_state (GdkDevice *device,
else
{
GdkDevicePrivate *gdkdev;
GdkInputWindow *input_window;
gdkdev = (GdkDevicePrivate *)device;
/* For now just use the last known button and axis state of the device.
@ -1359,12 +1295,10 @@ gdk_device_get_state (GdkDevice *device,
| GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
| GDK_BUTTON5_MASK));
}
input_window = _gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
/* For some reason, input_window is sometimes NULL when I use The GIMP 2
* (bug #141543?). Avoid crashing if debugging is disabled. */
if (axes && gdkdev->last_axis_data && input_window)
gdk_input_translate_coordinates (gdkdev, input_window,
if (axes && gdkdev->last_axis_data)
gdk_input_translate_coordinates (gdkdev, window,
gdkdev->last_axis_data,
axes, NULL, NULL);
}
@ -1397,7 +1331,6 @@ _gdk_input_set_tablet_active (void)
void
_gdk_input_init (GdkDisplay *display)
{
_gdk_input_ignore_core = FALSE;
_gdk_input_devices = NULL;
_gdk_init_input_core (display);

View File

@ -70,24 +70,19 @@ struct _GdkDevicePrivate
AXIS orientation_axes[2];
};
/* Addition used for extension_events mask */
#define GDK_ALL_DEVICES_MASK (1<<30)
struct _GdkInputWindow
{
/* gdk window */
GdkWindow *window;
GList *windows; /* GdkWindow:s with extension_events set */
/* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */
GdkExtensionMode mode;
GdkWindow *impl_window; /* an impl window */
/* position relative to root window */
gint root_x;
gint root_y;
/* rectangles relative to window of windows obscuring this one */
GdkRectangle *obscuring;
gint num_obscuring;
/* Is there a pointer grab for this window ? */
gint grabbed;
};
/* Global data */
@ -97,7 +92,7 @@ struct _GdkInputWindow
extern GList *_gdk_input_devices;
extern GList *_gdk_input_windows;
extern gint _gdk_input_ignore_core;
extern gboolean _gdk_input_in_proximity;
/* Function declarations */
void _gdk_init_input_core (GdkDisplay *display);
@ -109,7 +104,6 @@ GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device,
* (just wintab for now)
*/
void _gdk_input_configure_event (GdkWindow *window);
void _gdk_input_enter_event (GdkWindow *window);
gboolean _gdk_input_other_event (GdkEvent *event,
MSG *msg,
GdkWindow *window);
@ -124,10 +118,7 @@ GdkInputWindow *_gdk_input_window_find (GdkWindow *window);
void _gdk_input_window_destroy (GdkWindow *window);
gint _gdk_input_enable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev);
gint _gdk_input_disable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev);
void _gdk_input_select_events (GdkWindow *impl_window);
gint _gdk_input_grab_pointer (GdkWindow *window,
gint owner_events,
GdkEventMask event_mask,
@ -143,5 +134,7 @@ gboolean _gdk_device_get_history (GdkDevice *device,
void _gdk_input_wintab_init_check (void);
void _gdk_input_set_tablet_active (void);
void _gdk_input_update_for_device_mode (GdkDevicePrivate *gdkdev);
void _gdk_input_check_proximity (void);
#endif /* __GDK_INPUT_WIN32_H__ */

View File

@ -46,10 +46,10 @@ static GdkDeviceAxis gdk_input_core_axes[] = {
/* Global variables */
gint _gdk_input_ignore_core;
GList *_gdk_input_devices;
GList *_gdk_input_windows;
gboolean _gdk_input_in_proximity = 0;
gboolean _gdk_input_inside_input_window = 0;
void
_gdk_init_input_core (GdkDisplay *display)
@ -291,30 +291,63 @@ gdk_device_free_history (GdkTimeCoord **events,
g_free (events);
}
GdkInputWindow *
_gdk_input_window_find(GdkWindow *window)
{
GList *tmp_list;
for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
if (((GdkInputWindow *)(tmp_list->data))->window == window)
return (GdkInputWindow *)(tmp_list->data);
return NULL; /* Not found */
}
/* FIXME: this routine currently needs to be called between creation
and the corresponding configure event (because it doesn't get the
root_relative_geometry). This should work with
gtk_window_set_extension_events, but will likely fail in other
cases */
static void
unset_extension_events (GdkWindow *window)
{
GdkWindowObject *window_private;
GdkWindowObject *impl_window;
GdkInputWindow *iw;
window_private = (GdkWindowObject*) window;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
iw = impl_window->input_window;
if (window_private->extension_events != 0)
{
g_assert (iw != NULL);
g_assert (g_list_find (iw->windows, window) != NULL);
iw->windows = g_list_remove (iw->windows, window);
if (iw->windows == NULL)
{
impl_window->input_window = NULL;
_gdk_input_windows = g_list_remove(_gdk_input_windows,iw);
g_free (iw);
}
}
window_private->extension_events = 0;
}
static void
gdk_input_get_root_relative_geometry (HWND w,
int *x_ret,
int *y_ret)
{
POINT pt;
pt.x = 0;
pt.y = 0;
ClientToScreen (w, &pt);
if (x_ret)
*x_ret = pt.x + _gdk_offset_x;
if (y_ret)
*y_ret = pt.y + _gdk_offset_y;
}
void
gdk_input_set_extension_events (GdkWindow *window, gint mask,
GdkExtensionMode mode)
{
GdkWindowObject *window_private;
GList *tmp_list;
GdkWindowObject *impl_window;
GdkInputWindow *iw;
g_return_if_fail (window != NULL);
@ -324,68 +357,81 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
if (GDK_WINDOW_DESTROYED (window))
return;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
if (mode == GDK_EXTENSION_EVENTS_ALL && mask != 0)
mask |= GDK_ALL_DEVICES_MASK;
if (mode == GDK_EXTENSION_EVENTS_NONE)
mask = 0;
iw = impl_window->input_window;
if (mask != 0)
{
_gdk_input_wintab_init_check ();
iw = g_new(GdkInputWindow,1);
if (!iw)
{
iw = g_new0 (GdkInputWindow,1);
iw->window = window;
iw->mode = mode;
iw->impl_window = (GdkWindow *)impl_window;
iw->obscuring = NULL;
iw->num_obscuring = 0;
iw->grabbed = FALSE;
iw->windows = NULL;
_gdk_input_windows = g_list_append(_gdk_input_windows,iw);
_gdk_input_windows = g_list_append(_gdk_input_windows, iw);
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window), &iw->root_x, &iw->root_y);
impl_window->input_window = iw;
}
if (window_private->extension_events == 0)
iw->windows = g_list_append (iw->windows, window);
window_private->extension_events = mask;
/* Add enter window events to the event mask */
if (g_list_length (_gdk_input_devices) > 1)
gdk_window_set_events (window,
gdk_window_get_events (window) |
GDK_ENTER_NOTIFY_MASK);
}
else
{
iw = _gdk_input_window_find (window);
if (iw)
{
_gdk_input_windows = g_list_remove(_gdk_input_windows,iw);
g_free(iw);
}
window_private->extension_events = 0;
unset_extension_events (window);
}
for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
{
GdkDevicePrivate *gdkdev = tmp_list->data;
if (!GDK_IS_CORE (gdkdev))
{
if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
&& (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
_gdk_input_enable_window (window,gdkdev);
else
_gdk_input_disable_window (window,gdkdev);
}
}
_gdk_input_select_events ((GdkWindow *)impl_window);
}
void
_gdk_input_window_destroy (GdkWindow *window)
{
GdkInputWindow *input_window;
unset_extension_events (window);
}
input_window = _gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
void
_gdk_input_check_proximity (void)
{
GList *l;
gboolean new_proximity = FALSE;
_gdk_input_windows = g_list_remove (_gdk_input_windows,input_window);
g_free(input_window);
if (!_gdk_input_inside_input_window)
{
_gdk_display->ignore_core_events = FALSE;
return;
}
for (l = _gdk_input_devices; l != NULL; l = l->next)
{
GdkDevicePrivate *gdkdev = l->data;
if (gdkdev->info.mode != GDK_MODE_DISABLED &&
!GDK_IS_CORE (gdkdev))
{
if (_gdk_input_in_proximity)
{
new_proximity = TRUE;
break;
}
}
}
_gdk_display->ignore_core_events = new_proximity;
}
void
@ -394,53 +440,27 @@ _gdk_input_crossing_event (GdkWindow *window,
{
if (enter)
{
#if 0 /* No idea what to do... */
GdkWindowObject *priv = (GdkWindowObject *)window;
GdkInputWindow *input_window;
gint root_x, root_y;
#if 0
gdk_input_check_proximity(display);
#endif
_gdk_input_inside_input_window = TRUE;
input_window = priv->input_window;
if (input_window != NULL)
{
_gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
gdk_input_get_root_relative_geometry (GDK_WINDOW_HWND (window),
&root_x, &root_y);
input_window->root_x = root_x;
input_window->root_y = root_y;
}
#endif
}
else
_gdk_input_ignore_core = FALSE;
}
void
_gdk_input_exit (void)
{
GList *tmp_list;
GdkDevicePrivate *gdkdev;
for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
{
gdkdev = (GdkDevicePrivate *)(tmp_list->data);
if (!GDK_IS_CORE (gdkdev))
{
gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED);
g_free(gdkdev->info.name);
g_free(gdkdev->axes);
g_free(gdkdev->info.axes);
g_free(gdkdev->info.keys);
g_free(gdkdev);
}
_gdk_input_inside_input_window = FALSE;
}
g_list_free(_gdk_input_devices);
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
g_free(tmp_list->data);
g_list_free(_gdk_input_windows);
_gdk_input_check_proximity ();
}
gboolean
@ -473,7 +493,6 @@ gdk_device_set_mode (GdkDevice *device,
{
GList *tmp_list;
GdkDevicePrivate *gdkdev;
GdkInputMode old_mode;
GdkInputWindow *input_window;
if (GDK_IS_CORE (device))
@ -484,39 +503,21 @@ gdk_device_set_mode (GdkDevice *device,
if (device->mode == mode)
return TRUE;
old_mode = device->mode;
device->mode = mode;
if (mode == GDK_MODE_WINDOW)
{
device->has_cursor = FALSE;
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
_gdk_input_enable_window (input_window->window, gdkdev);
else
if (old_mode != GDK_MODE_DISABLED)
_gdk_input_disable_window (input_window->window, gdkdev);
}
}
device->has_cursor = FALSE;
else if (mode == GDK_MODE_SCREEN)
device->has_cursor = TRUE;
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
{
device->has_cursor = TRUE;
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
_gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
gdkdev);
}
else /* mode == GDK_MODE_DISABLED */
{
for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (old_mode != GDK_MODE_WINDOW ||
input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
_gdk_input_disable_window (input_window->window, gdkdev);
}
input_window = (GdkInputWindow *)tmp_list->data;
_gdk_input_select_events (input_window->impl_window);
}
if (!GDK_IS_CORE (gdkdev))
_gdk_input_update_for_device_mode (gdkdev);
return TRUE;
}

View File

@ -305,7 +305,7 @@ void _gdk_wchar_text_handle (GdkFont *font,
void _gdk_push_modal_window (GdkWindow *window);
void _gdk_remove_modal_window (GdkWindow *window);
GdkWindow *_gdk_modal_current (void);
gboolean _gdk_modal_blocked (GdkWindow *window);
#ifdef G_ENABLE_DEBUG
gchar *_gdk_win32_color_to_string (const GdkColor *color);
@ -467,6 +467,8 @@ extern gint _gdk_max_colors;
/* TRUE while a modal sizing, moving, or dnd operation is in progress */
extern gboolean _modal_operation_in_progress;
extern HWND _modal_move_resize_window;
/* TRUE when we are emptying the clipboard ourselves */
extern gboolean _ignore_destroy_clipboard;
@ -491,7 +493,9 @@ HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
gboolean _gdk_win32_pixbuf_to_hicon_supports_alpha (void);
void _gdk_win32_append_event (GdkEvent *event);
void _gdk_win32_emit_configure_event (GdkWindow *window);
GdkWindow *_gdk_win32_find_window_for_mouse_event (GdkWindow* reported_window,
MSG* msg);
/* Initialization */
void _gdk_windowing_window_init (GdkScreen *screen);

View File

@ -584,14 +584,14 @@ gdk_selection_convert (GdkWindow *requestor,
* it.
*
* If the data is from Mozilla Firefox or IE7, and
* starts with an "oldfashioned" BITMAPINFOHEADER,
* starts with an "old fashioned" BITMAPINFOHEADER,
* i.e. with biSize==40, and biCompression == BI_RGB and
* biBitCount==32, we assume that the "extra" byte in
* each pixel in fact is alpha.
*
* The gdk-pixbuf bmp loader doesn't trust 32-bit BI_RGB
* nitmaps to in fact have alpha, so we have to convince
* it by changint the bitmap header to a version 5
* bitmaps to in fact have alpha, so we have to convince
* it by changing the bitmap header to a version 5
* BI_BITFIELDS one with explicit alpha mask indicated.
*
* The RGB bytes that are in bitmaps on the clipboard
@ -718,6 +718,17 @@ gdk_selection_convert (GdkWindow *requestor,
bi->biSize +
bi->biClrUsed * sizeof (RGBQUAD));
if (bi->biCompression == BI_BITFIELDS && bi->biBitCount >= 16)
{
/* Screenshots taken with PrintScreen or
* Alt + PrintScreen are found on the clipboard in
* this format. In this case the BITMAPINFOHEADER is
* followed by three DWORD specifying the masks of the
* red green and blue components, so adjust the offset
* accordingly. */
bf->bfOffBits += (3 * sizeof (DWORD));
}
memcpy ((char *) data + sizeof (BITMAPFILEHEADER),
bi,
data_length);

View File

@ -77,6 +77,7 @@ G_BEGIN_DECLS
/* Return true if the GdkWindow is a win32 implemented window */
gboolean gdk_win32_window_is_win32 (GdkWindow *window);
HWND gdk_win32_window_get_impl_hwnd (GdkWindow *window);
/* Return the Gdk* for a particular HANDLE */
gpointer gdk_win32_handle_table_lookup (GdkNativeWindow handle);

View File

@ -46,6 +46,15 @@ static void gdk_window_impl_win32_finalize (GObject *object);
static gpointer parent_class = NULL;
static GSList *modal_window_stack = NULL;
typedef struct _FullscreenInfo FullscreenInfo;
struct _FullscreenInfo
{
RECT r;
guint hint_flags;
LONG style;
};
static void update_style_bits (GdkWindow *window);
static gboolean _gdk_window_get_functions (GdkWindow *window,
GdkWMFunction *functions);
@ -116,7 +125,7 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
impl->hicon_small = NULL;
impl->hint_flags = 0;
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
impl->extension_events_selected = FALSE;
impl->extension_events_mask = 0;
impl->transient_owner = NULL;
impl->transient_children = NULL;
impl->num_transients = 0;
@ -497,9 +506,10 @@ _gdk_window_impl_new (GdkWindow *window,
GdkDrawableImplWin32 *draw_impl;
const gchar *title;
wchar_t *wtitle;
gboolean override_redirect;
gint window_width, window_height;
gint offset_x = 0, offset_y = 0;
gint x, y;
gint x, y, real_x = 0, real_y = 0;
/* check consistency of redundant information */
guint remaining_mask = attributes_mask;
@ -527,8 +537,12 @@ _gdk_window_impl_new (GdkWindow *window,
g_assert (attributes->y == private->y);
remaining_mask &= ~GDK_WA_Y;
}
override_redirect = FALSE;
if ((attributes_mask & GDK_WA_NOREDIR) != 0)
remaining_mask &= ~GDK_WA_NOREDIR;
{
override_redirect = !!attributes->override_redirect;
remaining_mask &= ~GDK_WA_NOREDIR;
}
if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_COLORMAP|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0)
g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X",
@ -544,7 +558,8 @@ _gdk_window_impl_new (GdkWindow *window,
if (attributes_mask & GDK_WA_VISUAL)
g_assert (visual == attributes->visual);
impl->extension_events_selected = FALSE;
impl->extension_events_mask = 0;
impl->override_redirect = override_redirect;
/* wclass is not any longer set always, but if is ... */
if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS)
@ -634,8 +649,22 @@ _gdk_window_impl_new (GdkWindow *window,
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
/* non child windows are placed by the OS/window manager */
x = y = CW_USEDEFAULT;
real_x = private->x - offset_x;
real_y = private->y - offset_y;
if (private->window_type == GDK_WINDOW_TOPLEVEL ||
private->window_type == GDK_WINDOW_DIALOG)
{
/* We initially place it at default so that we can get the
default window positioning if we want */
x = y = CW_USEDEFAULT;
}
else
{
/* TEMP, FOREIGN: Put these where requested */
x = real_x;
y = real_y;
}
window_width = rect.right - rect.left;
window_height = rect.bottom - rect.top;
@ -657,7 +686,7 @@ _gdk_window_impl_new (GdkWindow *window,
if (!title || !*title)
title = "";
private->event_mask = GDK_STRUCTURE_MASK | event_mask;
impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
if (attributes_mask & GDK_WA_TYPE_HINT)
gdk_window_set_type_hint (window, attributes->type_hint);
@ -702,6 +731,21 @@ _gdk_window_impl_new (GdkWindow *window,
}
if (private->window_type != GDK_WINDOW_CHILD)
{
GetWindowRect (GDK_WINDOW_HWND (window), &rect);
impl->initial_x = rect.left;
impl->initial_y = rect.top;
/* Now we know the initial position, move to actually specified position */
if (real_x != x || real_y != y)
{
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
real_x, real_y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
}
}
g_object_ref (window);
gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
@ -826,9 +870,6 @@ _gdk_win32_window_destroy (GdkWindow *window,
GDK_NOTE (MISC, g_print ("_gdk_win32_window_destroy: %p\n",
GDK_WINDOW_HWND (window)));
if (private->extension_events != 0)
_gdk_input_window_destroy (window);
/* Remove ourself from the modal stack */
_gdk_remove_modal_window (window);
@ -858,8 +899,6 @@ _gdk_win32_window_destroy (GdkWindow *window,
private->destroyed = TRUE;
DestroyWindow (GDK_WINDOW_HWND (window));
}
gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
}
void
@ -926,7 +965,9 @@ adjust_for_gravity_hints (GdkWindow *window,
if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
{
#ifdef G_ENABLE_DEBUG
gint orig_x = *x, orig_y = *y;
#endif
switch (impl->hints.win_gravity)
{
@ -985,34 +1026,32 @@ adjust_for_gravity_hints (GdkWindow *window,
static void
show_window_internal (GdkWindow *window,
gboolean raise,
gboolean already_mapped,
gboolean deiconify)
{
GdkWindowObject *private;
HWND old_active_window;
gboolean focus_on_map = TRUE;
GdkWindowImplWin32 *window_impl;
gboolean focus_on_map = FALSE;
DWORD exstyle;
HWND top;
private = (GdkWindowObject *) window;
if (private->destroyed)
return;
GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s\n",
GDK_WINDOW_HWND (window),
_gdk_win32_window_state_to_string (private->state),
(raise ? " raise" : ""),
(deiconify ? " deiconify" : "")));
/* If asked to show (not deiconify) an withdrawn and iconified
* window, do that.
*/
if (!deiconify &&
!GDK_WINDOW_IS_MAPPED (window) &&
!already_mapped &&
(private->state & GDK_WINDOW_STATE_ICONIFIED))
{
ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
return;
}
@ -1030,50 +1069,153 @@ show_window_internal (GdkWindow *window,
/* If asked to show (but not raise) a window that is already
* visible, do nothing.
*/
if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
if (!deiconify && !already_mapped && IsWindowVisible (GDK_WINDOW_HWND (window)))
return;
/* Other cases */
if (!GDK_WINDOW_IS_MAPPED (window))
{
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_WITHDRAWN,
0);
focus_on_map = private->focus_on_map;
}
if (!already_mapped)
focus_on_map = private->focus_on_map;
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
if (private->state & GDK_WINDOW_STATE_BELOW)
exstyle &= (~WS_EX_TOPMOST);
if (private->state & GDK_WINDOW_STATE_ABOVE)
exstyle |= WS_EX_TOPMOST;
if (exstyle & WS_EX_TOPMOST)
top = HWND_TOPMOST;
else
top = HWND_TOP;
/* Use SetWindowPos to show transparent windows so automatic redraws
* in other windows can be suppressed.
*/
if (exstyle & WS_EX_TRANSPARENT)
{
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
if (!raise)
flags |= SWP_NOZORDER;
if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
flags |= SWP_NOACTIVATE;
SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
return;
}
old_active_window = GetActiveWindow ();
/* For initial map of "normal" windows we want to emulate WM window
* positioning behaviour, which means:
* + Use user specified position if GDK_HINT_POS or GDK_HINT_USER_POS
* otherwise:
* + default to the initial CW_USEDEFAULT placement,
* no matter if the user moved the window before showing it.
* + Certain window types and hints have more elaborate positioning
* schemes.
*/
window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
if (!already_mapped &&
(GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG) &&
(window_impl->hint_flags & (GDK_HINT_POS | GDK_HINT_USER_POS)) == 0 &&
!window_impl->override_redirect)
{
gboolean center = FALSE;
RECT window_rect, center_on_rect;
int x, y;
x = window_impl->initial_x;
y = window_impl->initial_y;
if (window_impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
{
HMONITOR monitor;
MONITORINFO mi;
monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof (mi);
if (monitor && GetMonitorInfo (monitor, &mi))
center_on_rect = mi.rcMonitor;
else
{
center_on_rect.left = 0;
center_on_rect.right = 0;
center_on_rect.right = GetSystemMetrics (SM_CXSCREEN);
center_on_rect.bottom = GetSystemMetrics (SM_CYSCREEN);
}
center = TRUE;
}
else if (window_impl->transient_owner != NULL &&
GDK_WINDOW_IS_MAPPED (window_impl->transient_owner))
{
GdkWindowObject *owner = GDK_WINDOW_OBJECT (window_impl->transient_owner);
/* Center on transient parent */
center_on_rect.left = owner->x;
center_on_rect.top = owner->y;
center_on_rect.right = center_on_rect.left + owner->width;
center_on_rect.bottom = center_on_rect.top + owner->height;
_gdk_win32_adjust_client_rect (GDK_WINDOW (owner), &center_on_rect);
center = TRUE;
}
if (center)
{
window_rect.left = 0;
window_rect.top = 0;
window_rect.right = private->width;
window_rect.bottom = private->height;
_gdk_win32_adjust_client_rect (window, &window_rect);
x = center_on_rect.left + ((center_on_rect.right - center_on_rect.left) - (window_rect.right - window_rect.left)) / 2;
y = center_on_rect.top + ((center_on_rect.bottom - center_on_rect.top) - (window_rect.bottom - window_rect.top)) / 2;
}
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
x, y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
}
if (!already_mapped &&
(GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG) &&
!window_impl->override_redirect)
{
/* Ensure new windows are fully onscreen */
RECT window_rect;
HMONITOR monitor;
MONITORINFO mi;
int x, y;
GetWindowRect (GDK_WINDOW_HWND (window), &window_rect);
monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof (mi);
if (monitor && GetMonitorInfo (monitor, &mi))
{
x = window_rect.left;
y = window_rect.top;
if (window_rect.right > mi.rcWork.right)
{
window_rect.left -= (window_rect.right - mi.rcWork.right);
window_rect.right -= (window_rect.right - mi.rcWork.right);
}
if (window_rect.bottom > mi.rcWork.bottom)
{
window_rect.top -= (window_rect.bottom - mi.rcWork.bottom);
window_rect.bottom -= (window_rect.bottom - mi.rcWork.bottom);
}
if (window_rect.left < mi.rcWork.left)
{
window_rect.right += (mi.rcWork.left - window_rect.left);
window_rect.left += (mi.rcWork.left - window_rect.left);
}
if (window_rect.top < mi.rcWork.top)
{
window_rect.bottom += (mi.rcWork.top - window_rect.top);
window_rect.top += (mi.rcWork.top - window_rect.top);
}
if (x != window_rect.left || y != window_rect.top)
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
window_rect.left, window_rect.top, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
}
}
if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
{
@ -1085,7 +1227,10 @@ show_window_internal (GdkWindow *window,
}
else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
{
ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
if (focus_on_map)
ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
else
ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
}
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
{
@ -1096,38 +1241,16 @@ show_window_internal (GdkWindow *window,
ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
}
if (raise)
/* Sync STATE_ABOVE to TOPMOST */
if (((private->state & GDK_WINDOW_STATE_ABOVE) &&
!(exstyle & WS_EX_TOPMOST)) ||
(!(private->state & GDK_WINDOW_STATE_ABOVE) &&
(exstyle & WS_EX_TOPMOST)))
{
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
{
if (focus_on_map && private->accept_focus)
{
SetForegroundWindow (GDK_WINDOW_HWND (window));
if (top == HWND_TOPMOST)
SetWindowPos (GDK_WINDOW_HWND (window), top,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
else
{
SetWindowPos (GDK_WINDOW_HWND (window), top,
0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
}
else
{
BringWindowToTop (GDK_WINDOW_HWND (window));
}
}
else if (old_active_window != GDK_WINDOW_HWND (window))
{
SetActiveWindow (old_active_window);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
(private->state & GDK_WINDOW_STATE_ABOVE)?HWND_TOPMOST:HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
}
@ -1351,6 +1474,17 @@ gdk_win32_window_move_resize (GdkWindow *window,
gint width,
gint height)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplWin32 *window_impl;
window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
window_impl->inhibit_configure = TRUE;
/* We ignore changes to the window being moved or resized by the
user, as we don't want to fight the user */
if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
goto out;
if (with_move && (width < 0 && height < 0))
{
gdk_win32_window_move (window, x, y);
@ -1366,6 +1500,12 @@ gdk_win32_window_move_resize (GdkWindow *window,
gdk_win32_window_resize (window, width, height);
}
}
out:
window_impl->inhibit_configure = FALSE;
if (WINDOW_IS_TOPLEVEL (window))
_gdk_win32_emit_configure_event (window);
}
static gboolean
@ -1872,6 +2012,7 @@ gdk_window_set_geometry_hints (GdkWindow *window,
GdkWindowHints geom_mask)
{
GdkWindowImplWin32 *impl;
FullscreenInfo *fi;
g_return_if_fail (GDK_IS_WINDOW (window));
@ -1883,7 +2024,11 @@ gdk_window_set_geometry_hints (GdkWindow *window,
impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
impl->hint_flags = geom_mask;
fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
if (fi)
fi->hint_flags = geom_mask;
else
impl->hint_flags = geom_mask;
impl->hints = *geometry;
if (geom_mask & GDK_HINT_POS)
@ -2069,24 +2214,40 @@ _gdk_remove_modal_window (GdkWindow *window)
}
}
gboolean
_gdk_modal_blocked (GdkWindow *window)
{
GSList *l;
gboolean found_any = FALSE;
for (l = modal_window_stack; l != NULL; l = l->next)
{
GdkWindow *modal = l->data;
if (modal == window)
return FALSE;
if (GDK_WINDOW_IS_MAPPED (modal))
found_any = TRUE;
}
return found_any;
}
GdkWindow *
_gdk_modal_current (void)
{
if (modal_window_stack != NULL)
{
GSList *tmp = modal_window_stack;
GSList *l;
while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
{
tmp = g_slist_next (tmp);
}
return tmp != NULL ? tmp->data : NULL;
}
else
for (l = modal_window_stack; l != NULL; l = l->next)
{
return NULL;
GdkWindow *modal = l->data;
if (GDK_WINDOW_IS_MAPPED (modal))
return modal;
}
return NULL;
}
static void
@ -2581,6 +2742,16 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
screen_to_client (hwnd, screen_pt, &client_pt);
hwndc = ChildWindowFromPointEx (hwnd, client_pt, CWP_SKIPDISABLED |
CWP_SKIPINVISIBLE);
/* Verify that we're really inside the client area of the window */
if (hwndc != hwnd)
{
GetClientRect (hwndc, &rect);
screen_to_client (hwndc, screen_pt, &client_pt);
if (!PtInRect (&rect, client_pt))
hwndc = hwnd;
}
} while (hwndc != hwnd && (hwnd = hwndc, 1));
}
@ -2588,6 +2759,12 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
{
hwnd = WindowFromPoint (screen_pt);
/* Verify that we're really inside the client area of the window */
GetClientRect (hwnd, &rect);
screen_to_client (hwnd, screen_pt, &client_pt);
if (!PtInRect (&rect, client_pt))
hwnd = NULL;
/* If we didn't hit any window at that point, return the desktop */
if (hwnd == NULL)
{
@ -2603,13 +2780,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
if (window && (win_x || win_y))
{
screen_to_client (hwnd, screen_pt, &client_pt);
GetClientRect (hwnd, &rect);
if (win_x)
*win_x = client_pt.x - rect.left;
*win_x = client_pt.x;
if (win_y)
*win_y = client_pt.y - rect.top;
*win_y = client_pt.y;
}
GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
@ -2623,21 +2797,29 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
static GdkEventMask
gdk_win32_window_get_events (GdkWindow *window)
{
GdkWindowImplWin32 *impl;
if (GDK_WINDOW_DESTROYED (window))
return 0;
return GDK_WINDOW_OBJECT (window)->event_mask;
impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
return impl->native_event_mask;
}
static void
gdk_win32_window_set_events (GdkWindow *window,
GdkEventMask event_mask)
GdkEventMask event_mask)
{
GdkWindowImplWin32 *impl;
impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
/* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
* set it here, too. Not that I know or remember why it is
* necessary, will have to test some day.
*/
GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
}
static void
@ -2700,9 +2882,15 @@ void
gdk_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)
{
GdkWindowObject *private;
GdkWindowImplWin32 *window_impl;
g_return_if_fail (GDK_IS_WINDOW (window));
g_warning ("gdk_window_set_override_redirect not implemented");
private = (GdkWindowObject *) window;
window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
window_impl->override_redirect = !!override_redirect;
}
void
@ -2912,6 +3100,9 @@ update_style_bits (GdkWindow *window)
gboolean all;
RECT rect, before, after;
if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
return;
old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
@ -3107,7 +3298,7 @@ gboolean
_gdk_window_get_functions (GdkWindow *window,
GdkWMFunction *functions)
{
GdkWMDecoration* functions_set;
GdkWMFunction* functions_set;
functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
if (functions_set)
@ -3271,7 +3462,7 @@ gdk_window_deiconify (GdkWindow *window)
if (GDK_WINDOW_IS_MAPPED (window))
{
show_window_internal (window, FALSE, TRUE);
show_window_internal (window, GDK_WINDOW_IS_MAPPED (window), TRUE);
}
else
{
@ -3343,15 +3534,6 @@ gdk_window_unmaximize (GdkWindow *window)
0);
}
typedef struct _FullscreenInfo FullscreenInfo;
struct _FullscreenInfo
{
RECT r;
guint hint_flags;
LONG style;
};
void
gdk_window_fullscreen (GdkWindow *window)
{
@ -3393,14 +3575,15 @@ gdk_window_fullscreen (GdkWindow *window)
g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
/* Send state change before configure event */
gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
(fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
x, y, width, height,
SWP_NOCOPYBITS | SWP_SHOWWINDOW));
gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
}
}
@ -3417,6 +3600,8 @@ gdk_window_unfullscreen (GdkWindow *window)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
impl->hint_flags = fi->hint_flags;
SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
@ -3426,8 +3611,7 @@ gdk_window_unfullscreen (GdkWindow *window)
g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
g_free (fi);
gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
update_style_bits (window);
}
}
@ -3451,10 +3635,10 @@ gdk_window_set_keep_above (GdkWindow *window,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
else
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
setting ? GDK_WINDOW_STATE_ABOVE : 0);
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
setting ? GDK_WINDOW_STATE_ABOVE : 0);
}
void
@ -3477,10 +3661,10 @@ gdk_window_set_keep_below (GdkWindow *window,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
}
else
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
setting ? GDK_WINDOW_STATE_BELOW : 0);
gdk_synthesize_window_state (window,
setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
setting ? GDK_WINDOW_STATE_BELOW : 0);
}
void
@ -3725,9 +3909,9 @@ gdk_window_set_opacity (GdkWindow *window,
exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
if (!(exstyle & WS_EX_LAYERED))
API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
GWL_EXSTYLE,
exstyle | WS_EX_LAYERED));
SetWindowLong (GDK_WINDOW_HWND (window),
GWL_EXSTYLE,
exstyle | WS_EX_LAYERED);
setLayeredWindowAttributes =
(PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
@ -3906,6 +4090,15 @@ gdk_win32_window_is_win32 (GdkWindow *window)
return GDK_WINDOW_IS_WIN32 (window);
}
HWND
gdk_win32_window_get_impl_hwnd (GdkWindow *window)
{
if (GDK_WINDOW_IS_WIN32 (window))
return GDK_WINDOW_HWND (window);
return NULL;
}
GdkDrawable *
gdk_win32_begin_direct_draw_libgtk_only (GdkDrawable *drawable,
GdkGC *gc,

View File

@ -80,16 +80,23 @@ struct _GdkWindowImplWin32
gint hint_flags;
GdkGeometry hints;
GdkEventMask native_event_mask;
GdkWindowTypeHint type_hint;
gboolean extension_events_selected;
GdkEventMask extension_events_mask;
GdkWindow *transient_owner;
GSList *transient_children;
gint num_transients;
gboolean changing_state;
gint initial_x;
gint initial_y;
guint no_bg : 1;
guint inhibit_configure : 1;
guint override_redirect : 1;
};
struct _GdkWindowImplWin32Class

View File

@ -266,6 +266,8 @@ _gdk_input_other_event (GdkEvent *event,
else
window = _gdk_window_get_input_window_for_event (event_window,
event_type,
/* TODO: Seems wrong, but the code used to ignore button motion handling here... */
0,
x, y,
xevent->xany.serial);
priv = (GdkWindowObject *)window;

View File

@ -3630,6 +3630,8 @@ shortcuts_pane_create (GtkFileChooserDefault *impl,
/* Box for buttons */
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);

View File

@ -72,7 +72,7 @@ static void win32_poll_status (GtkPrintOperation *op);
static const GUID myIID_IPrintDialogCallback = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
#if !defined (_MSC_VER) && !defined (__MINGW64_VERSION_MAJOR)
#if !defined (_MSC_VER) && !defined (HAVE_IPRINTDIALOGCALLBACK)
#undef INTERFACE
#define INTERFACE IPrintDialogCallback
DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)

View File

@ -292,7 +292,11 @@ gtk_settings_class_init (GtkSettingsClass *class)
g_param_spec_string ("gtk-theme-name",
P_("Theme Name"),
P_("Name of theme RC file to load"),
#ifdef G_OS_WIN32
"MS-Windows",
#else
"Raleigh",
#endif
GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_THEME_NAME);

View File

@ -114,6 +114,7 @@ struct _GtkStatusIconPrivate
#ifdef GDK_WINDOWING_WIN32
GtkWidget *dummy_widget;
NOTIFYICONDATAW nid;
gint taskbar_top;
gint last_click_x, last_click_y;
GtkOrientation orientation;
gchar *tooltip_text;
@ -889,6 +890,8 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
priv->orientation = GTK_ORIENTATION_VERTICAL;
else
priv->orientation = GTK_ORIENTATION_HORIZONTAL;
priv->taskbar_top = abd.rc.top;
}
priv->last_click_x = priv->last_click_y = 0;
@ -2568,6 +2571,7 @@ gtk_status_icon_position_menu (GtkMenu *menu,
#ifdef GDK_WINDOWING_WIN32
GtkStatusIcon *status_icon;
GtkStatusIconPrivate *priv;
GtkRequisition menu_req;
g_return_if_fail (GTK_IS_MENU (menu));
g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
@ -2575,8 +2579,11 @@ gtk_status_icon_position_menu (GtkMenu *menu,
status_icon = GTK_STATUS_ICON (user_data);
priv = status_icon->priv;
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
*x = priv->last_click_x;
*y = priv->last_click_y;
*y = priv->taskbar_top - menu_req.height;
*push_in = TRUE;
#endif
}

View File

@ -41,7 +41,7 @@
#include <string.h>
#include <stdio.h>
#include "gtk/gtk.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#ifdef BUILDING_STANDALONE
@ -660,8 +660,9 @@ setup_msw_rc_style (void)
btn_face.red, btn_face.green, btn_face.blue);
gtk_rc_parse_string (buf);
/* enable coloring for text on buttons TODO: use GetThemeMetric for the
border and outside border */
/* enable coloring for text on buttons
* TODO: use GetThemeMetric for the border and outside border
* TODO: child-displacement-x & y should be 0 when XP theme is active */
g_snprintf (buf, sizeof (buf),
"style \"msw-button\" = \"msw-default\"\n"
"{\n"
@ -849,7 +850,7 @@ setup_system_styles (GtkStyle *style)
sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
&style->fg[GTK_STATE_INSENSITIVE]);
sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
&style->bg[GTK_STATE_ACTIVE]);
&style->fg[GTK_STATE_ACTIVE]);
sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
&style->fg[GTK_STATE_PRELIGHT]);
@ -2347,231 +2348,290 @@ DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
DrawEdge (hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
}
static void
get_notebook_tab_position (GtkNotebook *notebook,
gboolean *start,
gboolean *end)
{
gboolean found_start = FALSE, found_end = FALSE;
gint i, n_pages;
/* default value */
*start = TRUE;
*end = FALSE;
n_pages = gtk_notebook_get_n_pages (notebook);
for (i = 0; i < n_pages; i++)
{
GtkWidget *tab_child;
GtkWidget *tab_label;
gboolean expand;
GtkPackType pack_type;
gboolean is_selected;
tab_child = gtk_notebook_get_nth_page (notebook, i);
is_selected = gtk_notebook_get_current_page (notebook) == i;
/* Skip invisible tabs */
tab_label = gtk_notebook_get_tab_label (notebook, tab_child);
if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label))
continue;
/* Mimics what the notebook does internally. */
if (tab_label && !gtk_widget_get_child_visible (tab_label))
{
/* One child is hidden because scroll arrows are present.
* So both corners are rounded. */
*start = FALSE;
*end = FALSE;
return;
}
gtk_notebook_query_tab_label_packing (notebook, tab_child, &expand,
NULL, /* don't need fill */
&pack_type);
if (pack_type == GTK_PACK_START)
{
if (!found_start)
{
/* This is the first tab with PACK_START pack type */
found_start = TRUE;
if (is_selected)
{
/* first PACK_START item is selected: set start to TRUE */
*start = TRUE;
if (expand && !found_end)
{
/* tentatively set end to TRUE: will be invalidated if we
* find other items */
*end = TRUE;
}
}
else
{
*start = FALSE;
}
}
else if (!found_end && !is_selected)
{
/* an unselected item exists, and no item with PACK_END pack type */
*end = FALSE;
}
}
if (pack_type == GTK_PACK_END)
{
if (!found_end)
{
/* This is the first tab with PACK_END pack type */
found_end = TRUE;
if (is_selected)
{
/* first PACK_END item is selected: set end to TRUE */
*end = TRUE;
if (expand && !found_start)
{
/* tentatively set start to TRUE: will be invalidated if
* we find other items */
*start = TRUE;
}
}
else
{
*end = FALSE;
}
}
else if (!found_start && !is_selected)
{
*start = FALSE;
}
}
}
}
static gboolean
draw_themed_tab_button (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GtkNotebook *notebook,
gint x, gint y,
gint width, gint height, gint gap_side)
gint x,
gint y,
gint width,
gint height,
gint gap_side)
{
GdkPixmap *pixmap = NULL;
gint border_width =
gtk_container_get_border_width (GTK_CONTAINER (notebook));
GtkWidget *widget = GTK_WIDGET (notebook);
GdkRectangle draw_rect, clip_rect;
GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
cairo_t *cr;
gboolean start, stop;
XpThemeElement element;
gint d_w, d_h;
if (gap_side == GTK_POS_TOP)
get_notebook_tab_position (notebook, &start, &stop);
if (state_type == GTK_STATE_NORMAL)
{
int widget_right;
if (state_type == GTK_STATE_NORMAL)
{
draw_rect.x = x;
draw_rect.y = y;
draw_rect.width = width + 2;
draw_rect.height = height;
clip_rect = draw_rect;
clip_rect.height--;
}
if (start && stop)
{
/* Both edges of the notebook are covered by the item */
element = XP_THEME_ELEMENT_TAB_ITEM_BOTH_EDGE;
}
else if (start)
{
/* The start edge is covered by the item */
element = XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE;
}
else if (stop)
{
/* the stop edge is reached by the item */
element = XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE;
}
else
{
draw_rect.x = x + 2;
draw_rect.y = y;
draw_rect.width = width - 2;
draw_rect.height = height - 2;
clip_rect = draw_rect;
}
/* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
if (draw_rect.x + draw_rect.width >= widget_right)
{
draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
}
}
if (gap_side == GTK_POS_BOTTOM)
{
int widget_right;
if (state_type == GTK_STATE_NORMAL)
{
draw_rect.x = x;
draw_rect.y = y;
draw_rect.width = width + 2;
draw_rect.height = height;
clip_rect = draw_rect;
}
else
{
draw_rect.x = x + 2;
draw_rect.y = y + 2;
draw_rect.width = width - 2;
draw_rect.height = height - 2;
clip_rect = draw_rect;
}
/* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
if (draw_rect.x + draw_rect.width >= widget_right)
{
draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
}
rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
}
else if (gap_side == GTK_POS_LEFT)
{
int widget_bottom;
if (state_type == GTK_STATE_NORMAL)
{
draw_rect.x = x;
draw_rect.y = y;
draw_rect.width = width;
draw_rect.height = height + 2;
clip_rect = draw_rect;
clip_rect.width--;
}
else
{
draw_rect.x = x;
draw_rect.y = y + 2;
draw_rect.width = width - 2;
draw_rect.height = height - 2;
clip_rect = draw_rect;
}
/* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
if (draw_rect.y + draw_rect.height >= widget_bottom)
{
draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
}
rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
}
else if (gap_side == GTK_POS_RIGHT)
{
int widget_bottom;
if (state_type == GTK_STATE_NORMAL)
{
draw_rect.x = x + 1;
draw_rect.y = y;
draw_rect.width = width;
draw_rect.height = height + 2;
clip_rect = draw_rect;
clip_rect.width--;
}
else
{
draw_rect.x = x + 2;
draw_rect.y = y + 2;
draw_rect.width = width - 2;
draw_rect.height = height - 2;
clip_rect = draw_rect;
}
/* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
if (draw_rect.y + draw_rect.height >= widget_bottom)
{
draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
}
rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
}
if (gap_side == GTK_POS_TOP)
{
if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
draw_rect.x, draw_rect.y,
draw_rect.width, draw_rect.height,
state_type, &clip_rect))
{
return FALSE;
}
{
/* no edge should be aligned with the tab */
element = XP_THEME_ELEMENT_TAB_ITEM;
}
}
else
{
GdkPixbuf *pixbuf;
GdkPixbuf *rotated;
if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
{
pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
draw_rect.height, draw_rect.width, state_type, 0))
{
g_object_unref (pixmap);
return FALSE;
}
pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
clip_rect.height, clip_rect.width);
g_object_unref (pixmap);
}
else
{
pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
draw_rect.width, draw_rect.height, state_type, 0))
{
g_object_unref (pixmap);
return FALSE;
}
pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
clip_rect.width, clip_rect.height);
g_object_unref (pixmap);
}
rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
g_object_unref (pixbuf);
pixbuf = rotated;
// XXX - This is really hacky and evil. When we're drawing the left-most tab
// while it is active on a bottom-oriented notebook, there is one white
// pixel at the top. There may be a better solution than this if someone
// has time to discover it.
if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
&& x == widget->allocation.x)
{
int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
int psub = 0;
guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
guchar *p = pixels + rowstride;
for (psub = 0; psub < n_channels; psub++)
{
pixels[psub] = p[psub];
}
}
cr = gdk_cairo_create (window);
gdk_cairo_set_source_pixbuf (cr, pixbuf, clip_rect.x, clip_rect.y);
cairo_paint (cr);
cairo_destroy (cr);
g_object_unref (pixbuf);
/* Ideally, we should do the same here. Unfortunately, we don't have ways
* to determine what tab widget is actually being drawn here, so we can't
* determine its position relative to the borders */
element = XP_THEME_ELEMENT_TAB_ITEM;
}
draw_rect.x = x;
draw_rect.y = y;
draw_rect.width = width;
draw_rect.height = height;
/* Perform adjustments required to have the theme perfectly aligned */
if (state_type == GTK_STATE_ACTIVE)
{
switch (gap_side)
{
case GTK_POS_TOP:
draw_rect.x += 2;
draw_rect.width -= 2;
draw_rect.height -= 1;
break;
case GTK_POS_BOTTOM:
draw_rect.x += 2;
draw_rect.width -= 2;
draw_rect.y += 1;
draw_rect.height -= 1;
break;
case GTK_POS_LEFT:
draw_rect.y += 2;
draw_rect.height -= 2;
draw_rect.width -= 1;
break;
case GTK_POS_RIGHT:
draw_rect.y += 2;
draw_rect.height -= 2;
draw_rect.x += 1;
draw_rect.width -= 1;
break;
}
}
else
{
switch (gap_side)
{
case GTK_POS_TOP:
draw_rect.height += 1;
draw_rect.width += 2;
break;
case GTK_POS_BOTTOM:
draw_rect.y -= 1;
draw_rect.height += 1;
draw_rect.width += 2;
break;
case GTK_POS_LEFT:
draw_rect.width += 1;
draw_rect.height += 2;
break;
case GTK_POS_RIGHT:
draw_rect.x -= 1;
draw_rect.width += 1;
draw_rect.height += 2;
break;
}
}
clip_rect = draw_rect;
/* Take care of obvious case where the clipping is an empty region */
if (clip_rect.width <= 0 || clip_rect.height <= 0)
return TRUE;
/* Simple case: tabs on top are just drawn as is */
if (gap_side == GTK_POS_TOP)
{
return xp_theme_draw (window, element, style,
draw_rect.x, draw_rect.y,
draw_rect.width, draw_rect.height,
state_type, &clip_rect);
}
/* For other cases, we need to print the tab on a pixmap, and then rotate
* it according to the gap side */
if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
{
/* pixmap will have width/height inverted as we'll rotate +- PI / 2 */
d_w = draw_rect.height;
d_h = draw_rect.width;
}
else
{
d_w = draw_rect.width;
d_h = draw_rect.height;
}
pixmap = gdk_pixmap_new (window, d_w, d_h, -1);
/* First copy the previously saved window background */
cr = gdk_cairo_create (pixmap);
/* pixmaps unfortunately don't handle the alpha channel. We then
* paint it first in white, hoping the actual background is clear */
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_destroy (cr);
if (!xp_theme_draw (pixmap, element, style, 0, 0, d_w, d_h, state_type, 0))
{
g_object_unref (pixmap);
return FALSE;
}
/* Now we have the pixmap, we need to flip/rotate it according to its
* final position. We'll do it using cairo on the dest window */
cr = gdk_cairo_create (window);
cairo_rectangle (cr, clip_rect.x, clip_rect.y,
clip_rect.width, clip_rect.height);
cairo_clip (cr);
cairo_translate(cr, draw_rect.x + draw_rect.width * 0.5,
draw_rect.y + draw_rect.height * 0.5);
if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT) {
cairo_rotate (cr, M_PI/2.0);
}
if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_BOTTOM) {
cairo_scale (cr, 1, -1);
}
cairo_translate(cr, -d_w * 0.5, -d_h * 0.5);
gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
return TRUE;
}
@ -2643,67 +2703,68 @@ draw_extension (GtkStyle *style,
{
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
/* Why this differs from gap_side, I have no idea.. */
int real_gap_side = gtk_notebook_get_tab_pos (notebook);
/* draw_themed_tab_button and draw_tab_button expect to work with tab
* position, instead of simply taking the "side of the gap" (gap_side)
* which simply said is the side of the tab that touches the notebook
* frame and is always the exact opposite of the gap side... */
int tab_pos = gtk_notebook_get_tab_pos (notebook);
if (!draw_themed_tab_button (style, window, state_type,
GTK_NOTEBOOK (widget), x, y,
width, height, real_gap_side))
notebook, x, y,
width, height, tab_pos))
{
if (!draw_tab_button (style, window, state_type,
shadow_type, area, widget,
detail, x, y, width, height, real_gap_side))
detail, x, y, width, height, tab_pos))
{
/* GtkStyle expects the usual gap_side */
parent_class->draw_extension (style, window, state_type,
shadow_type, area, widget, detail,
x, y, width, height,
real_gap_side);
gap_side);
}
}
}
}
static void
draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
GtkShadowType shadow_type, GdkRectangle *area,
GtkWidget *widget, const gchar *detail, gint x,
gint y, gint width, gint height, GtkPositionType gap_side,
gint gap_x, gint gap_width)
draw_box_gap (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GtkShadowType shadow_type,
GdkRectangle *area,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height,
GtkPositionType gap_side,
gint gap_x,
gint gap_width)
{
if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
{
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
int side = gtk_notebook_get_tab_pos (notebook);
int x2 = x, y2 = y, w2 = width, h2 = height;
if (side == GTK_POS_TOP)
{
x2 = x;
y2 = y - gtk_notebook_get_tab_vborder (notebook);
w2 = width;
h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
}
else if (side == GTK_POS_BOTTOM)
{
x2 = x;
y2 = y;
w2 = width;
h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
}
else if (side == GTK_POS_LEFT)
{
x2 = x - gtk_notebook_get_tab_hborder (notebook);
y2 = y;
w2 = width + gtk_notebook_get_tab_hborder (notebook);
h2 = height;
}
else if (side == GTK_POS_RIGHT)
{
x2 = x;
y2 = y;
w2 = width + gtk_notebook_get_tab_hborder (notebook) * 2;
h2 = height;
}
int side = gtk_notebook_get_tab_pos (notebook);
int x2 = x, y2 = y;
int w2 = width + style->xthickness, h2 = height + style->ythickness;
switch (side)
{
case GTK_POS_TOP:
y2 -= 1;
break;
case GTK_POS_BOTTOM:
break;
case GTK_POS_LEFT:
x2 -= 1;
break;
case GTK_POS_RIGHT:
w2 += 1;
break;
}
if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
x2, y2, w2, h2, state_type, area))

View File

@ -121,6 +121,7 @@ static const short element_part_map[XP_THEME_ELEMENT__SIZEOF] = {
TABP_TABITEM,
TABP_TABITEMLEFTEDGE,
TABP_TABITEMRIGHTEDGE,
TABP_TABITEMBOTHEDGE,
TABP_PANE,
SBP_THUMBBTNHORZ,
SBP_THUMBBTNVERT,
@ -408,6 +409,7 @@ xp_theme_get_handle_by_element (XpThemeElement element)
case XP_THEME_ELEMENT_TAB_ITEM:
case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
case XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE:
case XP_THEME_ELEMENT_TAB_ITEM_BOTH_EDGE:
case XP_THEME_ELEMENT_TAB_PANE:
klazz = XP_THEME_CLASS_TAB;
break;
@ -536,6 +538,7 @@ xp_theme_map_gtk_state (XpThemeElement element, GtkStateType state)
case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
case XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE:
case XP_THEME_ELEMENT_TAB_ITEM_BOTH_EDGE:
case XP_THEME_ELEMENT_TAB_ITEM:
switch (state)
{
@ -940,6 +943,7 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
HDC dc;
XpDCInfo dc_info;
int part_state;
HWND hwnd;
if (!xp_theme_is_drawable (element))
return FALSE;
@ -949,8 +953,9 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
return FALSE;
/* FIXME: Recheck its function */
if (GDK_IS_WINDOW (win) && gdk_win32_window_is_win32 (win))
enable_theme_dialog_texture_func (GDK_WINDOW_HWND (win), ETDT_ENABLETAB);
hwnd = gdk_win32_window_get_impl_hwnd (win);
if (hwnd != NULL)
enable_theme_dialog_texture_func (hwnd, ETDT_ENABLETAB);
dc = get_window_dc (style, win, state_type, &dc_info,
x, y, width, height,
@ -976,7 +981,7 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
/* Support transparency */
if (is_theme_partially_transparent_func (theme, element_part_map[element], part_state))
draw_theme_parent_background_func (GDK_WINDOW_HWND (win), dc, pClip);
draw_theme_parent_background_func (hwnd, dc, pClip);
draw_theme_background_func (theme, dc, element_part_map[element],
part_state, &rect, pClip);

View File

@ -59,6 +59,7 @@ typedef enum
XP_THEME_ELEMENT_TAB_ITEM,
XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE,
XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE,
XP_THEME_ELEMENT_TAB_ITEM_BOTH_EDGE,
XP_THEME_ELEMENT_TAB_PANE,
XP_THEME_ELEMENT_SCROLLBAR_H,
XP_THEME_ELEMENT_SCROLLBAR_V,

View File

@ -436,6 +436,7 @@ typedef struct
GtkWidget *spin;
GtkWidget *area;
gint page;
GtkPrintContext *context;
PrintData *data;
gdouble dpi_x, dpi_y;
} PreviewOp;
@ -446,6 +447,11 @@ preview_expose (GtkWidget *widget,
gpointer data)
{
PreviewOp *pop = data;
cairo_t *cr;
cr = gdk_cairo_create (pop->area->window);
gtk_print_context_set_cairo_context (pop->context, cr, pop->dpi_x, pop->dpi_y);
cairo_destroy (cr);
gdk_window_clear (pop->area->window);
gtk_print_operation_preview_render_page (pop->preview,
@ -567,8 +573,6 @@ preview_cb (GtkPrintOperation *op,
gtk_widget_set_size_request (GTK_WIDGET (da), width, height);
gtk_box_pack_start (GTK_BOX (vbox), da, TRUE, TRUE, 0);
gtk_widget_set_double_buffered (da, FALSE);
gtk_widget_realize (da);
cr = gdk_cairo_create (da->window);
@ -582,6 +586,7 @@ preview_cb (GtkPrintOperation *op,
pop->spin = page;
pop->area = da;
pop->page = 1;
pop->context = context;
g_signal_connect (page, "value-changed",
G_CALLBACK (update_page), pop);