added mouse support
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9062 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f4f986a34d
commit
dbb3afbf3a
@ -123,14 +123,13 @@ remove_device (my_device_info *my_dev)
|
||||
}
|
||||
|
||||
|
||||
/* gameport driver cookie (per open) */
|
||||
/* driver cookie (per open) */
|
||||
|
||||
typedef struct driver_cookie
|
||||
{
|
||||
struct driver_cookie *next;
|
||||
|
||||
my_device_info *my_dev;
|
||||
bool enhanced;
|
||||
|
||||
} driver_cookie;
|
||||
|
||||
@ -459,13 +458,72 @@ set_leds(my_device_info *my_dev, uint8* data)
|
||||
|
||||
st = usb->send_request (my_dev->dev,
|
||||
USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_CLASS,
|
||||
0x09,
|
||||
USB_REQUEST_HID_SET_REPORT,
|
||||
0x200 | report_id, my_dev->ifno, actual,
|
||||
&leds, actual, &actual);
|
||||
DPRINTF_INFO ((MY_ID "set_leds: leds=0x%02x, st=%d, len=%d\n",
|
||||
leds, (int) st, (int)actual));
|
||||
}
|
||||
|
||||
#define MAX_BUTTONS 16
|
||||
|
||||
static int
|
||||
sign_extend(int value, int size)
|
||||
{
|
||||
if (value & (1 << (size - 1)))
|
||||
return value | (UINT_MAX << size);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
interpret_ms_buffer(my_device_info *my_dev)
|
||||
{
|
||||
mouse_movement info;
|
||||
uint8 *report = (uint8*)my_dev->buffer;
|
||||
uint32 i;
|
||||
|
||||
info.buttons = 0;
|
||||
info.clicks = 0;
|
||||
for (i = 0; i < my_dev->num_insns; i++) {
|
||||
const report_insn *insn = &my_dev->insns [i];
|
||||
int32 value =
|
||||
(((report [insn->byte_idx + 1] << 8) |
|
||||
report [insn->byte_idx]) >> insn->bit_pos)
|
||||
& ((1 << insn->num_bits) - 1);
|
||||
|
||||
if (insn->usage_page == USAGE_PAGE_BUTTON) {
|
||||
if ((insn->usage_id - 1) < MAX_BUTTONS) {
|
||||
info.buttons |=
|
||||
(value & 1) << (insn->usage_id - 1);
|
||||
info.clicks = 1;
|
||||
}
|
||||
} else if (insn->usage_page == USAGE_PAGE_GENERIC_DESKTOP) {
|
||||
if (insn->is_phy_signed) {
|
||||
value = sign_extend (value, insn->num_bits);
|
||||
}
|
||||
|
||||
switch (insn->usage_id) {
|
||||
case USAGE_ID_X:
|
||||
info.xdelta = value;
|
||||
break;
|
||||
case USAGE_ID_Y:
|
||||
info.ydelta = -value;
|
||||
break;
|
||||
case USAGE_ID_WHEEL:
|
||||
info.wheel_delta = -value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info.modifiers = 0;
|
||||
info.timestamp = my_dev->timestamp;
|
||||
|
||||
cbuf_putn(my_dev->cbuf, &info, sizeof(info));
|
||||
release_sem_etc(my_dev->sem_cb, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
/*
|
||||
callback: got a report, issue next request
|
||||
@ -509,10 +567,11 @@ usb_callback(void *cookie, uint32 status,
|
||||
#endif
|
||||
my_dev->timestamp = system_time ();
|
||||
|
||||
if (my_dev->is_keyboard)
|
||||
if (my_dev->is_keyboard) {
|
||||
interpret_kb_buffer(my_dev);
|
||||
|
||||
memcpy(my_dev->last_buffer, my_dev->buffer, my_dev->total_report_size);
|
||||
} else
|
||||
interpret_ms_buffer(my_dev);
|
||||
|
||||
release_sem (my_dev->sem_lock);
|
||||
}
|
||||
@ -622,7 +681,6 @@ hid_device_added(const usb_device *dev, void **cookie)
|
||||
close (fd);
|
||||
}
|
||||
|
||||
/* XXX check application type */
|
||||
/* Generic Desktop : Keyboard or Mouse */
|
||||
|
||||
if (memcmp (rep_desc, "\x05\x01\x09\x06", 4) != 0 &&
|
||||
@ -669,10 +727,10 @@ hid_device_added(const usb_device *dev, void **cookie)
|
||||
|
||||
/* count axes, hats and buttons */
|
||||
|
||||
count_controls (my_dev->insns, my_dev->num_insns,
|
||||
/*count_controls (my_dev->insns, my_dev->num_insns,
|
||||
&my_dev->num_axes, &my_dev->num_hats, &my_dev->num_buttons);
|
||||
DPRINTF_INFO ((MY_ID "%d axes, %d hats, %d buttons\n",
|
||||
my_dev->num_axes, my_dev->num_hats, my_dev->num_buttons));
|
||||
my_dev->num_axes, my_dev->num_hats, my_dev->num_buttons));*/
|
||||
|
||||
/* get initial state */
|
||||
|
||||
@ -762,7 +820,6 @@ hid_device_open(const char *name, uint32 flags,
|
||||
return B_NO_MEMORY;
|
||||
|
||||
acquire_sem (my_dev->sem_lock);
|
||||
cookie->enhanced = false;
|
||||
cookie->my_dev = my_dev;
|
||||
cookie->next = my_dev->open_fds;
|
||||
my_dev->open_fds = cookie;
|
||||
@ -817,9 +874,9 @@ hid_device_control(driver_cookie *cookie, uint32 op,
|
||||
if (!my_dev->active)
|
||||
return B_ERROR; /* already unplugged */
|
||||
|
||||
if (my_dev->is_keyboard) {
|
||||
if (my_dev->is_keyboard)
|
||||
switch (op) {
|
||||
case 0x270f:
|
||||
case KB_READ:
|
||||
err = acquire_sem_etc(my_dev->sem_cb, 1, B_CAN_INTERRUPT, 0LL);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
@ -827,18 +884,31 @@ hid_device_control(driver_cookie *cookie, uint32 op,
|
||||
return err;
|
||||
break;
|
||||
|
||||
case 0x2711:
|
||||
case KB_SET_LEDS:
|
||||
set_leds(my_dev, (uint8 *)arg);
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
switch (op) {
|
||||
case MS_READ:
|
||||
err = acquire_sem_etc(my_dev->sem_cb, 1, B_CAN_INTERRUPT, 0LL);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
cbuf_getn(my_dev->cbuf, arg, sizeof(mouse_movement));
|
||||
return err;
|
||||
break;
|
||||
case MS_NUM_EVENTS:
|
||||
{
|
||||
int32 count;
|
||||
get_sem_count(my_dev->sem_cb, &count);
|
||||
return count;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* not implemented */
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -339,79 +339,3 @@ end:
|
||||
*first_report_id = item_state.report_id;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
designed for game controllers
|
||||
*/
|
||||
|
||||
int
|
||||
count_controls(report_insn *insns, size_t num_insns,
|
||||
int *num_axes, int *num_hats, int *num_buttons)
|
||||
{
|
||||
unsigned int insn_idx;
|
||||
int hats = 0, buttons = 0,
|
||||
axes = 2; /* X and Y axes are reserved */
|
||||
|
||||
if (insns == NULL || num_insns <= 0)
|
||||
return FAILURE;
|
||||
|
||||
for (insn_idx = 0; insn_idx < num_insns; insn_idx++) {
|
||||
report_insn *insn = &insns [insn_idx];
|
||||
insn->ctrl_type = TYPE_NONE;
|
||||
switch (insn->usage_page) {
|
||||
case USAGE_PAGE_GENERIC_DESKTOP:
|
||||
switch (insn->usage_id) {
|
||||
case USAGE_ID_X:
|
||||
insn->ctrl_type = TYPE_AXIS_X;
|
||||
break;
|
||||
|
||||
case USAGE_ID_Y:
|
||||
insn->ctrl_type = TYPE_AXIS_Y;
|
||||
break;
|
||||
|
||||
case USAGE_ID_Z:
|
||||
case USAGE_ID_RX:
|
||||
case USAGE_ID_RY:
|
||||
case USAGE_ID_RZ:
|
||||
case USAGE_ID_SLIDER:
|
||||
case USAGE_ID_DIAL:
|
||||
case USAGE_ID_WHEEL:
|
||||
axes++;
|
||||
insn->ctrl_type = TYPE_AXIS;
|
||||
break;
|
||||
|
||||
case USAGE_ID_HAT_SWITCH:
|
||||
hats++;
|
||||
insn->ctrl_type = TYPE_HAT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USAGE_PAGE_SIMULATION:
|
||||
switch (insn->usage_id) {
|
||||
case USAGE_ID_RUDDER:
|
||||
case USAGE_ID_THROTTLE:
|
||||
axes++;
|
||||
insn->ctrl_type = TYPE_AXIS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USAGE_PAGE_BUTTON:
|
||||
if (insn->num_bits == 1) {
|
||||
buttons++;
|
||||
insn->ctrl_type = TYPE_BUTTON;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_axes != NULL)
|
||||
*num_axes = axes;
|
||||
if (num_hats != NULL)
|
||||
*num_hats = hats;
|
||||
if (num_buttons != NULL)
|
||||
*num_buttons = buttons;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -130,12 +130,6 @@ typedef struct
|
||||
report "instruction"
|
||||
*/
|
||||
|
||||
/* control types for game controllers */
|
||||
enum
|
||||
{
|
||||
TYPE_NONE, TYPE_HAT, TYPE_AXIS, TYPE_AXIS_X, TYPE_AXIS_Y, TYPE_BUTTON
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int usage_page, usage_id;
|
||||
@ -168,10 +162,3 @@ int parse_report_descriptor
|
||||
size_t *num_insns,
|
||||
size_t *total_report_size,
|
||||
int *first_report_id);
|
||||
|
||||
int count_controls
|
||||
(report_insn *insns,
|
||||
size_t num_insns,
|
||||
int *num_axes,
|
||||
int *num_hats,
|
||||
int *num_buttons);
|
||||
|
Loading…
Reference in New Issue
Block a user