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: TestBot news
by André Hentschel
Nice work, thanks Francois
Am 27.07.19 um 11:59 schrieb Francois Gouget:
> I tried upgrating wxppro but Windows Update got in an infinite loop on
> startup so I gave up. It has all updates up 2014 which is when support
> for it was dropped by Microsoft anyway so there should not be anything
> missing. In the end it just got a TestAgentd update (so no command line
> window)
There were updates after 2014, not sure if they are download only. One of the latest:
https://support.microsoft.com/en-us/help/4500705/customer-guidance-for-cve-…
July 27, 2019
Re: TestBot news
by Francois Gouget
It also looks like the TestBot is no longer receiving the wine-devel
emails but that's outside my jurisdiction :-(
It's still possible to submit jobs through the website so don't hesitate
to do so if you want to see how your patches fare.
https://testbot.winehq.org/Submit.pl
--
Francois Gouget <fgouget(a)codeweavers.com>
July 27, 2019
Re: TestBot news
by Francois Gouget
On Wed, 24 Jul 2019, Francois Gouget wrote:
[...]
> So I'll wait a bit before upgrading the other VM hosts: I can compensate
> the lost of a host by shuffling the VMs around (it takes time though).
> But losing a second host entirely or even partially would really start
> to make a dent in the TestBot performance and require that I move
> another bunch of VMs around :-(
vm4 turned out to be a relatively easy target so I upgraded it next and
it worked. So now all the vm hosts are running Debian 10 (and vm2 still
has a problem with pre-Win7 VMs).
I upgraded w7pro64 and w2008s64. They now have all Windows updates up
to this week.
I tried upgrading w8 but Windows Update got stuck (no progress in more
than 24 hours). So I just updated TestAgentd.
I tried upgrating wxppro but Windows Update got in an infinite loop on
startup so I gave up. It has all updates up 2014 which is when support
for it was dropped by Microsoft anyway so there should not be anything
missing. In the end it just got a TestAgentd update (so no command line
window).
As before, let me know if you notice something weird.
--
Francois Gouget <fgouget(a)codeweavers.com>
July 27, 2019
Re: [PATCH v9 8/8] winex11.drv: Don't react to small slow mouse movements.
by Derek Lesho
I tried to send this patch as a new email since it's now patch #8 but git
send-email still replied here for some reason, sorry.
On Fri, Jul 26, 2019 at 7:20 PM 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>
> ---
> v9:
> - Remove accumulation of raw mouse movement, as it was incorrect and raw
> events are always whole anyway.
> - Add accumulation for the mouse-wheel.
> ---
> dlls/winex11.drv/mouse.c | 50 +++++++++++++++++++++++++++++----------
> dlls/winex11.drv/x11drv.h | 1 +
> 2 files changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> index 9259907eb5..5cd8e07e21 100644
> --- a/dlls/winex11.drv/mouse.c
> +++ b/dlls/winex11.drv/mouse.c
> @@ -259,6 +259,10 @@ static void update_relative_valuators(XIAnyClassInfo
> **valuators, int n_valuator
> thread_data->y_rel_valuator.number = -1;
> thread_data->wheel_valuator.number = -1;
>
> + thread_data->x_rel_valuator.accum = 0;
> + thread_data->y_rel_valuator.accum = 0;
> + thread_data->wheel_valuator.accum = 0;
> +
> for (i = 0; i < n_valuators; i++)
> {
> XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
> @@ -1755,8 +1759,6 @@ 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;
> @@ -1774,18 +1776,18 @@ 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;
> }
> 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;
> @@ -1796,20 +1798,44 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
>
> 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 (dwheel)
> + 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 );
> + }
> + }
> +
> + wheel->accum += dwheel;
> + if (fabs(wheel->accum) < 1.0)
> + {
> + TRACE("accumulating wheel motion (event %f, accum %f)\n", dwheel,
> wheel->accum);
> + }
> + else
> {
> raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
> - raw_input.data.mouse.u.usButtonData = dwheel;
> + raw_input.data.mouse.u.usButtonData = wheel->accum;
> + wheel->accum -= dwheel;
> }
>
> TRACE("raw event %f,%f + %f\n", raw_dx, raw_dy, dwheel);
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index 8af2ebfcef..565cf83b89 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 26, 2019
[PATCH v9 8/8] 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>
---
v9:
- Remove accumulation of raw mouse movement, as it was incorrect and raw events are always whole anyway.
- Add accumulation for the mouse-wheel.
---
dlls/winex11.drv/mouse.c | 50 +++++++++++++++++++++++++++++----------
dlls/winex11.drv/x11drv.h | 1 +
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 9259907eb5..5cd8e07e21 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -259,6 +259,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
thread_data->y_rel_valuator.number = -1;
thread_data->wheel_valuator.number = -1;
+ thread_data->x_rel_valuator.accum = 0;
+ thread_data->y_rel_valuator.accum = 0;
+ thread_data->wheel_valuator.accum = 0;
+
for (i = 0; i < n_valuators; i++)
{
XIValuatorClassInfo *class = (XIValuatorClassInfo *)valuators[i];
@@ -1755,8 +1759,6 @@ 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;
@@ -1774,18 +1776,18 @@ 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;
}
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;
@@ -1796,20 +1798,44 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
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 (dwheel)
+ 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 );
+ }
+ }
+
+ wheel->accum += dwheel;
+ if (fabs(wheel->accum) < 1.0)
+ {
+ TRACE("accumulating wheel motion (event %f, accum %f)\n", dwheel, wheel->accum);
+ }
+ else
{
raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
- raw_input.data.mouse.u.usButtonData = dwheel;
+ raw_input.data.mouse.u.usButtonData = wheel->accum;
+ wheel->accum -= dwheel;
}
TRACE("raw event %f,%f + %f\n", raw_dx, raw_dy, dwheel);
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 8af2ebfcef..565cf83b89 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 26, 2019
[PATCH v9 7/8] winex11.drv: Implement native mouse-button raw-input using RawButton*.
by Derek Lesho
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
dlls/winex11.drv/mouse.c | 97 +++++++++++++++++++++++++++++++++++++--
dlls/winex11.drv/x11drv.h | 1 +
2 files changed, 93 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 7423f946b9..9259907eb5 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -257,6 +257,7 @@ 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->wheel_valuator.number = -1;
for (i = 0; i < n_valuators; i++)
{
@@ -274,6 +275,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
{
valuator_data = &thread_data->y_rel_valuator;
}
+ else if (class->number == 3) /* scroll wheel */
+ {
+ valuator_data = &thread_data->wheel_valuator;
+ }
if (valuator_data) {
valuator_data->number = class->number;
@@ -285,6 +290,21 @@ 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;
+ __wine_send_raw_input(&raw_input);
+ once = 1;
+ }
+}
+
/***********************************************************************
* X11DRV_XInput2_Enable
*/
@@ -318,6 +338,8 @@ void X11DRV_XInput2_Enable(void)
mask.deviceid = XIAllMasterDevices;
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_RawMotion );
+ XISetMask( mask_bits, XI_RawButtonPress );
+ XISetMask( mask_bits, XI_RawButtonRelease );
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
@@ -326,6 +348,8 @@ void X11DRV_XInput2_Enable(void)
pXIFreeDeviceInfo( pointer_info );
data->xi2_state = xi_enabled;
+
+ inform_wineserver();
#endif
}
@@ -350,6 +374,7 @@ void X11DRV_XInput2_Disable(void)
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
data->x_rel_valuator.number = -1;
data->y_rel_valuator.number = -1;
+ data->wheel_valuator.number = -1;
#endif
}
@@ -1713,16 +1738,17 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
INPUT input;
RAWINPUT raw_input;
int i;
- double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
+ double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, dwheel = 0, val, raw_val;
struct x11drv_thread_data *thread_data = x11drv_thread_data();
- struct x11drv_valuator_data *x_rel, *y_rel;
+ struct x11drv_valuator_data *x_rel, *y_rel, *wheel;
- if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
+ if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0 || thread_data->wheel_valuator.number < 0) return FALSE;
if (!event->valuators.mask_len) return FALSE;
if (thread_data->xi2_state < xi_enabled) return FALSE;
x_rel = &thread_data->x_rel_valuator;
y_rel = &thread_data->y_rel_valuator;
+ wheel = &thread_data->wheel_valuator;
input.type = INPUT_MOUSE;
input.u.mi.mouseData = 0;
@@ -1741,7 +1767,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
virtual_rect = get_virtual_screen_rect();
- for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
+ for (i = 0; i <= max( wheel->number, max( x_rel->number, y_rel->number ) ); i++)
{
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
val = *values++;
@@ -1764,6 +1790,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_input.data.mouse.lLastY = raw_dy = raw_val;
}
+ if (i == wheel->number)
+ dwheel = raw_val;
}
if (broken_rawevents && is_old_motion_event( xev->serial ))
@@ -1778,12 +1806,66 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
__wine_send_input( 0, &input );
}
- TRACE("raw event %f,%f\n", raw_dx, raw_dy);
+ if (dwheel)
+ {
+ raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
+ raw_input.data.mouse.u.usButtonData = dwheel;
+ }
+
+ TRACE("raw event %f,%f + %f\n", raw_dx, raw_dy, dwheel);
__wine_send_raw_input( &raw_input );
return TRUE;
}
+/***********************************************************************
+ * X11DRV_RawButton
+ */
+static BOOL X11DRV_RawButton( XGenericEventCookie *xev )
+{
+ RAWINPUT ri;
+
+ static const unsigned short raw_button_press_flags[] = {
+ 0, /* 0 = unused */
+ RI_MOUSE_LEFT_BUTTON_DOWN, /* 1 */
+ RI_MOUSE_MIDDLE_BUTTON_DOWN, /* 2 */
+ RI_MOUSE_RIGHT_BUTTON_DOWN, /* 3 */
+ 0, /* 4 = unknown */
+ 0, /* 5 = unknown */
+ 0, /* 6 = unknown */
+ 0, /* 7 = unknown */
+ RI_MOUSE_BUTTON_4_DOWN, /* 8 */
+ RI_MOUSE_BUTTON_5_DOWN /* 9 */
+ };
+
+ static const unsigned short raw_button_release_flags[] = {
+ 0, /* 0 = unused */
+ RI_MOUSE_LEFT_BUTTON_UP, /* 1 */
+ RI_MOUSE_MIDDLE_BUTTON_UP, /* 2 */
+ RI_MOUSE_RIGHT_BUTTON_UP, /* 3 */
+ 0, /* 4 = unknown */
+ 0, /* 5 = unknown */
+ 0, /* 6 = unknown */
+ 0, /* 7 = unknown */
+ RI_MOUSE_BUTTON_4_UP, /* 8 */
+ RI_MOUSE_BUTTON_5_UP /* 9 */
+ };
+
+ int detail = ((XIRawEvent*)xev->data)->detail;
+ if (detail > 9) return TRUE;
+
+ ri.header.dwType = RIM_TYPEMOUSE;
+ ri.data.mouse.u.usButtonFlags = xev->evtype == XI_RawButtonPress ? raw_button_press_flags[detail] : raw_button_release_flags[detail] ;
+ ri.data.mouse.u.usButtonData = 0;
+ ri.data.mouse.lLastX = 0;
+ ri.data.mouse.lLastY = 0;
+ ri.data.mouse.ulExtraInformation = 0;
+
+ __wine_send_raw_input( &ri );
+
+ return TRUE;
+}
+
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
@@ -1845,6 +1927,11 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
case XI_RawMotion:
ret = X11DRV_RawMotion( event );
break;
+ case XI_RawButtonPress:
+ /* fall through */
+ case XI_RawButtonRelease:
+ ret = X11DRV_RawButton( event );
+ break;
default:
TRACE( "Unhandled event %#x\n", event->evtype );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a6d64f4383..8af2ebfcef 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -340,6 +340,7 @@ struct x11drv_thread_data
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
struct x11drv_valuator_data x_rel_valuator;
struct x11drv_valuator_data y_rel_valuator;
+ struct x11drv_valuator_data wheel_valuator;
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
--
2.22.0
July 26, 2019
[PATCH v9 6/8] winex11.drv: Implement native mouse-movement raw-input using RawMotion.
by Derek Lesho
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
v9: Remove inform_wineserver, as we don't support button presses / the wheel until patch 7
---
dlls/winex11.drv/mouse.c | 133 ++++++++++++++-------------------
dlls/winex11.drv/x11drv.h | 8 +-
dlls/winex11.drv/x11drv_main.c | 4 +
3 files changed, 64 insertions(+), 81 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f737a306a5..7423f946b9 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -286,13 +286,14 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
/***********************************************************************
- * 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();
XIEventMask mask;
+ int core_pointer;
XIDeviceInfo *pointer_info;
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
int count;
@@ -301,7 +302,7 @@ static void enable_xinput2(void)
if (data->xi2_state == xi_unknown)
{
- int major = 2, minor = 0;
+ int major = 2, minor = 1;
if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
else
{
@@ -310,64 +311,63 @@ static void enable_xinput2(void)
}
}
if (data->xi2_state == xi_unavailable) return;
- if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
+ if (!pXIGetClientPointer( data->display, None, &core_pointer )) return;
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
- mask.deviceid = XIAllDevices;
+ mask.deviceid = XIAllMasterDevices;
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 );
- pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count );
+ pointer_info = pXIQueryDevice( data->display, core_pointer, &count );
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
pXIFreeDeviceInfo( pointer_info );
- /* This device info list is only used to find the initial current slave if
- * no XI_DeviceChanged events happened. If any hierarchy change occurred that
- * might be relevant here (eg. user switching mice after (un)plugging), a
- * XI_DeviceChanged event will point us to the right slave. So this list is
- * safe to be obtained statically at enable_xinput2() time.
- */
- if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
- data->xi2_current_slave = 0;
-
data->xi2_state = xi_enabled;
#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;
mask.mask = NULL;
mask.mask_len = 0;
- mask.deviceid = XIAllDevices;
+ mask.deviceid = XIAllMasterDevices;
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
- pXIFreeDeviceInfo( data->xi2_devices );
data->x_rel_valuator.number = -1;
data->y_rel_valuator.number = -1;
- data->xi2_devices = NULL;
- data->xi2_core_pointer = 0;
- data->xi2_current_slave = 0;
#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 +393,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 +423,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ disable_xinput2_path();
DestroyWindow( msg_hwnd );
return FALSE;
}
@@ -489,7 +489,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 */
@@ -1701,22 +1701,6 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
-/***********************************************************************
- * X11DRV_DeviceChanged
- */
-static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
-{
- XIDeviceChangedEvent *event = xev->data;
- struct x11drv_thread_data *data = x11drv_thread_data();
-
- if (event->deviceid != data->xi2_core_pointer) return FALSE;
- if (event->reason != XISlaveSwitch) return FALSE;
-
- update_relative_valuators( event->classes, event->num_classes );
- data->xi2_current_slave = event->sourceid;
- return TRUE;
-}
-
/***********************************************************************
* X11DRV_RawMotion
*/
@@ -1724,46 +1708,36 @@ 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;
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 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
- * case.
- */
- if (!thread_data->xi2_current_slave)
- {
- XIDeviceInfo *devices = thread_data->xi2_devices;
-
- for (i = 0; i < thread_data->xi2_device_count; i++)
- {
- if (devices[i].use != XISlavePointer) continue;
- if (devices[i].deviceid != event->deviceid) continue;
- if (devices[i].attachment != thread_data->xi2_core_pointer) continue;
- thread_data->xi2_current_slave = event->deviceid;
- break;
- }
- }
-
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
+ if (thread_data->xi2_state < xi_enabled) return FALSE;
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 +1745,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 +1761,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 +1772,15 @@ 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 );
+ }
+
+ 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;
}
@@ -1858,9 +1842,6 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
switch (event->evtype)
{
- case XI_DeviceChanged:
- ret = X11DRV_DeviceChanged( event );
- break;
case XI_RawMotion:
ret = X11DRV_RawMotion( event );
break;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a0308b0675..a6d64f4383 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,13 +337,9 @@ 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 */
- void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
- int xi2_device_count;
+ enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
struct x11drv_valuator_data x_rel_valuator;
struct x11drv_valuator_data y_rel_valuator;
- int xi2_core_pointer; /* XInput2 core pointer id */
- int xi2_current_slave; /* Current slave driving the Core pointer */
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
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 26, 2019
[PATCH v9 5/8] server: Don't emulate rawinput mouse events if native exist.
by Derek Lesho
Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
---
v9: Make raw-mouse emulation all of nothing
---
server/protocol.def | 5 +++--
server/queue.c | 14 ++++++++++----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def
index b5368c71f6..4ce9091661 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -310,8 +310,7 @@ typedef union
/* TODO: fill this in if/when necessary */
} hid;
} hw_rawinput_t;
-#define RIM_ENABLE_NATIVE_MOUSE_MOVE 0x0800
-#define RIM_ENABLE_NATIVE_MOUSE_PRESS 0x1000
+#define RIM_ENABLE_NATIVE_MOUSE 0x0800
struct hardware_msg_data
{
@@ -367,6 +366,8 @@ typedef union
} hw;
} hw_input_t;
+#define RIM_ENABLE_NATIVE_MOUSE_MOVE 0x0800
+#define RIM_ENABLE_NATIVE_MOUSE_PRESS 0x1000
typedef union
{
unsigned char bytes[1]; /* raw data for sent messages */
diff --git a/server/queue.c b/server/queue.c
index 03e64341c1..fd830d2da1 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1599,6 +1599,8 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
return 1;
}
+int emulate_raw_mouse = 1;
+
/* queue a hardware message for a mouse event */
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
unsigned int origin, struct msg_queue *sender )
@@ -1664,7 +1666,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
y = desktop->cursor.y;
}
- if ((device = current->process->rawinput_mouse))
+ device = current->process->rawinput_mouse;
+ if (device && emulate_raw_mouse)
{
if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0;
msg_data = msg->data;
@@ -1713,11 +1716,11 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
}
queue_hardware_message( desktop, msg, 0 );
-
- if (device->flags & RIDEV_NOLEGACY)
- return FALSE;
}
+ if (device && device->flags & RIDEV_NOLEGACY)
+ return FALSE;
+
for (i = 0; i < ARRAY_SIZE( messages ); i++)
{
if (!messages[i]) continue;
@@ -2466,6 +2469,9 @@ DECL_HANDLER(send_rawinput_message)
queue_hardware_message( desktop, msg, 0 );
}
break;
+ case RIM_ENABLE_NATIVE_MOUSE_MOVE:
+ emulate_raw_mouse = 0;
+ break;
default:
set_error( STATUS_INVALID_PARAMETER );
}
--
2.22.0
July 26, 2019
Re: [PATCH v8 7/7] winex11.drv: Don't react to small slow mouse movements.
by Derek Lesho
Just a rebase.
On Fri, Jul 26, 2019 at 3:32 PM 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 f328eb369c..77054618de 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++)
> {
> @@ -1733,6 +1735,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie
> *xev )
> 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 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;
> @@ -1746,15 +1749,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();
>
> @@ -1765,38 +1764,70 @@ 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;
>
> - TRACE("raw event %f,%f\n", raw_dx, raw_dy);
> - __wine_send_raw_input( &raw_input );
> + 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 );
> + }
> + }
> +
> + raw_accum_x += raw_dx;
> + raw_accum_y += raw_dy;
> + if (fabs(raw_accum_x) < 1.0 && fabs(raw_accum_y) < 1.0)
> + {
> + 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 );
> + }
>
> return TRUE;
> }
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index a6d64f4383..7dfc06bcd2 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 26, 2019
Re: [PATCH v8 6/7] winex11.drv: Implement native mouse-movement raw-input using RawMotion.
by Derek Lesho
This update has wine use XI2.1 and removes the legacy code dealing with the
quirks in XI2.0. It also removes the duplicate event detection, as the
server is smarter and will only accept raw-input events from the correct
thread.
Thank you again for debugging the XI2.0 issue Remi!
On Fri, Jul 26, 2019 at 3:31 PM Derek Lesho <dereklesho52(a)gmail.com> wrote:
> Signed-off-by: Derek Lesho <dereklesho52(a)Gmail.com>
> ---
> dlls/winex11.drv/mouse.c | 150 ++++++++++++++++-----------------
> dlls/winex11.drv/x11drv.h | 8 +-
> dlls/winex11.drv/x11drv_main.c | 4 +
> 3 files changed, 81 insertions(+), 81 deletions(-)
>
> diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> index f737a306a5..f328eb369c 100644
> --- a/dlls/winex11.drv/mouse.c
> +++ b/dlls/winex11.drv/mouse.c
> @@ -284,15 +284,31 @@ 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();
> XIEventMask mask;
> + int core_pointer;
> XIDeviceInfo *pointer_info;
> unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
> int count;
> @@ -301,7 +317,7 @@ static void enable_xinput2(void)
>
> if (data->xi2_state == xi_unknown)
> {
> - int major = 2, minor = 0;
> + int major = 2, minor = 1;
> if (!pXIQueryVersion( data->display, &major, &minor ))
> data->xi2_state = xi_disabled;
> else
> {
> @@ -310,64 +326,65 @@ static void enable_xinput2(void)
> }
> }
> if (data->xi2_state == xi_unavailable) return;
> - if (!pXIGetClientPointer( data->display, None,
> &data->xi2_core_pointer )) return;
> + if (!pXIGetClientPointer( data->display, None, &core_pointer ))
> return;
>
> mask.mask = mask_bits;
> mask.mask_len = sizeof(mask_bits);
> - mask.deviceid = XIAllDevices;
> + mask.deviceid = XIAllMasterDevices;
> 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 );
>
> - pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer,
> &count );
> + pointer_info = pXIQueryDevice( data->display, core_pointer, &count );
> update_relative_valuators( pointer_info->classes,
> pointer_info->num_classes );
> pXIFreeDeviceInfo( pointer_info );
>
> - /* This device info list is only used to find the initial current
> slave if
> - * no XI_DeviceChanged events happened. If any hierarchy change
> occurred that
> - * might be relevant here (eg. user switching mice after
> (un)plugging), a
> - * XI_DeviceChanged event will point us to the right slave. So this
> list is
> - * safe to be obtained statically at enable_xinput2() time.
> - */
> - if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
> - data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices,
> &data->xi2_device_count );
> - 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;
>
> mask.mask = NULL;
> mask.mask_len = 0;
> - mask.deviceid = XIAllDevices;
> + mask.deviceid = XIAllMasterDevices;
>
> pXISelectEvents( data->display, DefaultRootWindow( data->display ),
> &mask, 1 );
> - pXIFreeDeviceInfo( data->xi2_devices );
> data->x_rel_valuator.number = -1;
> data->y_rel_valuator.number = -1;
> - data->xi2_devices = NULL;
> - data->xi2_core_pointer = 0;
> - data->xi2_current_slave = 0;
> #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 +410,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 +440,7 @@ static BOOL grab_clipping_window( const RECT *clip )
>
> if (!clipping_cursor)
> {
> - disable_xinput2();
> + disable_xinput2_path();
> DestroyWindow( msg_hwnd );
> return FALSE;
> }
> @@ -489,7 +506,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 */
> @@ -1701,22 +1718,6 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
>
> #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
>
> -/***********************************************************************
> - * X11DRV_DeviceChanged
> - */
> -static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
> -{
> - XIDeviceChangedEvent *event = xev->data;
> - struct x11drv_thread_data *data = x11drv_thread_data();
> -
> - if (event->deviceid != data->xi2_core_pointer) return FALSE;
> - if (event->reason != XISlaveSwitch) return FALSE;
> -
> - update_relative_valuators( event->classes, event->num_classes );
> - data->xi2_current_slave = event->sourceid;
> - return TRUE;
> -}
> -
> /***********************************************************************
> * X11DRV_RawMotion
> */
> @@ -1724,46 +1725,36 @@ 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;
>
> 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 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
> - * case.
> - */
> - if (!thread_data->xi2_current_slave)
> - {
> - XIDeviceInfo *devices = thread_data->xi2_devices;
> -
> - for (i = 0; i < thread_data->xi2_device_count; i++)
> - {
> - if (devices[i].use != XISlavePointer) continue;
> - if (devices[i].deviceid != event->deviceid) continue;
> - if (devices[i].attachment != thread_data->xi2_core_pointer)
> continue;
> - thread_data->xi2_current_slave = event->deviceid;
> - break;
> - }
> - }
> -
> - if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
> + if (thread_data->xi2_state < xi_enabled) return FALSE;
>
> 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 +1762,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 +1778,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 +1789,15 @@ 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 );
> + }
> +
> + 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;
> }
>
> @@ -1858,9 +1859,6 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
>
> switch (event->evtype)
> {
> - case XI_DeviceChanged:
> - ret = X11DRV_DeviceChanged( event );
> - break;
> case XI_RawMotion:
> ret = X11DRV_RawMotion( event );
> break;
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index a0308b0675..a6d64f4383 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,13 +337,9 @@ 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 */
> - void *xi2_devices; /* list of XInput2 devices (valid when
> state is enabled) */
> - int xi2_device_count;
> + enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled,
> xi_extra } xi2_state; /* XInput2 state */
> struct x11drv_valuator_data x_rel_valuator;
> struct x11drv_valuator_data y_rel_valuator;
> - int xi2_core_pointer; /* XInput2 core pointer id */
> - int xi2_current_slave; /* Current slave driving the Core
> pointer */
> };
>
> extern struct x11drv_thread_data *x11drv_init_thread_data(void)
> DECLSPEC_HIDDEN;
> 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 26, 2019