Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
deb74efc
Commit
deb74efc
authored
Jul 06, 2007
by
Vitaliy Margolen
Committed by
Alexandre Julliard
Jul 09, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dinput: Handle multiple keyboard and mouse devices.
parent
6d6e4f4e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
77 additions
and
73 deletions
+77
-73
device_private.h
dlls/dinput/device_private.h
+1
-0
dinput_main.c
dlls/dinput/dinput_main.c
+63
-24
dinput_private.h
dlls/dinput/dinput_private.h
+1
-0
keyboard.c
dlls/dinput/keyboard.c
+8
-28
mouse.c
dlls/dinput/mouse.c
+4
-21
No files found.
dlls/dinput/device_private.h
View file @
deb74efc
...
...
@@ -61,6 +61,7 @@ struct IDirectInputDevice2AImpl
DWORD
dwCoopLevel
;
HWND
win
;
int
acquired
;
DI_EVENT_PROC
event_proc
;
/* function to receive mouse & keyboard events */
LPDIDEVICEOBJECTDATA
data_queue
;
/* buffer for 'GetDeviceData'. */
int
queue_len
;
/* size of the queue - set in 'SetProperty' */
...
...
dlls/dinput/dinput_main.c
View file @
deb74efc
...
...
@@ -678,50 +678,89 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
* DInput hook thread
*/
static
LRESULT
CALLBACK
LL_hook_proc
(
int
code
,
WPARAM
wparam
,
LPARAM
lparam
)
{
IDirectInputImpl
*
dinput
;
if
(
code
!=
HC_ACTION
)
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
EnterCriticalSection
(
&
dinput_hook_crit
);
LIST_FOR_EACH_ENTRY
(
dinput
,
&
direct_input_list
,
IDirectInputImpl
,
entry
)
{
IDirectInputDevice2AImpl
*
dev
;
EnterCriticalSection
(
&
dinput
->
crit
);
LIST_FOR_EACH_ENTRY
(
dev
,
&
dinput
->
devices_list
,
IDirectInputDevice2AImpl
,
entry
)
if
(
dev
->
acquired
&&
dev
->
event_proc
)
{
TRACE
(
"calling %p->%p (%lx %lx)
\n
"
,
dev
,
dev
->
event_proc
,
wparam
,
lparam
);
dev
->
event_proc
(
(
LPDIRECTINPUTDEVICE8A
)
dev
,
wparam
,
lparam
);
}
LeaveCriticalSection
(
&
dinput
->
crit
);
}
LeaveCriticalSection
(
&
dinput_hook_crit
);
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
}
static
LRESULT
CALLBACK
dinput_hook_WndProc
(
HWND
hWnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
static
HHOOK
kbd_hook
,
mouse_hook
;
BOOL
res
;
UINT
kbd_cnt
=
0
,
mice_cnt
=
0
;
TRACE
(
"got message %x %p %p
\n
"
,
message
,
(
LPVOID
)
wParam
,
(
LPVOID
)
lParam
);
switch
(
message
)
{
case
WM_USER
+
0x10
:
if
(
wParam
==
WH_KEYBOARD_LL
)
{
if
(
lParam
)
IDirectInputImpl
*
dinput
;
if
(
!
wParam
&&
!
lParam
)
{
if
(
kbd_hook
)
return
0
;
kbd_hook
=
SetWindowsHookExW
(
WH_KEYBOARD_LL
,
(
LPVOID
)
lParam
,
DINPUT_instance
,
0
);
return
(
LRESULT
)
kbd_hook
;
DestroyWindow
(
hWnd
);
return
0
;
}
else
EnterCriticalSection
(
&
dinput_hook_crit
);
/* Count acquired keyboards and mice*/
LIST_FOR_EACH_ENTRY
(
dinput
,
&
direct_input_list
,
IDirectInputImpl
,
entry
)
{
if
(
!
kbd_hook
)
return
0
;
res
=
UnhookWindowsHookEx
(
kbd_hook
);
kbd_hook
=
NULL
;
return
res
;
IDirectInputDevice2AImpl
*
dev
;
EnterCriticalSection
(
&
dinput
->
crit
);
LIST_FOR_EACH_ENTRY
(
dev
,
&
dinput
->
devices_list
,
IDirectInputDevice2AImpl
,
entry
)
{
if
(
!
dev
->
acquired
)
continue
;
if
(
IsEqualGUID
(
&
dev
->
guid
,
&
GUID_SysKeyboard
)
||
IsEqualGUID
(
&
dev
->
guid
,
&
DInput_Wine_Keyboard_GUID
))
kbd_cnt
++
;
else
if
(
IsEqualGUID
(
&
dev
->
guid
,
&
GUID_SysMouse
)
||
IsEqualGUID
(
&
dev
->
guid
,
&
DInput_Wine_Mouse_GUID
))
mice_cnt
++
;
}
LeaveCriticalSection
(
&
dinput
->
crit
);
}
else
if
(
wParam
==
WH_MOUSE_LL
)
{
if
(
lParam
)
LeaveCriticalSection
(
&
dinput_hook_crit
);
if
(
kbd_cnt
&&
!
kbd_hook
)
kbd_hook
=
SetWindowsHookExW
(
WH_KEYBOARD_LL
,
LL_hook_proc
,
DINPUT_instance
,
0
);
else
if
(
!
kbd_cnt
&&
kbd_hook
)
{
if
(
mouse_hook
)
return
0
;
mouse_hook
=
SetWindowsHookExW
(
WH_MOUSE_LL
,
(
LPVOID
)
lParam
,
DINPUT_instance
,
0
);
return
(
LRESULT
)
mouse_hook
;
UnhookWindowsHookEx
(
kbd_hook
);
kbd_hook
=
NULL
;
}
else
if
(
mice_cnt
&&
!
mouse_hook
)
mouse_hook
=
SetWindowsHookExW
(
WH_MOUSE_LL
,
LL_hook_proc
,
DINPUT_instance
,
0
);
else
if
(
!
mice_cnt
&&
mouse_hook
)
{
if
(
!
mouse_hook
)
return
0
;
res
=
UnhookWindowsHookEx
(
mouse_hook
);
UnhookWindowsHookEx
(
mouse_hook
);
mouse_hook
=
NULL
;
return
res
;
}
}
else
if
(
!
wParam
&&
!
lParam
)
DestroyWindow
(
hWnd
);
return
0
;
case
WM_DESTROY
:
...
...
dlls/dinput/dinput_private.h
View file @
deb74efc
...
...
@@ -58,5 +58,6 @@ extern const struct dinput_device joystick_linuxinput_device;
extern
HINSTANCE
DINPUT_instance
;
extern
HHOOK
set_dinput_hook
(
int
hook_id
,
LPVOID
proc
);
typedef
void
(
*
DI_EVENT_PROC
)(
LPDIRECTINPUTDEVICE8A
,
WPARAM
,
LPARAM
);
#endif
/* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */
dlls/dinput/keyboard.c
View file @
deb74efc
...
...
@@ -50,25 +50,18 @@ struct SysKeyboardImpl
BYTE
DInputKeyState
[
WINE_DINPUT_KEYBOARD_MAX_KEYS
];
};
static
SysKeyboardImpl
*
current_lock
=
NULL
;
/* Today's acquired device
* FIXME: currently this can be only one.
* Maybe this should be a linked list or st.
* I don't know what the rules are for multiple acquired keyboards,
* but 'DI_LOSTFOCUS' and 'DI_UNACQUIRED' exist for a reason.
*/
static
LRESULT
CALLBACK
KeyboardCallback
(
int
code
,
WPARAM
wparam
,
LPARAM
lparam
)
static
void
KeyboardCallback
(
LPDIRECTINPUTDEVICE8A
iface
,
WPARAM
wparam
,
LPARAM
lparam
)
{
SysKeyboardImpl
*
This
=
(
SysKeyboardImpl
*
)
current_lock
;
SysKeyboardImpl
*
This
=
(
SysKeyboardImpl
*
)
iface
;
int
dik_code
;
KBDLLHOOKSTRUCT
*
hook
=
(
KBDLLHOOKSTRUCT
*
)
lparam
;
BYTE
new_diks
;
TRACE
(
"(%d,%ld,%ld)
\n
"
,
code
,
wparam
,
lparam
);
if
(
wparam
!=
WM_KEYDOWN
&&
wparam
!=
WM_KEYUP
&&
wparam
!=
WM_SYSKEYDOWN
&&
wparam
!=
WM_SYSKEYUP
)
return
;
/* returns now if not HC_ACTION */
if
(
code
!=
HC_ACTION
)
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
TRACE
(
"(%p) %ld,%ld
\n
"
,
iface
,
wparam
,
lparam
);
dik_code
=
hook
->
scanCode
&
0xff
;
if
(
hook
->
flags
&
LLKHF_EXTENDED
)
dik_code
|=
0x80
;
...
...
@@ -77,7 +70,7 @@ static LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam
/* returns now if key event already known */
if
(
new_diks
==
This
->
DInputKeyState
[
dik_code
])
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
)
;
return
;
This
->
DInputKeyState
[
dik_code
]
=
new_diks
;
TRACE
(
" setting %02X to %02X
\n
"
,
dik_code
,
This
->
DInputKeyState
[
dik_code
]);
...
...
@@ -86,8 +79,6 @@ static LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam
EnterCriticalSection
(
&
This
->
base
.
crit
);
queue_event
((
LPDIRECTINPUTDEVICE8A
)
This
,
dik_code
,
new_diks
,
hook
->
time
,
This
->
base
.
dinput
->
evsequence
++
);
LeaveCriticalSection
(
&
This
->
base
.
crit
);
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
}
const
GUID
DInput_Wine_Keyboard_GUID
=
{
/* 0ab8648a-7735-11d2-8c73-71df54a96441 */
...
...
@@ -189,6 +180,7 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, const void *kvt, IDirectInpu
newDevice
->
base
.
ref
=
1
;
memcpy
(
&
newDevice
->
base
.
guid
,
rguid
,
sizeof
(
*
rguid
));
newDevice
->
base
.
dinput
=
dinput
;
newDevice
->
base
.
event_proc
=
KeyboardCallback
;
InitializeCriticalSection
(
&
newDevice
->
base
.
crit
);
newDevice
->
base
.
crit
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": SysKeyboardImpl*->base.crit"
);
...
...
@@ -306,12 +298,6 @@ static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
if
((
res
=
IDirectInputDevice2AImpl_Acquire
(
iface
))
!=
DI_OK
)
return
res
;
if
(
current_lock
!=
NULL
)
{
FIXME
(
"Not more than one keyboard can be acquired at the same time.
\n
"
);
SysKeyboardAImpl_Unacquire
((
LPDIRECTINPUTDEVICE8A
)
current_lock
);
}
current_lock
=
This
;
set_dinput_hook
(
WH_KEYBOARD_LL
,
KeyboardCallback
);
return
DI_OK
;
...
...
@@ -328,12 +314,6 @@ static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
set_dinput_hook
(
WH_KEYBOARD_LL
,
NULL
);
/* No more locks */
if
(
current_lock
==
This
)
current_lock
=
NULL
;
else
ERR
(
"this != current_lock
\n
"
);
return
DI_OK
;
}
...
...
dlls/dinput/mouse.c
View file @
deb74efc
...
...
@@ -68,8 +68,7 @@ struct SysMouseImpl
DIMOUSESTATE2
m_state
;
};
/* FIXME: This is ugly and not thread safe :/ */
static
IDirectInputDevice8A
*
current_lock
=
NULL
;
static
void
dinput_mouse_hook
(
LPDIRECTINPUTDEVICE8A
iface
,
WPARAM
wparam
,
LPARAM
lparam
);
const
GUID
DInput_Wine_Mouse_GUID
=
{
/* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
0x9e573ed8
,
0x7734
,
0x11d2
,
{
0x8d
,
0x4a
,
0x23
,
0x90
,
0x3f
,
0xb6
,
0xbd
,
0xf7
}
...
...
@@ -174,6 +173,7 @@ static SysMouseImpl *alloc_device(REFGUID rguid, const void *mvt, IDirectInputIm
InitializeCriticalSection
(
&
newDevice
->
base
.
crit
);
newDevice
->
base
.
crit
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": SysMouseImpl*->base.crit"
);
newDevice
->
base
.
dinput
=
dinput
;
newDevice
->
base
.
event_proc
=
dinput_mouse_hook
;
/* Create copy of default data format */
if
(
!
(
df
=
HeapAlloc
(
GetProcessHeap
(),
0
,
c_dfDIMouse2
.
dwSize
)))
goto
failed
;
...
...
@@ -252,15 +252,13 @@ const struct dinput_device mouse_device = {
*/
/* low-level mouse hook */
static
LRESULT
CALLBACK
dinput_mouse_hook
(
int
cod
e
,
WPARAM
wparam
,
LPARAM
lparam
)
static
void
dinput_mouse_hook
(
LPDIRECTINPUTDEVICE8A
ifac
e
,
WPARAM
wparam
,
LPARAM
lparam
)
{
MSLLHOOKSTRUCT
*
hook
=
(
MSLLHOOKSTRUCT
*
)
lparam
;
SysMouseImpl
*
This
=
(
SysMouseImpl
*
)
current_lock
;
SysMouseImpl
*
This
=
(
SysMouseImpl
*
)
iface
;
DWORD
dwCoop
;
int
wdata
=
0
,
inst_id
=
-
1
;
if
(
code
!=
HC_ACTION
)
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
EnterCriticalSection
(
&
This
->
base
.
crit
);
dwCoop
=
This
->
base
.
dwCoopLevel
;
...
...
@@ -345,12 +343,6 @@ static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lpara
wdata
,
hook
->
time
,
This
->
base
.
dinput
->
evsequence
++
);
LeaveCriticalSection
(
&
This
->
base
.
crit
);
/* Ignore message */
if
(
dwCoop
&
DISCL_EXCLUSIVE
)
return
1
;
/* Pass the events down to previous handlers (e.g. win32 input) */
return
CallNextHookEx
(
0
,
code
,
wparam
,
lparam
);
}
static
BOOL
dinput_window_check
(
SysMouseImpl
*
This
)
{
...
...
@@ -387,9 +379,6 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
if
((
res
=
IDirectInputDevice2AImpl_Acquire
(
iface
))
!=
DI_OK
)
return
res
;
/* Store (in a global variable) the current lock */
current_lock
=
(
IDirectInputDevice8A
*
)
This
;
/* Init the mouse state */
GetCursorPos
(
&
point
);
if
(
This
->
base
.
data_format
.
user_df
->
dwFlags
&
DIDF_ABSAXIS
)
...
...
@@ -448,12 +437,6 @@ static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
if
(
This
->
base
.
dwCoopLevel
&
DISCL_EXCLUSIVE
)
ShowCursor
(
TRUE
);
/* show cursor */
/* No more locks */
if
(
current_lock
==
(
IDirectInputDevice8A
*
)
This
)
current_lock
=
NULL
;
else
ERR
(
"this(%p) != current_lock(%p)
\n
"
,
This
,
current_lock
);
/* And put the mouse cursor back where it was at acquire time */
if
(
This
->
base
.
dwCoopLevel
&
DISCL_EXCLUSIVE
)
{
...
...
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