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
eda33b4b
Commit
eda33b4b
authored
Feb 21, 2018
by
Aric Stewart
Committed by
Alexandre Julliard
Feb 21, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebus.sys: Build SDL device report.
Signed-off-by:
Aric Stewart
<
aric@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
752de1b5
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
312 additions
and
95 deletions
+312
-95
bus_sdl.c
dlls/winebus.sys/bus_sdl.c
+196
-1
bus_udev.c
dlls/winebus.sys/bus_udev.c
+1
-94
controller.h
dlls/winebus.sys/controller.h
+115
-0
No files found.
dlls/winebus.sys/bus_sdl.c
View file @
eda33b4b
...
...
@@ -45,6 +45,7 @@
#include "wine/debug.h"
#include "wine/unicode.h"
#include "hidusage.h"
#include "controller.h"
#ifdef WORDS_BIGENDIAN
# define LE_WORD(x) RtlUshortByteSwap(x)
...
...
@@ -81,6 +82,9 @@ MAKE_FUNCPTR(SDL_JoystickName);
MAKE_FUNCPTR
(
SDL_JoystickNumAxes
);
MAKE_FUNCPTR
(
SDL_JoystickOpen
);
MAKE_FUNCPTR
(
SDL_WaitEvent
);
MAKE_FUNCPTR
(
SDL_JoystickNumButtons
);
MAKE_FUNCPTR
(
SDL_JoystickNumBalls
);
MAKE_FUNCPTR
(
SDL_JoystickNumHats
);
#endif
static
Uint16
(
*
pSDL_JoystickGetProduct
)(
SDL_Joystick
*
joystick
);
static
Uint16
(
*
pSDL_JoystickGetProductVersion
)(
SDL_Joystick
*
joystick
);
...
...
@@ -90,6 +94,13 @@ struct platform_private
{
SDL_Joystick
*
sdl_joystick
;
SDL_JoystickID
id
;
int
axis_start
;
int
ball_start
;
int
hat_start
;
int
report_descriptor_size
;
BYTE
*
report_descriptor
;
};
static
inline
struct
platform_private
*
impl_from_DEVICE_OBJECT
(
DEVICE_OBJECT
*
device
)
...
...
@@ -97,6 +108,171 @@ static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *de
return
(
struct
platform_private
*
)
get_platform_private
(
device
);
}
static
const
BYTE
REPORT_AXIS_TAIL
[]
=
{
0x16
,
0x00
,
0x80
,
/* LOGICAL_MINIMUM (-32768) */
0x26
,
0xff
,
0x7f
,
/* LOGICAL_MAXIMUM (32767) */
0x36
,
0x00
,
0x80
,
/* PHYSICAL_MINIMUM (-32768) */
0x46
,
0xff
,
0x7f
,
/* PHYSICAL_MAXIMUM (32767) */
0x75
,
0x10
,
/* REPORT_SIZE (16) */
0x95
,
0x00
,
/* REPORT_COUNT (?) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
};
#define IDX_ABS_AXIS_COUNT 15
static
BYTE
*
add_axis_block
(
BYTE
*
report_ptr
,
BYTE
count
,
BYTE
page
,
const
BYTE
*
usages
,
BOOL
absolute
)
{
int
i
;
memcpy
(
report_ptr
,
REPORT_AXIS_HEADER
,
sizeof
(
REPORT_AXIS_HEADER
));
report_ptr
[
IDX_AXIS_PAGE
]
=
page
;
report_ptr
+=
sizeof
(
REPORT_AXIS_HEADER
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
memcpy
(
report_ptr
,
REPORT_AXIS_USAGE
,
sizeof
(
REPORT_AXIS_USAGE
));
report_ptr
[
IDX_AXIS_USAGE
]
=
usages
[
i
];
report_ptr
+=
sizeof
(
REPORT_AXIS_USAGE
);
}
if
(
absolute
)
{
memcpy
(
report_ptr
,
REPORT_AXIS_TAIL
,
sizeof
(
REPORT_AXIS_TAIL
));
report_ptr
[
IDX_ABS_AXIS_COUNT
]
=
count
;
report_ptr
+=
sizeof
(
REPORT_AXIS_TAIL
);
}
else
{
memcpy
(
report_ptr
,
REPORT_REL_AXIS_TAIL
,
sizeof
(
REPORT_REL_AXIS_TAIL
));
report_ptr
[
IDX_REL_AXIS_COUNT
]
=
count
;
report_ptr
+=
sizeof
(
REPORT_REL_AXIS_TAIL
);
}
return
report_ptr
;
}
static
BOOL
build_report_descriptor
(
struct
platform_private
*
ext
)
{
BYTE
*
report_ptr
;
INT
i
,
descript_size
;
INT
report_size
;
INT
button_count
,
axis_count
,
ball_count
,
hat_count
;
static
const
BYTE
device_usage
[
2
]
=
{
HID_USAGE_PAGE_GENERIC
,
HID_USAGE_GENERIC_GAMEPAD
};
static
const
BYTE
controller_usages
[]
=
{
HID_USAGE_GENERIC_X
,
HID_USAGE_GENERIC_Y
,
HID_USAGE_GENERIC_Z
,
HID_USAGE_GENERIC_RX
,
HID_USAGE_GENERIC_RY
,
HID_USAGE_GENERIC_RZ
,
HID_USAGE_GENERIC_SLIDER
,
HID_USAGE_GENERIC_DIAL
,
HID_USAGE_GENERIC_WHEEL
};
static
const
BYTE
joystick_usages
[]
=
{
HID_USAGE_GENERIC_X
,
HID_USAGE_GENERIC_Y
,
HID_USAGE_GENERIC_Z
,
HID_USAGE_GENERIC_RZ
,
HID_USAGE_GENERIC_RX
,
HID_USAGE_GENERIC_RY
,
HID_USAGE_GENERIC_SLIDER
,
HID_USAGE_GENERIC_DIAL
,
HID_USAGE_GENERIC_WHEEL
};
descript_size
=
sizeof
(
REPORT_HEADER
)
+
sizeof
(
REPORT_TAIL
);
report_size
=
0
;
/* For now lump all buttons just into incremental usages, Ignore Keys */
button_count
=
pSDL_JoystickNumButtons
(
ext
->
sdl_joystick
);
if
(
button_count
)
{
descript_size
+=
sizeof
(
REPORT_BUTTONS
);
if
(
button_count
%
8
)
descript_size
+=
sizeof
(
REPORT_PADDING
);
report_size
=
(
button_count
+
7
)
/
8
;
}
axis_count
=
pSDL_JoystickNumAxes
(
ext
->
sdl_joystick
);
if
(
axis_count
>
6
)
{
FIXME
(
"Clamping joystick to 6 axis
\n
"
);
axis_count
=
6
;
}
ext
->
axis_start
=
report_size
;
if
(
axis_count
)
{
descript_size
+=
sizeof
(
REPORT_AXIS_HEADER
);
descript_size
+=
(
sizeof
(
REPORT_AXIS_USAGE
)
*
axis_count
);
descript_size
+=
sizeof
(
REPORT_AXIS_TAIL
);
report_size
+=
(
2
*
axis_count
);
}
ball_count
=
pSDL_JoystickNumBalls
(
ext
->
sdl_joystick
);
ext
->
ball_start
=
report_size
;
if
(
ball_count
)
{
if
((
ball_count
*
2
)
+
axis_count
>
9
)
{
FIXME
(
"Capping ball + axis at 9
\n
"
);
ball_count
=
(
9
-
axis_count
)
/
2
;
}
descript_size
+=
sizeof
(
REPORT_AXIS_HEADER
);
descript_size
+=
(
sizeof
(
REPORT_AXIS_USAGE
)
*
ball_count
*
2
);
descript_size
+=
sizeof
(
REPORT_REL_AXIS_TAIL
);
report_size
+=
(
2
*
ball_count
);
}
hat_count
=
pSDL_JoystickNumHats
(
ext
->
sdl_joystick
);
ext
->
hat_start
=
report_size
;
if
(
hat_count
)
{
descript_size
+=
sizeof
(
REPORT_HATSWITCH
);
for
(
i
=
0
;
i
<
hat_count
;
i
++
)
report_size
++
;
}
TRACE
(
"Report Descriptor will be %i bytes
\n
"
,
descript_size
);
TRACE
(
"Report will be %i bytes
\n
"
,
report_size
);
ext
->
report_descriptor
=
HeapAlloc
(
GetProcessHeap
(),
0
,
descript_size
);
if
(
!
ext
->
report_descriptor
)
{
ERR
(
"Failed to alloc report descriptor
\n
"
);
return
FALSE
;
}
report_ptr
=
ext
->
report_descriptor
;
memcpy
(
report_ptr
,
REPORT_HEADER
,
sizeof
(
REPORT_HEADER
));
report_ptr
[
IDX_HEADER_PAGE
]
=
device_usage
[
0
];
report_ptr
[
IDX_HEADER_USAGE
]
=
device_usage
[
1
];
report_ptr
+=
sizeof
(
REPORT_HEADER
);
if
(
button_count
)
{
report_ptr
=
add_button_block
(
report_ptr
,
1
,
button_count
);
if
(
button_count
%
8
)
{
BYTE
padding
=
8
-
(
button_count
%
8
);
report_ptr
=
add_padding_block
(
report_ptr
,
padding
);
}
}
if
(
axis_count
)
{
if
(
axis_count
==
6
&&
button_count
>=
14
)
report_ptr
=
add_axis_block
(
report_ptr
,
axis_count
,
HID_USAGE_PAGE_GENERIC
,
controller_usages
,
TRUE
);
else
report_ptr
=
add_axis_block
(
report_ptr
,
axis_count
,
HID_USAGE_PAGE_GENERIC
,
joystick_usages
,
TRUE
);
}
if
(
ball_count
)
{
report_ptr
=
add_axis_block
(
report_ptr
,
ball_count
*
2
,
HID_USAGE_PAGE_GENERIC
,
&
joystick_usages
[
axis_count
],
FALSE
);
}
if
(
hat_count
)
report_ptr
=
add_hatswitch
(
report_ptr
,
hat_count
);
memcpy
(
report_ptr
,
REPORT_TAIL
,
sizeof
(
REPORT_TAIL
));
ext
->
report_descriptor_size
=
descript_size
;
return
TRUE
;
}
static
int
compare_platform_device
(
DEVICE_OBJECT
*
device
,
void
*
platform_dev
)
{
SDL_JoystickID
id1
=
impl_from_DEVICE_OBJECT
(
device
)
->
id
;
...
...
@@ -106,7 +282,16 @@ static int compare_platform_device(DEVICE_OBJECT *device, void *platform_dev)
static
NTSTATUS
get_reportdescriptor
(
DEVICE_OBJECT
*
device
,
BYTE
*
buffer
,
DWORD
length
,
DWORD
*
out_length
)
{
return
STATUS_NOT_IMPLEMENTED
;
struct
platform_private
*
ext
=
impl_from_DEVICE_OBJECT
(
device
);
*
out_length
=
ext
->
report_descriptor_size
;
if
(
length
<
ext
->
report_descriptor_size
)
return
STATUS_BUFFER_TOO_SMALL
;
memcpy
(
buffer
,
ext
->
report_descriptor
,
ext
->
report_descriptor_size
);
return
STATUS_SUCCESS
;
}
static
NTSTATUS
get_string
(
DEVICE_OBJECT
*
device
,
DWORD
index
,
WCHAR
*
buffer
,
DWORD
length
)
...
...
@@ -233,6 +418,13 @@ static void try_add_device(SDL_JoystickID index)
struct
platform_private
*
private
=
impl_from_DEVICE_OBJECT
(
device
);
private
->
sdl_joystick
=
joystick
;
private
->
id
=
id
;
if
(
!
build_report_descriptor
(
private
))
{
ERR
(
"Building report descriptor failed, removing device
\n
"
);
bus_remove_hid_device
(
device
);
HeapFree
(
GetProcessHeap
(),
0
,
serial
);
return
;
}
IoInvalidateDeviceRelations
(
device
,
BusRelations
);
}
else
...
...
@@ -299,6 +491,9 @@ NTSTATUS WINAPI sdl_driver_init(DRIVER_OBJECT *driver, UNICODE_STRING *registry_
LOAD_FUNCPTR
(
SDL_JoystickNumAxes
);
LOAD_FUNCPTR
(
SDL_JoystickOpen
);
LOAD_FUNCPTR
(
SDL_WaitEvent
);
LOAD_FUNCPTR
(
SDL_JoystickNumButtons
);
LOAD_FUNCPTR
(
SDL_JoystickNumBalls
);
LOAD_FUNCPTR
(
SDL_JoystickNumHats
);
#undef LOAD_FUNCPTR
pSDL_JoystickGetProduct
=
wine_dlsym
(
sdl_handle
,
"SDL_JoystickGetProduct"
,
NULL
,
0
);
pSDL_JoystickGetProductVersion
=
wine_dlsym
(
sdl_handle
,
"SDL_JoystickGetProductVersion"
,
NULL
,
0
);
...
...
dlls/winebus.sys/bus_udev.c
View file @
eda33b4b
...
...
@@ -75,6 +75,7 @@
#define LE_DWORD(x) (x)
#endif
#include "controller.h"
#include "bus.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
plugplay
);
...
...
@@ -110,50 +111,6 @@ static inline struct platform_private *impl_from_DEVICE_OBJECT(DEVICE_OBJECT *de
}
#ifdef HAS_PROPER_INPUT_HEADER
static
const
BYTE
REPORT_HEADER
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
0x09
,
0x00
,
/* USAGE (??) */
0xa1
,
0x01
,
/* COLLECTION (Application) */
0x09
,
0x01
,
/* USAGE () */
0xa1
,
0x00
,
/* COLLECTION (Physical) */
};
#define IDX_HEADER_PAGE 1
#define IDX_HEADER_USAGE 3
static
const
BYTE
REPORT_BUTTONS
[]
=
{
0x05
,
0x09
,
/* USAGE_PAGE (Button) */
0x19
,
0x01
,
/* USAGE_MINIMUM (Button 1) */
0x29
,
0x03
,
/* USAGE_MAXIMUM (Button 3) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x01
,
/* LOGICAL_MAXIMUM (1) */
0x35
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x45
,
0x01
,
/* LOGICAL_MAXIMUM (1) */
0x95
,
0x03
,
/* REPORT_COUNT (3) */
0x75
,
0x01
,
/* REPORT_SIZE (1) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
};
#define IDX_BUTTON_MIN_USAGE 3
#define IDX_BUTTON_MAX_USAGE 5
#define IDX_BUTTON_COUNT 11
static
const
BYTE
REPORT_PADDING
[]
=
{
0x95
,
0x03
,
/* REPORT_COUNT (3) */
0x75
,
0x01
,
/* REPORT_SIZE (1) */
0x81
,
0x03
,
/* INPUT (Cnst,Var,Abs) */
};
#define IDX_PADDING_BIT_COUNT 1
static
const
BYTE
REPORT_AXIS_HEADER
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
};
#define IDX_AXIS_PAGE 1
static
const
BYTE
REPORT_AXIS_USAGE
[]
=
{
0x09
,
0x30
,
/* USAGE (X) */
};
#define IDX_AXIS_USAGE 1
static
const
BYTE
REPORT_ABS_AXIS_TAIL
[]
=
{
0x17
,
0x00
,
0x00
,
0x00
,
0x00
,
/* LOGICAL_MINIMUM (0) */
...
...
@@ -170,33 +127,6 @@ static const BYTE REPORT_ABS_AXIS_TAIL[] = {
#define IDX_ABS_PHY_MAXIMUM 16
#define IDX_ABS_AXIS_COUNT 23
static
const
BYTE
REPORT_REL_AXIS_TAIL
[]
=
{
0x15
,
0x81
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x7f
,
/* LOGICAL_MAXIMUM (0xffff) */
0x75
,
0x08
,
/* REPORT_SIZE (16) */
0x95
,
0x02
,
/* REPORT_COUNT (2) */
0x81
,
0x06
,
/* INPUT (Data,Var,Rel) */
};
#define IDX_REL_AXIS_COUNT 7
static
const
BYTE
REPORT_HATSWITCH
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
0x09
,
0x39
,
/* USAGE (Hatswitch) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x08
,
/* LOGICAL_MAXIMUM (0x08) */
0x35
,
0x00
,
/* PHYSICAL_MINIMUM (0) */
0x45
,
0x08
,
/* PHYSICAL_MAXIMUM (8) */
0x75
,
0x08
,
/* REPORT_SIZE (8) */
0x95
,
0x01
,
/* REPORT_COUNT (1) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
};
#define IDX_HATSWITCH_COUNT 15
static
const
BYTE
REPORT_TAIL
[]
=
{
0xc0
,
/* END_COLLECTION */
0xc0
/* END_COLLECTION */
};
static
const
BYTE
ABS_TO_HID_MAP
[][
2
]
=
{
{
HID_USAGE_PAGE_GENERIC
,
HID_USAGE_GENERIC_X
},
/*ABS_X*/
{
HID_USAGE_PAGE_GENERIC
,
HID_USAGE_GENERIC_Y
},
/*ABS_Y*/
...
...
@@ -271,15 +201,6 @@ struct wine_input_private {
#define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
static
BYTE
*
add_button_block
(
BYTE
*
report_ptr
,
BYTE
usage_min
,
BYTE
usage_max
)
{
memcpy
(
report_ptr
,
REPORT_BUTTONS
,
sizeof
(
REPORT_BUTTONS
));
report_ptr
[
IDX_BUTTON_MIN_USAGE
]
=
usage_min
;
report_ptr
[
IDX_BUTTON_MAX_USAGE
]
=
usage_max
;
report_ptr
[
IDX_BUTTON_COUNT
]
=
(
usage_max
-
usage_min
)
+
1
;
return
report_ptr
+
sizeof
(
REPORT_BUTTONS
);
}
static
BYTE
*
add_axis_block
(
BYTE
*
report_ptr
,
BYTE
count
,
BYTE
page
,
BYTE
*
usages
,
BOOL
absolute
,
const
struct
wine_input_absinfo
*
absinfo
)
{
int
i
;
...
...
@@ -314,20 +235,6 @@ static BYTE *add_axis_block(BYTE *report_ptr, BYTE count, BYTE page, BYTE *usage
return
report_ptr
;
}
static
BYTE
*
add_padding_block
(
BYTE
*
report_ptr
,
BYTE
bitcount
)
{
memcpy
(
report_ptr
,
REPORT_PADDING
,
sizeof
(
REPORT_PADDING
));
report_ptr
[
IDX_PADDING_BIT_COUNT
]
=
bitcount
;
return
report_ptr
+
sizeof
(
REPORT_PADDING
);
}
static
BYTE
*
add_hatswitch
(
BYTE
*
report_ptr
,
INT
count
)
{
memcpy
(
report_ptr
,
REPORT_HATSWITCH
,
sizeof
(
REPORT_HATSWITCH
));
report_ptr
[
IDX_HATSWITCH_COUNT
]
=
count
;
return
report_ptr
+
sizeof
(
REPORT_HATSWITCH
);
}
static
const
BYTE
*
what_am_I
(
struct
udev_device
*
dev
)
{
static
const
BYTE
Unknown
[
2
]
=
{
HID_USAGE_PAGE_GENERIC
,
0
};
...
...
dlls/winebus.sys/controller.h
0 → 100644
View file @
eda33b4b
/*
* Common controller functions and structures
*
* Copyright 2018 Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Blocks of data for building HID device descriptions */
static
const
BYTE
REPORT_HEADER
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
0x09
,
0x00
,
/* USAGE (??) */
0xa1
,
0x01
,
/* COLLECTION (Application) */
0x09
,
0x01
,
/* USAGE () */
0xa1
,
0x00
,
/* COLLECTION (Physical) */
};
#define IDX_HEADER_PAGE 1
#define IDX_HEADER_USAGE 3
static
const
BYTE
REPORT_BUTTONS
[]
=
{
0x05
,
0x09
,
/* USAGE_PAGE (Button) */
0x19
,
0x01
,
/* USAGE_MINIMUM (Button 1) */
0x29
,
0x03
,
/* USAGE_MAXIMUM (Button 3) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x01
,
/* LOGICAL_MAXIMUM (1) */
0x35
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x45
,
0x01
,
/* LOGICAL_MAXIMUM (1) */
0x95
,
0x03
,
/* REPORT_COUNT (3) */
0x75
,
0x01
,
/* REPORT_SIZE (1) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
};
#define IDX_BUTTON_MIN_USAGE 3
#define IDX_BUTTON_MAX_USAGE 5
#define IDX_BUTTON_COUNT 11
static
const
BYTE
REPORT_PADDING
[]
=
{
0x95
,
0x03
,
/* REPORT_COUNT (3) */
0x75
,
0x01
,
/* REPORT_SIZE (1) */
0x81
,
0x03
,
/* INPUT (Cnst,Var,Abs) */
};
#define IDX_PADDING_BIT_COUNT 1
static
const
BYTE
REPORT_AXIS_HEADER
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
};
#define IDX_AXIS_PAGE 1
static
const
BYTE
REPORT_AXIS_USAGE
[]
=
{
0x09
,
0x30
,
/* USAGE (X) */
};
#define IDX_AXIS_USAGE 1
static
const
BYTE
REPORT_REL_AXIS_TAIL
[]
=
{
0x15
,
0x81
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x7f
,
/* LOGICAL_MAXIMUM (0xffff) */
0x75
,
0x08
,
/* REPORT_SIZE (16) */
0x95
,
0x02
,
/* REPORT_COUNT (2) */
0x81
,
0x06
,
/* INPUT (Data,Var,Rel) */
};
#define IDX_REL_AXIS_COUNT 7
static
const
BYTE
REPORT_HATSWITCH
[]
=
{
0x05
,
0x01
,
/* USAGE_PAGE (Generic Desktop) */
0x09
,
0x39
,
/* USAGE (Hatswitch) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x08
,
/* LOGICAL_MAXIMUM (0x08) */
0x35
,
0x00
,
/* PHYSICAL_MINIMUM (0) */
0x45
,
0x08
,
/* PHYSICAL_MAXIMUM (8) */
0x75
,
0x08
,
/* REPORT_SIZE (8) */
0x95
,
0x01
,
/* REPORT_COUNT (1) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
};
#define IDX_HATSWITCH_COUNT 15
static
const
BYTE
REPORT_TAIL
[]
=
{
0xc0
,
/* END_COLLECTION */
0xc0
/* END_COLLECTION */
};
static
inline
BYTE
*
add_button_block
(
BYTE
*
report_ptr
,
BYTE
usage_min
,
BYTE
usage_max
)
{
memcpy
(
report_ptr
,
REPORT_BUTTONS
,
sizeof
(
REPORT_BUTTONS
));
report_ptr
[
IDX_BUTTON_MIN_USAGE
]
=
usage_min
;
report_ptr
[
IDX_BUTTON_MAX_USAGE
]
=
usage_max
;
report_ptr
[
IDX_BUTTON_COUNT
]
=
(
usage_max
-
usage_min
)
+
1
;
return
report_ptr
+
sizeof
(
REPORT_BUTTONS
);
}
static
inline
BYTE
*
add_padding_block
(
BYTE
*
report_ptr
,
BYTE
bitcount
)
{
memcpy
(
report_ptr
,
REPORT_PADDING
,
sizeof
(
REPORT_PADDING
));
report_ptr
[
IDX_PADDING_BIT_COUNT
]
=
bitcount
;
return
report_ptr
+
sizeof
(
REPORT_PADDING
);
}
static
inline
BYTE
*
add_hatswitch
(
BYTE
*
report_ptr
,
INT
count
)
{
memcpy
(
report_ptr
,
REPORT_HATSWITCH
,
sizeof
(
REPORT_HATSWITCH
));
report_ptr
[
IDX_HATSWITCH_COUNT
]
=
count
;
return
report_ptr
+
sizeof
(
REPORT_HATSWITCH
);
}
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