Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c1d51031
Commit
c1d51031
authored
Jan 23, 2020
by
Andrew Eikum
Committed by
Alexandre Julliard
Jan 24, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xinput: Implement XInputGetKeystroke.
Signed-off-by:
Andrew Eikum
<
aeikum@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
c55e8822
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
209 additions
and
8 deletions
+209
-8
xinput_main.c
dlls/xinput1_3/xinput_main.c
+208
-8
xinput_private.h
dlls/xinput1_3/xinput_private.h
+1
-0
No files found.
dlls/xinput1_3/xinput_main.c
View file @
c1d51031
...
...
@@ -202,19 +202,219 @@ DWORD WINAPI DECLSPEC_HOTPATCH XInputGetStateEx(DWORD index, XINPUT_STATE* state
return
xinput_get_state
(
index
,
state
);
}
DWORD
WINAPI
DECLSPEC_HOTPATCH
XInputGetKeystroke
(
DWORD
index
,
DWORD
reserved
,
PXINPUT_KEYSTROKE
keystroke
)
static
const
int
JS_STATE_OFF
=
0
;
static
const
int
JS_STATE_LOW
=
1
;
static
const
int
JS_STATE_HIGH
=
2
;
static
int
joystick_state
(
const
SHORT
value
)
{
static
int
warn_once
;
if
(
value
>
20000
)
return
JS_STATE_HIGH
;
if
(
value
<
-
20000
)
return
JS_STATE_LOW
;
return
JS_STATE_OFF
;
}
if
(
!
warn_once
++
)
FIXME
(
"(index %u, reserved %u, keystroke %p) Stub!
\n
"
,
index
,
reserved
,
keystroke
);
static
WORD
js_vk_offs
(
const
int
x
,
const
int
y
)
{
if
(
y
==
JS_STATE_OFF
)
{
/*if (x == JS_STATE_OFF) shouldn't get here */
if
(
x
==
JS_STATE_LOW
)
return
3
;
/* LEFT */
/*if (x == JS_STATE_HIGH)*/
return
2
;
/* RIGHT */
}
if
(
y
==
JS_STATE_HIGH
)
{
if
(
x
==
JS_STATE_OFF
)
return
0
;
/* UP */
if
(
x
==
JS_STATE_LOW
)
return
4
;
/* UPLEFT */
/*if (x == JS_STATE_HIGH)*/
return
5
;
/* UPRIGHT */
}
/*if (y == JS_STATE_LOW)*/
{
if
(
x
==
JS_STATE_OFF
)
return
1
;
/* DOWN */
if
(
x
==
JS_STATE_LOW
)
return
7
;
/* DOWNLEFT */
/*if (x == JS_STATE_HIGH)*/
return
6
;
/* DOWNRIGHT */
}
}
if
(
index
>=
XUSER_MAX_COUNT
)
return
ERROR_BAD_ARGUMENTS
;
if
(
!
controllers
[
index
].
platform_private
)
static
DWORD
check_joystick_keystroke
(
const
DWORD
index
,
XINPUT_KEYSTROKE
*
keystroke
,
const
SHORT
*
cur_x
,
const
SHORT
*
cur_y
,
SHORT
*
last_x
,
SHORT
*
last_y
,
const
WORD
base_vk
)
{
int
cur_vk
=
0
,
cur_x_st
,
cur_y_st
;
int
last_vk
=
0
,
last_x_st
,
last_y_st
;
cur_x_st
=
joystick_state
(
*
cur_x
);
cur_y_st
=
joystick_state
(
*
cur_y
);
if
(
cur_x_st
||
cur_y_st
)
cur_vk
=
base_vk
+
js_vk_offs
(
cur_x_st
,
cur_y_st
);
last_x_st
=
joystick_state
(
*
last_x
);
last_y_st
=
joystick_state
(
*
last_y
);
if
(
last_x_st
||
last_y_st
)
last_vk
=
base_vk
+
js_vk_offs
(
last_x_st
,
last_y_st
);
if
(
cur_vk
!=
last_vk
)
{
if
(
last_vk
)
{
/* joystick was set, and now different. send a KEYUP event, and set
* last pos to centered, so the appropriate KEYDOWN event will be
* sent on the next call. */
keystroke
->
VirtualKey
=
last_vk
;
keystroke
->
Unicode
=
0
;
/* unused */
keystroke
->
Flags
=
XINPUT_KEYSTROKE_KEYUP
;
keystroke
->
UserIndex
=
index
;
keystroke
->
HidCode
=
0
;
*
last_x
=
0
;
*
last_y
=
0
;
return
ERROR_SUCCESS
;
}
/* joystick was unset, send KEYDOWN. */
keystroke
->
VirtualKey
=
cur_vk
;
keystroke
->
Unicode
=
0
;
/* unused */
keystroke
->
Flags
=
XINPUT_KEYSTROKE_KEYDOWN
;
keystroke
->
UserIndex
=
index
;
keystroke
->
HidCode
=
0
;
*
last_x
=
*
cur_x
;
*
last_y
=
*
cur_y
;
return
ERROR_SUCCESS
;
}
*
last_x
=
*
cur_x
;
*
last_y
=
*
cur_y
;
return
ERROR_EMPTY
;
}
static
BOOL
trigger_is_on
(
const
BYTE
value
)
{
return
value
>
30
;
}
static
DWORD
check_for_keystroke
(
const
DWORD
index
,
XINPUT_KEYSTROKE
*
keystroke
)
{
xinput_controller
*
device
=
&
controllers
[
index
];
const
XINPUT_GAMEPAD
*
cur
;
DWORD
ret
=
ERROR_EMPTY
;
int
i
;
static
const
struct
{
int
mask
;
WORD
vk
;
}
buttons
[]
=
{
{
XINPUT_GAMEPAD_DPAD_UP
,
VK_PAD_DPAD_UP
},
{
XINPUT_GAMEPAD_DPAD_DOWN
,
VK_PAD_DPAD_DOWN
},
{
XINPUT_GAMEPAD_DPAD_LEFT
,
VK_PAD_DPAD_LEFT
},
{
XINPUT_GAMEPAD_DPAD_RIGHT
,
VK_PAD_DPAD_RIGHT
},
{
XINPUT_GAMEPAD_START
,
VK_PAD_START
},
{
XINPUT_GAMEPAD_BACK
,
VK_PAD_BACK
},
{
XINPUT_GAMEPAD_LEFT_THUMB
,
VK_PAD_LTHUMB_PRESS
},
{
XINPUT_GAMEPAD_RIGHT_THUMB
,
VK_PAD_RTHUMB_PRESS
},
{
XINPUT_GAMEPAD_LEFT_SHOULDER
,
VK_PAD_LSHOULDER
},
{
XINPUT_GAMEPAD_RIGHT_SHOULDER
,
VK_PAD_RSHOULDER
},
{
XINPUT_GAMEPAD_A
,
VK_PAD_A
},
{
XINPUT_GAMEPAD_B
,
VK_PAD_B
},
{
XINPUT_GAMEPAD_X
,
VK_PAD_X
},
{
XINPUT_GAMEPAD_Y
,
VK_PAD_Y
},
/* note: guide button does not send an event */
};
if
(
!
verify_and_lock_device
(
device
))
return
ERROR_DEVICE_NOT_CONNECTED
;
return
ERROR_NOT_SUPPORTED
;
cur
=
&
device
->
state
.
Gamepad
;
/*** buttons ***/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
buttons
);
++
i
)
{
if
((
cur
->
wButtons
&
buttons
[
i
].
mask
)
^
(
device
->
last_keystroke
.
wButtons
&
buttons
[
i
].
mask
))
{
keystroke
->
VirtualKey
=
buttons
[
i
].
vk
;
keystroke
->
Unicode
=
0
;
/* unused */
if
(
cur
->
wButtons
&
buttons
[
i
].
mask
)
{
keystroke
->
Flags
=
XINPUT_KEYSTROKE_KEYDOWN
;
device
->
last_keystroke
.
wButtons
|=
buttons
[
i
].
mask
;
}
else
{
keystroke
->
Flags
=
XINPUT_KEYSTROKE_KEYUP
;
device
->
last_keystroke
.
wButtons
&=
~
buttons
[
i
].
mask
;
}
keystroke
->
UserIndex
=
index
;
keystroke
->
HidCode
=
0
;
ret
=
ERROR_SUCCESS
;
goto
done
;
}
}
/*** triggers ***/
if
(
trigger_is_on
(
cur
->
bLeftTrigger
)
^
trigger_is_on
(
device
->
last_keystroke
.
bLeftTrigger
))
{
keystroke
->
VirtualKey
=
VK_PAD_LTRIGGER
;
keystroke
->
Unicode
=
0
;
/* unused */
keystroke
->
Flags
=
trigger_is_on
(
cur
->
bLeftTrigger
)
?
XINPUT_KEYSTROKE_KEYDOWN
:
XINPUT_KEYSTROKE_KEYUP
;
keystroke
->
UserIndex
=
index
;
keystroke
->
HidCode
=
0
;
device
->
last_keystroke
.
bLeftTrigger
=
cur
->
bLeftTrigger
;
ret
=
ERROR_SUCCESS
;
goto
done
;
}
if
(
trigger_is_on
(
cur
->
bRightTrigger
)
^
trigger_is_on
(
device
->
last_keystroke
.
bRightTrigger
))
{
keystroke
->
VirtualKey
=
VK_PAD_RTRIGGER
;
keystroke
->
Unicode
=
0
;
/* unused */
keystroke
->
Flags
=
trigger_is_on
(
cur
->
bRightTrigger
)
?
XINPUT_KEYSTROKE_KEYDOWN
:
XINPUT_KEYSTROKE_KEYUP
;
keystroke
->
UserIndex
=
index
;
keystroke
->
HidCode
=
0
;
device
->
last_keystroke
.
bRightTrigger
=
cur
->
bRightTrigger
;
ret
=
ERROR_SUCCESS
;
goto
done
;
}
/*** joysticks ***/
ret
=
check_joystick_keystroke
(
index
,
keystroke
,
&
cur
->
sThumbLX
,
&
cur
->
sThumbLY
,
&
device
->
last_keystroke
.
sThumbLX
,
&
device
->
last_keystroke
.
sThumbLY
,
VK_PAD_LTHUMB_UP
);
if
(
ret
==
ERROR_SUCCESS
)
goto
done
;
ret
=
check_joystick_keystroke
(
index
,
keystroke
,
&
cur
->
sThumbRX
,
&
cur
->
sThumbRY
,
&
device
->
last_keystroke
.
sThumbRX
,
&
device
->
last_keystroke
.
sThumbRY
,
VK_PAD_RTHUMB_UP
);
if
(
ret
==
ERROR_SUCCESS
)
goto
done
;
done:
unlock_device
(
device
);
return
ret
;
}
DWORD
WINAPI
DECLSPEC_HOTPATCH
XInputGetKeystroke
(
DWORD
index
,
DWORD
reserved
,
PXINPUT_KEYSTROKE
keystroke
)
{
TRACE
(
"(index %u, reserved %u, keystroke %p)
\n
"
,
index
,
reserved
,
keystroke
);
if
(
index
>=
XUSER_MAX_COUNT
&&
index
!=
XUSER_INDEX_ANY
)
return
ERROR_BAD_ARGUMENTS
;
if
(
index
==
XUSER_INDEX_ANY
)
{
int
i
;
for
(
i
=
0
;
i
<
XUSER_MAX_COUNT
;
++
i
)
if
(
check_for_keystroke
(
i
,
keystroke
)
==
ERROR_SUCCESS
)
return
ERROR_SUCCESS
;
return
ERROR_EMPTY
;
}
return
check_for_keystroke
(
index
,
keystroke
);
}
DWORD
WINAPI
DECLSPEC_HOTPATCH
XInputGetCapabilities
(
DWORD
index
,
DWORD
flags
,
XINPUT_CAPABILITIES
*
capabilities
)
...
...
dlls/xinput1_3/xinput_private.h
View file @
c1d51031
...
...
@@ -23,6 +23,7 @@ typedef struct _xinput_controller
XINPUT_CAPABILITIES
caps
;
void
*
platform_private
;
/* non-NULL when device is valid; validity may be read without holding crit */
XINPUT_STATE
state
;
XINPUT_GAMEPAD
last_keystroke
;
XINPUT_VIBRATION
vibration
;
}
xinput_controller
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment