Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2019
- 65 participants
- 633 messages
Re: [PATCH vkd3d v2 3/6] vkd3d: Handle SINT and UINT formats in ClearRenderTargetView().
by Jactry Zeng
OK, I will try it again.
Thanks!
On Thu, Jul 18, 2019 at 9:49 AM Henri Verbeet <hverbeet(a)gmail.com> wrote:
> On Wed, 17 Jul 2019 at 15:48, Józef Kucia <joseph.kucia(a)gmail.com> wrote:
> > +bool vk_format_is_signed_integer(VkFormat format)
> > +{
> > + switch (format)
> > + {
> > + case VK_FORMAT_R32G32B32A32_SINT:
> > + case VK_FORMAT_R16G16B16A16_SINT:
> > + case VK_FORMAT_R32G32B32_SINT:
> > + case VK_FORMAT_R8G8B8A8_SINT:
> > + case VK_FORMAT_R32G32_SINT:
> > + case VK_FORMAT_R16G16_SINT:
> > + case VK_FORMAT_R8G8_SINT:
> > + case VK_FORMAT_R32_SINT:
> > + case VK_FORMAT_R16_SINT:
> > + case VK_FORMAT_R8_SINT:
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > +bool vk_format_is_unsigned_integer(VkFormat format)
> > +{
> > + switch (format)
> > + {
> > + case VK_FORMAT_R32G32B32A32_UINT:
> > + case VK_FORMAT_R16G16B16A16_UINT:
> > + case VK_FORMAT_R32G32B32_UINT:
> > + case VK_FORMAT_R8G8B8A8_UINT:
> > + case VK_FORMAT_R32G32_UINT:
> > + case VK_FORMAT_R16G16_UINT:
> > + case VK_FORMAT_R8G8_UINT:
> > + case VK_FORMAT_R32_UINT:
> > + case VK_FORMAT_R16_UINT:
> > + case VK_FORMAT_R8_UINT:
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> That's a little ugly, can we store the format type in vkd3d_formats[]?
>
>
>
--
Regards,
Jactry Zeng
July 19, 2019
Re: [PATCH v6 7/7] winex11.drv: Don't react to small slow mouse movements.
by Derek Lesho
Fixed a major oversight made when re-basing the patch of of patch 6 version
5.
On Fri, Jul 19, 2019 at 1:26 AM Derek Lesho <dereklesho52(a)gmail.com> wrote:
> From: Jordan Galby <gravemind2a+wine(a)gmail.com>
>
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
> From: Jordan Galby <gravemind2a+wine(a)gmail.com>
> Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
> ---
> dlls/winex11.drv/mouse.c | 63 +++++++++++++++++++++++++++++----------
> dlls/winex11.drv/x11drv.h | 1 +
> 2 files changed, 48 insertions(+), 16 deletions(-)
>
> diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> index a68844d328..1251f3fa45 100644
> --- a/dlls/winex11.drv/mouse.c
> +++ b/dlls/winex11.drv/mouse.c
> @@ -257,6 +257,8 @@ static void update_relative_valuators(XIAnyClassInfo
> **valuators, int n_valuator
>
> thread_data->x_rel_valuator.number = -1;
> thread_data->y_rel_valuator.number = -1;
> + thread_data->x_rel_valuator.accum = 0;
> + thread_data->y_rel_valuator.accum = 0;
>
> for (i = 0; i < n_valuators; i++)
> {
> @@ -1764,6 +1766,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> struct x11drv_thread_data *thread_data = x11drv_thread_data();
> struct x11drv_valuator_data *x_rel, *y_rel;
> static unsigned int last_cookie = 0;
> + static double raw_accum_x = 0, raw_accum_y = 0;
>
> if (thread_data->x_rel_valuator.number < 0 ||
> thread_data->y_rel_valuator.number < 0) return FALSE;
> if (!event->valuators.mask_len) return FALSE;
> @@ -1797,15 +1800,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
> input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
> input.u.mi.dwExtraInfo = 0;
> - input.u.mi.dx = 0;
> - input.u.mi.dy = 0;
>
> raw_input.header.dwType = RIM_TYPEMOUSE;
> raw_input.data.mouse.u.usButtonFlags = 0;
> raw_input.data.mouse.u.usButtonData = 0;
> raw_input.data.mouse.ulExtraInformation = 0;
> - raw_input.data.mouse.lLastX = 0;
> - raw_input.data.mouse.lLastY = 0;
>
> virtual_rect = get_virtual_screen_rect();
>
> @@ -1816,39 +1815,71 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> raw_val = *raw_values++;
> if (i == x_rel->number)
> {
> - input.u.mi.dx = dx = val;
> + dx = val;
> if (x_rel->min < x_rel->max)
> - input.u.mi.dx = val * (virtual_rect.right -
> virtual_rect.left)
> + dx = val * (virtual_rect.right - virtual_rect.left)
> / (x_rel->max - x_rel->min);
>
> - raw_input.data.mouse.lLastX = raw_dx = raw_val;
> + raw_dx = raw_val;
> }
> if (i == y_rel->number)
> {
> - input.u.mi.dy = dy = val;
> + dy = val;
> if (y_rel->min < y_rel->max)
> - input.u.mi.dy = val * (virtual_rect.bottom -
> virtual_rect.top)
> + dy = val * (virtual_rect.bottom - virtual_rect.top)
> / (y_rel->max - y_rel->min);
>
> - raw_input.data.mouse.lLastY = raw_dy = raw_val;
> + raw_dy = raw_val;
> }
> }
>
> if (broken_rawevents && is_old_motion_event( xev->serial ))
> {
> - TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx,
> input.u.mi.dy, xev->serial );
> + TRACE( "pos %d,%d old serial %lu, ignoring\n", (LONG) dx, (LONG)
> dy, xev->serial );
> return FALSE;
> }
>
> - if (thread_data->xi2_state == xi_extra)
> + /* Accumulate the *double* motions so sub-pixel motions
> + * wont be lost when sent/cast to *LONG* target fields.
> + */
> +
> + x_rel->accum += dx;
> + y_rel->accum += dy;
> + if (fabs(x_rel->accum) < 1.0 && fabs(y_rel->accum) < 1.0)
> {
> - TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy,
> dx, dy );
> - __wine_send_input( 0, &input );
> + TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n",
> dx, dy, x_rel->accum, y_rel->accum );
> }
> + else
> + {
> + input.u.mi.dx = x_rel->accum;
> + input.u.mi.dy = y_rel->accum;
> + x_rel->accum -= input.u.mi.dx;
> + y_rel->accum -= input.u.mi.dy;
>
> - if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
> + if (thread_data->xi2_state == xi_extra)
> + {
> + TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx,
> input.u.mi.dy, dx, dy );
> + __wine_send_input( 0, &input );
> + }
> + }
> +
> + if (InterlockedExchange(&last_cookie, xev->cookie) == xev->cookie)
> + return TRUE;
> +
> + raw_accum_x += raw_dx;
> + raw_accum_y += raw_dy;
> + if (fabs(raw_accum_x) < 1.0 && fabs(raw_accum_y) < 1.0)
> {
> - TRACE("raw event %f,%f\n", raw_dx, raw_dy);
> + TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n",
> raw_dx, raw_dy, raw_accum_x, raw_accum_y );
> + }
> + else
> + {
> + raw_input.data.mouse.lLastX = raw_accum_x;
> + raw_input.data.mouse.lLastY = raw_accum_y;
> + raw_accum_x -= raw_input.data.mouse.lLastX;
> + raw_accum_y -= raw_input.data.mouse.lLastY;
> +
> + TRACE("raw event %d,%d(event %f,%f)\n",
> raw_input.data.mouse.lLastX, raw_input.data.mouse.lLastY, raw_dx, raw_dy);
> __wine_send_raw_input( &raw_input );
> }
>
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index a9138eef2a..392b046c6d 100644
> --- a/dlls/winex11.drv/x11drv.h
> +++ b/dlls/winex11.drv/x11drv.h
> @@ -320,6 +320,7 @@ struct x11drv_valuator_data
> double min;
> double max;
> int number;
> + double accum;
> };
>
> struct x11drv_thread_data
> --
> 2.22.0
>
>
July 19, 2019
[PATCH v6 7/7] winex11.drv: Don't react to small slow mouse movements.
by Derek Lesho
From: Jordan Galby <gravemind2a+wine(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
From: Jordan Galby <gravemind2a+wine(a)gmail.com>
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
dlls/winex11.drv/mouse.c | 63 +++++++++++++++++++++++++++++----------
dlls/winex11.drv/x11drv.h | 1 +
2 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index a68844d328..1251f3fa45 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -257,6 +257,8 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
thread_data->x_rel_valuator.number = -1;
thread_data->y_rel_valuator.number = -1;
+ thread_data->x_rel_valuator.accum = 0;
+ thread_data->y_rel_valuator.accum = 0;
for (i = 0; i < n_valuators; i++)
{
@@ -1764,6 +1766,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
struct x11drv_thread_data *thread_data = x11drv_thread_data();
struct x11drv_valuator_data *x_rel, *y_rel;
static unsigned int last_cookie = 0;
+ static double raw_accum_x = 0, raw_accum_y = 0;
if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
if (!event->valuators.mask_len) return FALSE;
@@ -1797,15 +1800,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
input.u.mi.dwExtraInfo = 0;
- input.u.mi.dx = 0;
- input.u.mi.dy = 0;
raw_input.header.dwType = RIM_TYPEMOUSE;
raw_input.data.mouse.u.usButtonFlags = 0;
raw_input.data.mouse.u.usButtonData = 0;
raw_input.data.mouse.ulExtraInformation = 0;
- raw_input.data.mouse.lLastX = 0;
- raw_input.data.mouse.lLastY = 0;
virtual_rect = get_virtual_screen_rect();
@@ -1816,39 +1815,71 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_val = *raw_values++;
if (i == x_rel->number)
{
- input.u.mi.dx = dx = val;
+ dx = val;
if (x_rel->min < x_rel->max)
- input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
+ dx = val * (virtual_rect.right - virtual_rect.left)
/ (x_rel->max - x_rel->min);
- raw_input.data.mouse.lLastX = raw_dx = raw_val;
+ raw_dx = raw_val;
}
if (i == y_rel->number)
{
- input.u.mi.dy = dy = val;
+ dy = val;
if (y_rel->min < y_rel->max)
- input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
+ dy = val * (virtual_rect.bottom - virtual_rect.top)
/ (y_rel->max - y_rel->min);
- raw_input.data.mouse.lLastY = raw_dy = raw_val;
+ raw_dy = raw_val;
}
}
if (broken_rawevents && is_old_motion_event( xev->serial ))
{
- TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
+ TRACE( "pos %d,%d old serial %lu, ignoring\n", (LONG) dx, (LONG) dy, xev->serial );
return FALSE;
}
- if (thread_data->xi2_state == xi_extra)
+ /* Accumulate the *double* motions so sub-pixel motions
+ * wont be lost when sent/cast to *LONG* target fields.
+ */
+
+ x_rel->accum += dx;
+ y_rel->accum += dy;
+ if (fabs(x_rel->accum) < 1.0 && fabs(y_rel->accum) < 1.0)
{
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
- __wine_send_input( 0, &input );
+ TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n", dx, dy, x_rel->accum, y_rel->accum );
}
+ else
+ {
+ input.u.mi.dx = x_rel->accum;
+ input.u.mi.dy = y_rel->accum;
+ x_rel->accum -= input.u.mi.dx;
+ y_rel->accum -= input.u.mi.dy;
- if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
+ if (thread_data->xi2_state == xi_extra)
+ {
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
+ __wine_send_input( 0, &input );
+ }
+ }
+
+ if (InterlockedExchange(&last_cookie, xev->cookie) == xev->cookie)
+ return TRUE;
+
+ raw_accum_x += raw_dx;
+ raw_accum_y += raw_dy;
+ if (fabs(raw_accum_x) < 1.0 && fabs(raw_accum_y) < 1.0)
{
- TRACE("raw event %f,%f\n", raw_dx, raw_dy);
+ TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n", raw_dx, raw_dy, raw_accum_x, raw_accum_y );
+ }
+ else
+ {
+ raw_input.data.mouse.lLastX = raw_accum_x;
+ raw_input.data.mouse.lLastY = raw_accum_y;
+ raw_accum_x -= raw_input.data.mouse.lLastX;
+ raw_accum_y -= raw_input.data.mouse.lLastY;
+
+ TRACE("raw event %d,%d(event %f,%f)\n", raw_input.data.mouse.lLastX, raw_input.data.mouse.lLastY, raw_dx, raw_dy);
__wine_send_raw_input( &raw_input );
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a9138eef2a..392b046c6d 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -320,6 +320,7 @@ struct x11drv_valuator_data
double min;
double max;
int number;
+ double accum;
};
struct x11drv_thread_data
--
2.22.0
July 19, 2019
[PATCH v2] include: Implement InlineIsEqualGUID.
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
include/guiddef.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/guiddef.h b/include/guiddef.h
index 2adde9ca23..ba39dd87b4 100644
--- a/include/guiddef.h
+++ b/include/guiddef.h
@@ -139,8 +139,20 @@ typedef GUID FMTID,*LPFMTID;
#if defined(__cplusplus) && !defined(CINTERFACE)
#define IsEqualGUID(rguid1, rguid2) (!memcmp(&(rguid1), &(rguid2), sizeof(GUID)))
+inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+{
+ return (((ULONG *)&rguid1)[0] == ((ULONG *)&rguid2)[0] &&
+ ((ULONG *)&rguid1)[1] == ((ULONG *)&rguid2)[1] &&
+ ((ULONG *)&rguid1)[2] == ((ULONG *)&rguid2)[2] &&
+ ((ULONG *)&rguid1)[3] == ((ULONG *)&rguid2)[3]);
+}
#else /* defined(__cplusplus) && !defined(CINTERFACE) */
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
+#define InlineIsEqualGUID(rguid1, rguid2) \
+ (((ULONG *)rguid1)[0] == ((ULONG *)rguid2)[0] && \
+ ((ULONG *)rguid1)[1] == ((ULONG *)rguid2)[1] && \
+ ((ULONG *)rguid1)[2] == ((ULONG *)rguid2)[2] && \
+ ((ULONG *)rguid1)[3] == ((ULONG *)rguid2)[3])
#endif /* defined(__cplusplus) && !defined(CINTERFACE) */
#if defined(__cplusplus) && !defined(CINTERFACE)
--
2.17.1
July 19, 2019
Re: [PATCH] include: Implement InlineIsEqualGUID.
by Dmitry Timoshkov
Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> wrote:
> +inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
> +{
> + return (((unsigned long *)&rguid1)[0] == ((unsigned long *)&rguid2)[0] &&
> + ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid2)[1] &&
> + ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid2)[2] &&
> + ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid2)[3]);
> +}
Will this work on 64-bit?
--
Dmitry.
July 19, 2019
[PATCH] include: Implement InlineIsEqualGUID.
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
include/guiddef.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/guiddef.h b/include/guiddef.h
index 2adde9ca23..74fdd3b9f9 100644
--- a/include/guiddef.h
+++ b/include/guiddef.h
@@ -139,8 +139,20 @@ typedef GUID FMTID,*LPFMTID;
#if defined(__cplusplus) && !defined(CINTERFACE)
#define IsEqualGUID(rguid1, rguid2) (!memcmp(&(rguid1), &(rguid2), sizeof(GUID)))
+inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
+{
+ return (((unsigned long *)&rguid1)[0] == ((unsigned long *)&rguid2)[0] &&
+ ((unsigned long *)&rguid1)[1] == ((unsigned long *)&rguid2)[1] &&
+ ((unsigned long *)&rguid1)[2] == ((unsigned long *)&rguid2)[2] &&
+ ((unsigned long *)&rguid1)[3] == ((unsigned long *)&rguid2)[3]);
+}
#else /* defined(__cplusplus) && !defined(CINTERFACE) */
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
+#define InlineIsEqualGUID(rguid1, rguid2) \
+ (((unsigned long *)rguid1)[0] == ((unsigned long *)rguid2)[0] && \
+ ((unsigned long *)rguid1)[1] == ((unsigned long *)rguid2)[1] && \
+ ((unsigned long *)rguid1)[2] == ((unsigned long *)rguid2)[2] && \
+ ((unsigned long *)rguid1)[3] == ((unsigned long *)rguid2)[3])
#endif /* defined(__cplusplus) && !defined(CINTERFACE) */
#if defined(__cplusplus) && !defined(CINTERFACE)
--
2.17.1
July 18, 2019
[PATCH] services: Fix the arguments to is_root_pnp_service().
by Zebediah Figura
From: Zebediah Figura <z.figura12(a)gmail.com>
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
programs/services/services.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/services/services.c b/programs/services/services.c
index 67cd4fa855c..ec2a8eb05cc 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -424,7 +424,7 @@ static BOOL schedule_delayed_autostart(struct service_entry **services, unsigned
return TRUE;
}
-static BOOL is_root_pnp_service(const struct service_entry *service, HDEVINFO set)
+static BOOL is_root_pnp_service(HDEVINFO set, const struct service_entry *service)
{
SP_DEVINFO_DATA device = {sizeof(device)};
WCHAR name[MAX_SERVICE_NAME];
--
2.20.1
July 18, 2019
Re: [PATCH 6/7] winex11.drv: Implement native mouse-movement raw-input using RawMotion.
by Derek Lesho
This version removes the whole g_x11_threads list as I realized not all of
them receive events. The new method of ensuring only one thread per
process sending the events is much cleaner and should work 100% of the time.
On Thu, Jul 18, 2019 at 4:52 PM Derek Lesho <dereklesho52(a)gmail.com> wrote:
> Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
> ---
> dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++-------
> dlls/winex11.drv/x11drv.h | 4 +-
> dlls/winex11.drv/x11drv_main.c | 4 ++
> 3 files changed, 79 insertions(+), 18 deletions(-)
>
> diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> index f737a306a5..a68844d328 100644
> --- a/dlls/winex11.drv/mouse.c
> +++ b/dlls/winex11.drv/mouse.c
> @@ -284,11 +284,26 @@ static void update_relative_valuators(XIAnyClassInfo
> **valuators, int n_valuator
> }
> #endif
>
> +/***********************************************************************
> + * inform_wineserver
> + */
> +static void inform_wineserver(void)
> +{
> + static int once = 0;
> + if (!once)
> + {
> + RAWINPUT raw_input;
> + raw_input.header.dwType = RIM_ENABLE_NATIVE_MOUSE_MOVE;
> + __wine_send_raw_input(&raw_input);
> + once = 1;
> + }
> +}
> +
>
> /***********************************************************************
> - * enable_xinput2
> + * X11DRV_XInput2_Enable
> */
> -static void enable_xinput2(void)
> +void X11DRV_XInput2_Enable(void)
> {
> #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
> struct x11drv_thread_data *data = x11drv_thread_data();
> @@ -318,7 +333,6 @@ static void enable_xinput2(void)
> memset( mask_bits, 0, sizeof(mask_bits) );
> XISetMask( mask_bits, XI_DeviceChanged );
> XISetMask( mask_bits, XI_RawMotion );
> - XISetMask( mask_bits, XI_ButtonPress );
>
> pXISelectEvents( data->display, DefaultRootWindow( data->display ),
> &mask, 1 );
>
> @@ -337,19 +351,21 @@ static void enable_xinput2(void)
> data->xi2_current_slave = 0;
>
> data->xi2_state = xi_enabled;
> +
> + inform_wineserver();
> #endif
> }
>
> /***********************************************************************
> - * disable_xinput2
> + * X11DRV_XInput2_Disable
> */
> -static void disable_xinput2(void)
> +void X11DRV_XInput2_Disable(void)
> {
> #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
> struct x11drv_thread_data *data = x11drv_thread_data();
> XIEventMask mask;
>
> - if (data->xi2_state != xi_enabled) return;
> + if (data->xi2_state < xi_enabled) return;
>
> TRACE( "disabling\n" );
> data->xi2_state = xi_disabled;
> @@ -368,6 +384,21 @@ static void disable_xinput2(void)
> #endif
> }
>
> +static void use_xinput2_path(void)
> +{
> + struct x11drv_thread_data *thread_data = x11drv_thread_data();
> +
> + if (thread_data->xi2_state == xi_enabled)
> + thread_data->xi2_state = xi_extra;
> +}
> +
> +static void disable_xinput2_path(void)
> +{
> + struct x11drv_thread_data *thread_data = x11drv_thread_data();
> +
> + if (thread_data->xi2_state == xi_extra)
> + thread_data->xi2_state = xi_enabled;
> +}
>
> /***********************************************************************
> * grab_clipping_window
> @@ -393,9 +424,9 @@ static BOOL grab_clipping_window( const RECT *clip )
> return TRUE;
>
> /* enable XInput2 unless we are already clipping */
> - if (!data->clip_hwnd) enable_xinput2();
> + if (!data->clip_hwnd) use_xinput2_path();
>
> - if (data->xi2_state != xi_enabled)
> + if (data->xi2_state < xi_extra)
> {
> WARN( "XInput2 not supported, refusing to clip to %s\n",
> wine_dbgstr_rect(clip) );
> DestroyWindow( msg_hwnd );
> @@ -423,7 +454,7 @@ static BOOL grab_clipping_window( const RECT *clip )
>
> if (!clipping_cursor)
> {
> - disable_xinput2();
> + disable_xinput2_path();
> DestroyWindow( msg_hwnd );
> return FALSE;
> }
> @@ -489,7 +520,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND
> new_clip_hwnd )
> TRACE( "clip hwnd reset from %p\n", hwnd );
> data->clip_hwnd = 0;
> data->clip_reset = GetTickCount();
> - disable_xinput2();
> + disable_xinput2_path();
> DestroyWindow( hwnd );
> }
> else if (hwnd == GetForegroundWindow()) /* request to clip */
> @@ -1724,16 +1755,19 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> {
> XIRawEvent *event = xev->data;
> const double *values = event->valuators.values;
> + const double *raw_values = event->raw_values;
> RECT virtual_rect;
> INPUT input;
> + RAWINPUT raw_input;
> int i;
> - double dx = 0, dy = 0, val;
> + double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
> struct x11drv_thread_data *thread_data = x11drv_thread_data();
> struct x11drv_valuator_data *x_rel, *y_rel;
> + static unsigned int last_cookie = 0;
>
> if (thread_data->x_rel_valuator.number < 0 ||
> thread_data->y_rel_valuator.number < 0) return FALSE;
> if (!event->valuators.mask_len) return FALSE;
> - if (thread_data->xi2_state != xi_enabled) return FALSE;
> + if (thread_data->xi2_state < xi_enabled) return FALSE;
>
> /* If there is no slave currently detected, no previous motion nor
> device
> * change events were received. Look it up now on the device list in
> this
> @@ -1758,12 +1792,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> x_rel = &thread_data->x_rel_valuator;
> y_rel = &thread_data->y_rel_valuator;
>
> + input.type = INPUT_MOUSE;
> input.u.mi.mouseData = 0;
> input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
> input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
> input.u.mi.dwExtraInfo = 0;
> - input.u.mi.dx = 0;
> - input.u.mi.dy = 0;
> + input.u.mi.dx = 0;
> + input.u.mi.dy = 0;
> +
> + raw_input.header.dwType = RIM_TYPEMOUSE;
> + raw_input.data.mouse.u.usButtonFlags = 0;
> + raw_input.data.mouse.u.usButtonData = 0;
> + raw_input.data.mouse.ulExtraInformation = 0;
> + raw_input.data.mouse.lLastX = 0;
> + raw_input.data.mouse.lLastY = 0;
>
> virtual_rect = get_virtual_screen_rect();
>
> @@ -1771,12 +1813,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> {
> if (!XIMaskIsSet( event->valuators.mask, i )) continue;
> val = *values++;
> + raw_val = *raw_values++;
> if (i == x_rel->number)
> {
> input.u.mi.dx = dx = val;
> if (x_rel->min < x_rel->max)
> input.u.mi.dx = val * (virtual_rect.right -
> virtual_rect.left)
> / (x_rel->max - x_rel->min);
> +
> + raw_input.data.mouse.lLastX = raw_dx = raw_val;
> }
> if (i == y_rel->number)
> {
> @@ -1784,6 +1829,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> if (y_rel->min < y_rel->max)
> input.u.mi.dy = val * (virtual_rect.bottom -
> virtual_rect.top)
> / (y_rel->max - y_rel->min);
> +
> + raw_input.data.mouse.lLastY = raw_dy = raw_val;
> }
> }
>
> @@ -1793,10 +1840,18 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> return FALSE;
> }
>
> - TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx,
> dy );
> + if (thread_data->xi2_state == xi_extra)
> + {
> + TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy,
> dx, dy );
> + __wine_send_input( 0, &input );
> + }
> +
> + if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
> + {
> + TRACE("raw event %f,%f\n", raw_dx, raw_dy);
> + __wine_send_raw_input( &raw_input );
> + }
>
> - input.type = INPUT_MOUSE;
> - __wine_send_input( 0, &input );
> return TRUE;
> }
>
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index a0308b0675..a9138eef2a 100644
> --- a/dlls/winex11.drv/x11drv.h
> +++ b/dlls/winex11.drv/x11drv.h
> @@ -194,6 +194,8 @@ extern BOOL X11DRV_UnrealizePalette( HPALETTE hpal )
> DECLSPEC_HIDDEN;
>
> extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
> extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
> +extern void X11DRV_XInput2_Enable(void) DECLSPEC_HIDDEN;
> +extern void X11DRV_XInput2_Disable(void) DECLSPEC_HIDDEN;
>
> extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage
> *image,
> const struct gdi_image_bits *src_bits,
> struct gdi_image_bits *dst_bits,
> @@ -335,7 +337,7 @@ struct x11drv_thread_data
> HWND clip_hwnd; /* message window stored in desktop
> while clipping is active */
> DWORD clip_reset; /* time when clipping was last reset */
> HKL kbd_layout; /* active keyboard layout */
> - enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled }
> xi2_state; /* XInput2 state */
> + enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled,
> xi_extra } xi2_state; /* XInput2 state */
> void *xi2_devices; /* list of XInput2 devices (valid when
> state is enabled) */
> int xi2_device_count;
> struct x11drv_valuator_data x_rel_valuator;
> diff --git a/dlls/winex11.drv/x11drv_main.c
> b/dlls/winex11.drv/x11drv_main.c
> index e67a3c05a9..351ab89781 100644
> --- a/dlls/winex11.drv/x11drv_main.c
> +++ b/dlls/winex11.drv/x11drv_main.c
> @@ -610,6 +610,8 @@ void CDECL X11DRV_ThreadDetach(void)
>
> if (data)
> {
> + X11DRV_XInput2_Disable();
> +
> if (data->xim) XCloseIM( data->xim );
> if (data->font_set) XFreeFontSet( data->display, data->font_set );
> XCloseDisplay( data->display );
> @@ -680,6 +682,8 @@ struct x11drv_thread_data
> *x11drv_init_thread_data(void)
>
> if (use_xim) X11DRV_SetupXIM();
>
> + X11DRV_XInput2_Enable();
> +
> return data;
> }
>
> --
> 2.22.0
>
>
July 18, 2019
[PATCH 7/7] winex11.drv: Don't react to small slow mouse movements.
by Derek Lesho
From: Jordan Galby <gravemind2a+wine(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
From: Jordan Galby <gravemind2a+wine(a)gmail.com>
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
dlls/winex11.drv/mouse.c | 66 +++++++++++++++++++++++++++++----------
dlls/winex11.drv/x11drv.h | 2 ++
2 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index a68844d328..03262c063a 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -257,6 +257,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
thread_data->x_rel_valuator.number = -1;
thread_data->y_rel_valuator.number = -1;
+ thread_data->x_rel_valuator.accum = 0;
+ thread_data->y_rel_valuator.accum = 0;
+ thread_data->x_rel_valuator.raw_accum = 0;
+ thread_data->y_rel_valuator.raw_accum = 0;
for (i = 0; i < n_valuators; i++)
{
@@ -1797,15 +1801,11 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
input.u.mi.dwExtraInfo = 0;
- input.u.mi.dx = 0;
- input.u.mi.dy = 0;
raw_input.header.dwType = RIM_TYPEMOUSE;
raw_input.data.mouse.u.usButtonFlags = 0;
raw_input.data.mouse.u.usButtonData = 0;
raw_input.data.mouse.ulExtraInformation = 0;
- raw_input.data.mouse.lLastX = 0;
- raw_input.data.mouse.lLastY = 0;
virtual_rect = get_virtual_screen_rect();
@@ -1816,40 +1816,72 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_val = *raw_values++;
if (i == x_rel->number)
{
- input.u.mi.dx = dx = val;
+ dx = val;
if (x_rel->min < x_rel->max)
- input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
+ dx = val * (virtual_rect.right - virtual_rect.left)
/ (x_rel->max - x_rel->min);
- raw_input.data.mouse.lLastX = raw_dx = raw_val;
+ raw_dx = raw_val;
}
if (i == y_rel->number)
{
- input.u.mi.dy = dy = val;
+ dy = val;
if (y_rel->min < y_rel->max)
- input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
+ dy = val * (virtual_rect.bottom - virtual_rect.top)
/ (y_rel->max - y_rel->min);
- raw_input.data.mouse.lLastY = raw_dy = raw_val;
+ raw_dy = raw_val;
}
}
if (broken_rawevents && is_old_motion_event( xev->serial ))
{
- TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
+ TRACE( "pos %d,%d old serial %lu, ignoring\n", (LONG) dx, (LONG) dy, xev->serial );
return FALSE;
}
- if (thread_data->xi2_state == xi_extra)
+ /* Accumulate the *double* motions so sub-pixel motions
+ * wont be lost when sent/cast to *LONG* target fields.
+ */
+
+ x_rel->accum += dx;
+ y_rel->accum += dy;
+ if (fabs(x_rel->accum) < 1.0 && fabs(y_rel->accum) < 1.0)
{
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
- __wine_send_input( 0, &input );
+ TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n", dx, dy, x_rel->accum, y_rel->accum );
}
+ else
+ {
+ input.u.mi.dx = x_rel->accum;
+ input.u.mi.dy = y_rel->accum;
+ x_rel->accum -= input.u.mi.dx;
+ y_rel->accum -= input.u.mi.dy;
- if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
+ if (thread_data->xi2_state == xi_extra)
+ {
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
+ __wine_send_input( 0, &input );
+ }
+ }
+
+ x_rel->raw_accum += raw_dx;
+ y_rel->raw_accum += raw_dy;
+ if (fabs(x_rel->raw_accum) < 1.0 && fabs(y_rel->raw_accum) < 1.0)
+ {
+ TRACE( "accumulating raw motion (event %f,%f, accum %f,%f)\n", raw_dx, raw_dy, x_rel->raw_accum, y_rel->raw_accum );
+ }
+ else
{
- TRACE("raw event %f,%f\n", raw_dx, raw_dy);
- __wine_send_raw_input( &raw_input );
+ raw_input.data.mouse.lLastX = x_rel->raw_accum;
+ raw_input.data.mouse.lLastY = y_rel->raw_accum;
+ x_rel->raw_accum -= raw_input.data.mouse.lLastX;
+ y_rel->raw_accum -= raw_input.data.mouse.lLastY;
+
+ if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
+ {
+ TRACE("raw event %d,%d(event %f,%f)\n", raw_input.data.mouse.lLastX, raw_input.data.mouse.lLastY, raw_dx, raw_dy);
+ __wine_send_raw_input( &raw_input );
+ }
}
return TRUE;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a9138eef2a..408c1c3c72 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -320,6 +320,8 @@ struct x11drv_valuator_data
double min;
double max;
int number;
+ double accum;
+ double raw_accum;
};
struct x11drv_thread_data
--
2.22.0
July 18, 2019
[PATCH 6/7] winex11.drv: Implement native mouse-movement raw-input using RawMotion.
by Derek Lesho
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++-------
dlls/winex11.drv/x11drv.h | 4 +-
dlls/winex11.drv/x11drv_main.c | 4 ++
3 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a5..a68844d328 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -284,11 +284,26 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
}
#endif
+/***********************************************************************
+ * inform_wineserver
+ */
+static void inform_wineserver(void)
+{
+ static int once = 0;
+ if (!once)
+ {
+ RAWINPUT raw_input;
+ raw_input.header.dwType = RIM_ENABLE_NATIVE_MOUSE_MOVE;
+ __wine_send_raw_input(&raw_input);
+ once = 1;
+ }
+}
+
/***********************************************************************
- * enable_xinput2
+ * X11DRV_XInput2_Enable
*/
-static void enable_xinput2(void)
+void X11DRV_XInput2_Enable(void)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
@@ -318,7 +333,6 @@ static void enable_xinput2(void)
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
- XISetMask( mask_bits, XI_ButtonPress );
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
@@ -337,19 +351,21 @@ static void enable_xinput2(void)
data->xi2_current_slave = 0;
data->xi2_state = xi_enabled;
+
+ inform_wineserver();
#endif
}
/***********************************************************************
- * disable_xinput2
+ * X11DRV_XInput2_Disable
*/
-static void disable_xinput2(void)
+void X11DRV_XInput2_Disable(void)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
XIEventMask mask;
- if (data->xi2_state != xi_enabled) return;
+ if (data->xi2_state < xi_enabled) return;
TRACE( "disabling\n" );
data->xi2_state = xi_disabled;
@@ -368,6 +384,21 @@ static void disable_xinput2(void)
#endif
}
+static void use_xinput2_path(void)
+{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+
+ if (thread_data->xi2_state == xi_enabled)
+ thread_data->xi2_state = xi_extra;
+}
+
+static void disable_xinput2_path(void)
+{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+
+ if (thread_data->xi2_state == xi_extra)
+ thread_data->xi2_state = xi_enabled;
+}
/***********************************************************************
* grab_clipping_window
@@ -393,9 +424,9 @@ static BOOL grab_clipping_window( const RECT *clip )
return TRUE;
/* enable XInput2 unless we are already clipping */
- if (!data->clip_hwnd) enable_xinput2();
+ if (!data->clip_hwnd) use_xinput2_path();
- if (data->xi2_state != xi_enabled)
+ if (data->xi2_state < xi_extra)
{
WARN( "XInput2 not supported, refusing to clip to %s\n", wine_dbgstr_rect(clip) );
DestroyWindow( msg_hwnd );
@@ -423,7 +454,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ disable_xinput2_path();
DestroyWindow( msg_hwnd );
return FALSE;
}
@@ -489,7 +520,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
TRACE( "clip hwnd reset from %p\n", hwnd );
data->clip_hwnd = 0;
data->clip_reset = GetTickCount();
- disable_xinput2();
+ disable_xinput2_path();
DestroyWindow( hwnd );
}
else if (hwnd == GetForegroundWindow()) /* request to clip */
@@ -1724,16 +1755,19 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
XIRawEvent *event = xev->data;
const double *values = event->valuators.values;
+ const double *raw_values = event->raw_values;
RECT virtual_rect;
INPUT input;
+ RAWINPUT raw_input;
int i;
- double dx = 0, dy = 0, val;
+ double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
struct x11drv_thread_data *thread_data = x11drv_thread_data();
struct x11drv_valuator_data *x_rel, *y_rel;
+ static unsigned int last_cookie = 0;
if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
if (!event->valuators.mask_len) return FALSE;
- if (thread_data->xi2_state != xi_enabled) return FALSE;
+ if (thread_data->xi2_state < xi_enabled) return FALSE;
/* If there is no slave currently detected, no previous motion nor device
* change events were received. Look it up now on the device list in this
@@ -1758,12 +1792,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
x_rel = &thread_data->x_rel_valuator;
y_rel = &thread_data->y_rel_valuator;
+ input.type = INPUT_MOUSE;
input.u.mi.mouseData = 0;
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
input.u.mi.time = EVENT_x11_time_to_win32_time( event->time );
input.u.mi.dwExtraInfo = 0;
- input.u.mi.dx = 0;
- input.u.mi.dy = 0;
+ input.u.mi.dx = 0;
+ input.u.mi.dy = 0;
+
+ raw_input.header.dwType = RIM_TYPEMOUSE;
+ raw_input.data.mouse.u.usButtonFlags = 0;
+ raw_input.data.mouse.u.usButtonData = 0;
+ raw_input.data.mouse.ulExtraInformation = 0;
+ raw_input.data.mouse.lLastX = 0;
+ raw_input.data.mouse.lLastY = 0;
virtual_rect = get_virtual_screen_rect();
@@ -1771,12 +1813,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
val = *values++;
+ raw_val = *raw_values++;
if (i == x_rel->number)
{
input.u.mi.dx = dx = val;
if (x_rel->min < x_rel->max)
input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
/ (x_rel->max - x_rel->min);
+
+ raw_input.data.mouse.lLastX = raw_dx = raw_val;
}
if (i == y_rel->number)
{
@@ -1784,6 +1829,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
if (y_rel->min < y_rel->max)
input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
/ (y_rel->max - y_rel->min);
+
+ raw_input.data.mouse.lLastY = raw_dy = raw_val;
}
}
@@ -1793,10 +1840,18 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
return FALSE;
}
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
+ if (thread_data->xi2_state == xi_extra)
+ {
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
+ __wine_send_input( 0, &input );
+ }
+
+ if (InterlockedExchange(&last_cookie, xev->cookie) != xev->cookie)
+ {
+ TRACE("raw event %f,%f\n", raw_dx, raw_dy);
+ __wine_send_raw_input( &raw_input );
+ }
- input.type = INPUT_MOUSE;
- __wine_send_input( 0, &input );
return TRUE;
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a0308b0675..a9138eef2a 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -194,6 +194,8 @@ extern BOOL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
+extern void X11DRV_XInput2_Enable(void) DECLSPEC_HIDDEN;
+extern void X11DRV_XInput2_Disable(void) DECLSPEC_HIDDEN;
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
@@ -335,7 +337,7 @@ struct x11drv_thread_data
HWND clip_hwnd; /* message window stored in desktop while clipping is active */
DWORD clip_reset; /* time when clipping was last reset */
HKL kbd_layout; /* active keyboard layout */
- enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
+ enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
int xi2_device_count;
struct x11drv_valuator_data x_rel_valuator;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index e67a3c05a9..351ab89781 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -610,6 +610,8 @@ void CDECL X11DRV_ThreadDetach(void)
if (data)
{
+ X11DRV_XInput2_Disable();
+
if (data->xim) XCloseIM( data->xim );
if (data->font_set) XFreeFontSet( data->display, data->font_set );
XCloseDisplay( data->display );
@@ -680,6 +682,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
if (use_xim) X11DRV_SetupXIM();
+ X11DRV_XInput2_Enable();
+
return data;
}
--
2.22.0
July 18, 2019