winebus.sys: Factor out setting HID report values.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c6df23fed3
commit
9cf1e8353c
|
@ -50,12 +50,6 @@
|
|||
#include "wine/unicode.h"
|
||||
#include "hidusage.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define LE_DWORD(x) RtlUlongByteSwap(x)
|
||||
#else
|
||||
# define LE_DWORD(x) (x)
|
||||
#endif
|
||||
|
||||
#include "unix_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
|
||||
|
@ -142,64 +136,23 @@ static struct sdl_device *find_device_from_id(SDL_JoystickID id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void set_button_value(struct sdl_device *impl, int index, int value)
|
||||
static void set_hat_value(struct unix_device *iface, int index, int value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->unix_device.hid_device_state;
|
||||
USHORT offset = state->button_start;
|
||||
int byte_index = offset + index / 8;
|
||||
int bit_index = index % 8;
|
||||
BYTE mask = 1 << bit_index;
|
||||
if (index >= state->button_count) return;
|
||||
if (value) state->report_buf[byte_index] |= mask;
|
||||
else state->report_buf[byte_index] &= ~mask;
|
||||
}
|
||||
|
||||
static void set_axis_value(struct sdl_device *impl, int index, short value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->unix_device.hid_device_state;
|
||||
USHORT offset = state->abs_axis_start;
|
||||
if (index >= state->abs_axis_count) return;
|
||||
offset += index * sizeof(DWORD);
|
||||
*(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
|
||||
}
|
||||
|
||||
static void set_ball_value(struct sdl_device *impl, int index, int value1, int value2)
|
||||
{
|
||||
struct hid_device_state *state = &impl->unix_device.hid_device_state;
|
||||
USHORT offset = state->rel_axis_start;
|
||||
if (index >= state->rel_axis_count) return;
|
||||
offset += index * sizeof(DWORD);
|
||||
*(DWORD *)&state->report_buf[offset] = LE_DWORD(value1);
|
||||
*(DWORD *)&state->report_buf[offset + sizeof(DWORD)] = LE_DWORD(value2);
|
||||
}
|
||||
|
||||
static void set_hat_value(struct sdl_device *impl, int index, int value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->unix_device.hid_device_state;
|
||||
USHORT offset = state->hatswitch_start;
|
||||
unsigned char val;
|
||||
|
||||
if (index >= state->hatswitch_count) return;
|
||||
offset += index;
|
||||
|
||||
LONG x = 0, y = 0;
|
||||
switch (value)
|
||||
{
|
||||
/* 8 1 2
|
||||
* 7 0 3
|
||||
* 6 5 4 */
|
||||
case SDL_HAT_CENTERED: val = 0; break;
|
||||
case SDL_HAT_UP: val = 1; break;
|
||||
case SDL_HAT_RIGHTUP: val = 2; break;
|
||||
case SDL_HAT_RIGHT: val = 3; break;
|
||||
case SDL_HAT_RIGHTDOWN: val = 4; break;
|
||||
case SDL_HAT_DOWN: val = 5; break;
|
||||
case SDL_HAT_LEFTDOWN: val = 6; break;
|
||||
case SDL_HAT_LEFT: val = 7; break;
|
||||
case SDL_HAT_LEFTUP: val = 8; break;
|
||||
default: return;
|
||||
case SDL_HAT_CENTERED: break;
|
||||
case SDL_HAT_UP: y = 1; break;
|
||||
case SDL_HAT_RIGHTUP: y = x = 1; break;
|
||||
case SDL_HAT_RIGHT: x = 1; break;
|
||||
case SDL_HAT_RIGHTDOWN: x = 1; y = -1; break;
|
||||
case SDL_HAT_DOWN: y = -1; break;
|
||||
case SDL_HAT_LEFTDOWN: x = y = -1; break;
|
||||
case SDL_HAT_LEFT: x = -1; break;
|
||||
case SDL_HAT_LEFTUP: x = -1; y = 1; break;
|
||||
}
|
||||
|
||||
state->report_buf[offset] = val;
|
||||
hid_device_set_hatswitch_x(iface, index, x);
|
||||
hid_device_set_hatswitch_y(iface, index, y);
|
||||
}
|
||||
|
||||
static BOOL descriptor_add_haptic(struct sdl_device *impl)
|
||||
|
@ -286,40 +239,13 @@ static NTSTATUS build_joystick_report_descriptor(struct unix_device *iface)
|
|||
|
||||
/* Initialize axis in the report */
|
||||
for (i = 0; i < axis_count; i++)
|
||||
set_axis_value(impl, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i));
|
||||
hid_device_set_abs_axis(iface, i, pSDL_JoystickGetAxis(impl->sdl_joystick, i));
|
||||
for (i = 0; i < hat_count; i++)
|
||||
set_hat_value(impl, i, pSDL_JoystickGetHat(impl->sdl_joystick, i));
|
||||
set_hat_value(iface, i, pSDL_JoystickGetHat(impl->sdl_joystick, i));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static SHORT compose_dpad_value(SDL_GameController *joystick)
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP))
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHTUP;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFTUP;
|
||||
return SDL_HAT_UP;
|
||||
}
|
||||
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN))
|
||||
{
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHTDOWN;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFTDOWN;
|
||||
return SDL_HAT_DOWN;
|
||||
}
|
||||
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
return SDL_HAT_RIGHT;
|
||||
if (pSDL_GameControllerGetButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
return SDL_HAT_LEFT;
|
||||
return SDL_HAT_CENTERED;
|
||||
}
|
||||
|
||||
static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
|
||||
{
|
||||
static const USAGE left_axis_usages[] = {HID_USAGE_GENERIC_X, HID_USAGE_GENERIC_Y};
|
||||
|
@ -358,8 +284,15 @@ static NTSTATUS build_controller_report_descriptor(struct unix_device *iface)
|
|||
|
||||
/* Initialize axis in the report */
|
||||
for (i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++)
|
||||
set_axis_value(impl, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i));
|
||||
set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller));
|
||||
hid_device_set_abs_axis(iface, i, pSDL_GameControllerGetAxis(impl->sdl_controller, i));
|
||||
if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_UP))
|
||||
hid_device_set_hatswitch_y(iface, 0, -1);
|
||||
if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN))
|
||||
hid_device_set_hatswitch_y(iface, 0, +1);
|
||||
if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
|
||||
hid_device_set_hatswitch_x(iface, 0, -1);
|
||||
if (pSDL_GameControllerGetButton(impl->sdl_controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
|
||||
hid_device_set_hatswitch_x(iface, 0, +1);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -471,7 +404,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
|
|||
{
|
||||
SDL_JoyButtonEvent *ie = &event->jbutton;
|
||||
|
||||
set_button_value(impl, ie->button, ie->state);
|
||||
hid_device_set_button(iface, ie->button, ie->state);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
|
@ -479,18 +412,16 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
|
|||
{
|
||||
SDL_JoyAxisEvent *ie = &event->jaxis;
|
||||
|
||||
if (ie->axis < 6)
|
||||
{
|
||||
set_axis_value(impl, ie->axis, ie->value);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
}
|
||||
hid_device_set_abs_axis(iface, ie->axis, ie->value);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
case SDL_JOYBALLMOTION:
|
||||
{
|
||||
SDL_JoyBallEvent *ie = &event->jball;
|
||||
|
||||
set_ball_value(impl, ie->ball, ie->xrel, ie->yrel);
|
||||
hid_device_set_rel_axis(iface, 2 * ie->ball, ie->xrel);
|
||||
hid_device_set_rel_axis(iface, 2 * ie->ball + 1, ie->yrel);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
|
@ -498,7 +429,7 @@ static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *e
|
|||
{
|
||||
SDL_JoyHatEvent *ie = &event->jhat;
|
||||
|
||||
set_hat_value(impl, ie->hat, ie->value);
|
||||
set_hat_value(iface, ie->hat, ie->value);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
|
@ -524,10 +455,16 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
|
|||
switch ((button = ie->button))
|
||||
{
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||
hid_device_set_hatswitch_y(iface, 0, ie->state ? -1 : 0);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||
hid_device_set_hatswitch_y(iface, 0, ie->state ? +1 : 0);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||
hid_device_set_hatswitch_x(iface, 0, ie->state ? -1 : 0);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||
set_hat_value(impl, 0, compose_dpad_value(impl->sdl_controller));
|
||||
hid_device_set_hatswitch_x(iface, 0, ie->state ? +1 : 0);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = 4; break;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = 5; break;
|
||||
|
@ -538,7 +475,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
|
|||
case SDL_CONTROLLER_BUTTON_GUIDE: button = 10; break;
|
||||
}
|
||||
|
||||
set_button_value(impl, button, ie->state);
|
||||
hid_device_set_button(iface, button, ie->state);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
|
@ -546,7 +483,7 @@ static BOOL set_report_from_controller_event(struct sdl_device *impl, SDL_Event
|
|||
{
|
||||
SDL_ControllerAxisEvent *ie = &event->caxis;
|
||||
|
||||
set_axis_value(impl, ie->axis, ie->value);
|
||||
hid_device_set_abs_axis(iface, ie->axis, ie->value);
|
||||
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -126,7 +126,6 @@ struct lnxev_device
|
|||
BYTE rel_map[HID_REL_MAX];
|
||||
BYTE hat_map[8];
|
||||
BYTE button_map[KEY_MAX];
|
||||
int hat_values[8];
|
||||
};
|
||||
|
||||
static inline struct base_device *impl_from_unix_device(struct unix_device *iface)
|
||||
|
@ -325,89 +324,6 @@ static const BYTE* what_am_I(struct udev_device *dev)
|
|||
return Unknown;
|
||||
}
|
||||
|
||||
static void set_button_value(struct lnxev_device *impl, int index, int value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
|
||||
USHORT offset = state->button_start;
|
||||
int byte_index = offset + index / 8;
|
||||
int bit_index = index % 8;
|
||||
BYTE mask = 1 << bit_index;
|
||||
if (index >= state->button_count) return;
|
||||
if (value) state->report_buf[byte_index] |= mask;
|
||||
else state->report_buf[byte_index] &= ~mask;
|
||||
}
|
||||
|
||||
static void set_abs_axis_value(struct lnxev_device *impl, int code, int value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
|
||||
USHORT offset, index;
|
||||
/* check for hatswitches */
|
||||
if (code <= ABS_HAT3Y && code >= ABS_HAT0X)
|
||||
{
|
||||
index = code - ABS_HAT0X;
|
||||
impl->hat_values[index] = value;
|
||||
if ((code - ABS_HAT0X) % 2)
|
||||
index--;
|
||||
/* 8 1 2
|
||||
* 7 0 3
|
||||
* 6 5 4 */
|
||||
if (impl->hat_values[index] == 0)
|
||||
{
|
||||
if (impl->hat_values[index+1] == 0)
|
||||
value = 0;
|
||||
else if (impl->hat_values[index+1] < 0)
|
||||
value = 1;
|
||||
else
|
||||
value = 5;
|
||||
}
|
||||
else if (impl->hat_values[index] > 0)
|
||||
{
|
||||
if (impl->hat_values[index+1] == 0)
|
||||
value = 3;
|
||||
else if (impl->hat_values[index+1] < 0)
|
||||
value = 2;
|
||||
else
|
||||
value = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (impl->hat_values[index+1] == 0)
|
||||
value = 7;
|
||||
else if (impl->hat_values[index+1] < 0)
|
||||
value = 8;
|
||||
else
|
||||
value = 6;
|
||||
}
|
||||
index = impl->hat_map[index];
|
||||
offset = state->hatswitch_start;
|
||||
if (index >= state->hatswitch_count) return;
|
||||
offset += index;
|
||||
state->report_buf[offset] = value;
|
||||
}
|
||||
else if (code < HID_ABS_MAX && ABS_TO_HID_MAP[code][0] != 0)
|
||||
{
|
||||
index = impl->abs_map[code];
|
||||
offset = state->abs_axis_start;
|
||||
if (index >= state->abs_axis_count) return;
|
||||
offset += index * sizeof(DWORD);
|
||||
*(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_rel_axis_value(struct lnxev_device *impl, int code, int value)
|
||||
{
|
||||
struct hid_device_state *state = &impl->base.unix_device.hid_device_state;
|
||||
USHORT offset, index;
|
||||
if (code < HID_REL_MAX && REL_TO_HID_MAP[code][0] != 0)
|
||||
{
|
||||
index = impl->rel_map[code];
|
||||
offset = state->rel_axis_start;
|
||||
if (index >= state->rel_axis_count) return;
|
||||
offset += index * sizeof(DWORD);
|
||||
*(DWORD *)&state->report_buf[offset] = LE_DWORD(value);
|
||||
}
|
||||
}
|
||||
|
||||
static INT count_buttons(int device_fd, BYTE *map)
|
||||
{
|
||||
int i;
|
||||
|
@ -506,12 +422,11 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
}
|
||||
|
||||
hat_count = 0;
|
||||
for (i = ABS_HAT0X; i <=ABS_HAT3X; i+=2)
|
||||
for (i = ABS_HAT0X; i <= ABS_HAT3X; i += 2)
|
||||
{
|
||||
if (!test_bit(absbits, i)) continue;
|
||||
impl->hat_map[i - ABS_HAT0X] = hat_count++;
|
||||
impl->hat_values[i - ABS_HAT0X] = 0;
|
||||
impl->hat_values[i - ABS_HAT0X + 1] = 0;
|
||||
impl->hat_map[i - ABS_HAT0X] = hat_count;
|
||||
impl->hat_map[i - ABS_HAT0X + 1] = hat_count++;
|
||||
}
|
||||
|
||||
if (hat_count && !hid_device_add_hatswitch(iface, hat_count))
|
||||
|
@ -527,8 +442,15 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
|
||||
/* Initialize axis in the report */
|
||||
for (i = 0; i < HID_ABS_MAX; i++)
|
||||
if (test_bit(absbits, i))
|
||||
set_abs_axis_value(impl, i, abs_info[i].value);
|
||||
{
|
||||
if (!test_bit(absbits, i)) continue;
|
||||
if (i < ABS_HAT0X || i > ABS_HAT3Y)
|
||||
hid_device_set_abs_axis(iface, impl->abs_map[i], abs_info[i].value);
|
||||
else if ((i - ABS_HAT0X) % 2)
|
||||
hid_device_set_hatswitch_y(iface, impl->hat_map[i - ABS_HAT0X], abs_info[i].value);
|
||||
else
|
||||
hid_device_set_hatswitch_x(iface, impl->hat_map[i - ABS_HAT0X], abs_info[i].value);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -536,33 +458,39 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
|
|||
static BOOL set_report_from_event(struct unix_device *iface, struct input_event *ie)
|
||||
{
|
||||
struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
|
||||
switch(ie->type)
|
||||
|
||||
switch (ie->type)
|
||||
{
|
||||
#ifdef EV_SYN
|
||||
case EV_SYN:
|
||||
switch (ie->code)
|
||||
{
|
||||
case SYN_REPORT: return hid_device_sync_report(iface);
|
||||
case SYN_DROPPED: hid_device_drop_report(iface); break;
|
||||
}
|
||||
return FALSE;
|
||||
case EV_SYN:
|
||||
switch (ie->code)
|
||||
{
|
||||
case SYN_REPORT: return hid_device_sync_report(iface);
|
||||
case SYN_DROPPED: hid_device_drop_report(iface); break;
|
||||
}
|
||||
return FALSE;
|
||||
#endif
|
||||
#ifdef EV_MSC
|
||||
case EV_MSC:
|
||||
return FALSE;
|
||||
case EV_MSC:
|
||||
return FALSE;
|
||||
#endif
|
||||
case EV_KEY:
|
||||
set_button_value(impl, impl->button_map[ie->code], ie->value);
|
||||
return FALSE;
|
||||
case EV_ABS:
|
||||
set_abs_axis_value(impl, ie->code, ie->value);
|
||||
return FALSE;
|
||||
case EV_REL:
|
||||
set_rel_axis_value(impl, ie->code, ie->value);
|
||||
return FALSE;
|
||||
default:
|
||||
ERR("TODO: Process Report (%i, %i)\n",ie->type, ie->code);
|
||||
return FALSE;
|
||||
case EV_KEY:
|
||||
hid_device_set_button(iface, impl->button_map[ie->code], ie->value);
|
||||
return FALSE;
|
||||
case EV_ABS:
|
||||
if (ie->code < ABS_HAT0X || ie->code > ABS_HAT3Y)
|
||||
hid_device_set_abs_axis(iface, impl->abs_map[ie->code], ie->value);
|
||||
else if ((ie->code - ABS_HAT0X) % 2)
|
||||
hid_device_set_hatswitch_y(iface, impl->hat_map[ie->code - ABS_HAT0X], ie->value);
|
||||
else
|
||||
hid_device_set_hatswitch_x(iface, impl->hat_map[ie->code - ABS_HAT0X], ie->value);
|
||||
return FALSE;
|
||||
case EV_REL:
|
||||
hid_device_set_rel_axis(iface, impl->rel_map[ie->code], ie->value);
|
||||
return FALSE;
|
||||
default:
|
||||
ERR("TODO: Process Report (%i, %i)\n",ie->type, ie->code);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -791,8 +719,6 @@ static void lnxev_device_read_report(struct unix_device *iface)
|
|||
struct input_event ie;
|
||||
int size;
|
||||
|
||||
if (!state->report_buf || !state->report_len) return;
|
||||
|
||||
size = read(impl->base.device_fd, &ie, sizeof(ie));
|
||||
if (size == -1)
|
||||
TRACE_(hid_report)("Read failed. Likely an unplugged device\n");
|
||||
|
|
|
@ -369,6 +369,93 @@ void *hid_device_create(const struct hid_device_vtbl *vtbl, SIZE_T size)
|
|||
return impl;
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define LE_ULONG(x) RtlUlongByteSwap((ULONG)(x))
|
||||
#else
|
||||
# define LE_ULONG(x) ((ULONG)(x))
|
||||
#endif
|
||||
|
||||
BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->abs_axis_start + index * 4;
|
||||
if (index > state->abs_axis_count) return FALSE;
|
||||
*(ULONG *)(state->report_buf + offset) = LE_ULONG(value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->rel_axis_start + index * 4;
|
||||
if (index > state->rel_axis_count) return FALSE;
|
||||
*(ULONG *)(state->report_buf + offset) = LE_ULONG(value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->button_start + (index / 8);
|
||||
BYTE mask = (1 << (index % 8));
|
||||
if (index > state->button_count) return FALSE;
|
||||
if (is_set) state->report_buf[offset] |= mask;
|
||||
else state->report_buf[offset] &= ~mask;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* hatswitch x / y vs value:
|
||||
* -1 x +1
|
||||
* +-------->
|
||||
* -1 | 8 1 2
|
||||
* y | 7 0 3
|
||||
* +1 | 6 5 4
|
||||
* v
|
||||
*/
|
||||
static void hatswitch_decompose(BYTE value, LONG *x, LONG *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
if (value == 8 || value == 1 || value == 2) *y = -1;
|
||||
if (value == 6 || value == 5 || value == 4) *y = +1;
|
||||
if (value == 8 || value == 7 || value == 6) *x = -1;
|
||||
if (value == 2 || value == 3 || value == 4) *x = +1;
|
||||
}
|
||||
|
||||
static void hatswitch_compose(LONG x, LONG y, BYTE *value)
|
||||
{
|
||||
if (x == 0 && y == 0) *value = 0;
|
||||
else if (x == 0 && y < 0) *value = 1;
|
||||
else if (x > 0 && y < 0) *value = 2;
|
||||
else if (x > 0 && y == 0) *value = 3;
|
||||
else if (x > 0 && y > 0) *value = 4;
|
||||
else if (x == 0 && y > 0) *value = 5;
|
||||
else if (x < 0 && y > 0) *value = 6;
|
||||
else if (x < 0 && y == 0) *value = 7;
|
||||
else if (x < 0 && y < 0) *value = 8;
|
||||
}
|
||||
|
||||
BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->hatswitch_start + index;
|
||||
LONG x, y;
|
||||
if (index > state->hatswitch_count) return FALSE;
|
||||
hatswitch_decompose(state->report_buf[offset], &x, &y);
|
||||
hatswitch_compose(new_x, y, &state->report_buf[offset]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y)
|
||||
{
|
||||
struct hid_device_state *state = &iface->hid_device_state;
|
||||
ULONG offset = state->hatswitch_start + index;
|
||||
LONG x, y;
|
||||
if (index > state->hatswitch_count) return FALSE;
|
||||
hatswitch_decompose(state->report_buf[offset], &x, &y);
|
||||
hatswitch_compose(x, new_y, &state->report_buf[offset]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL hid_device_sync_report(struct unix_device *iface)
|
||||
{
|
||||
BOOL dropped;
|
||||
|
|
|
@ -119,6 +119,12 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
|
|||
|
||||
extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_button(struct unix_device *iface, ULONG index, BOOL is_set) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_hatswitch_x(struct unix_device *iface, ULONG index, LONG new_x) DECLSPEC_HIDDEN;
|
||||
extern BOOL hid_device_set_hatswitch_y(struct unix_device *iface, ULONG index, LONG new_y) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL hid_device_sync_report(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
extern void hid_device_drop_report(struct unix_device *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue