added mouse support
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9062 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -123,15 +123,14 @@ remove_device (my_device_info *my_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* gameport driver cookie (per open) */
|
/* driver cookie (per open) */
|
||||||
|
|
||||||
typedef struct driver_cookie
|
typedef struct driver_cookie
|
||||||
{
|
{
|
||||||
struct driver_cookie *next;
|
struct driver_cookie *next;
|
||||||
|
|
||||||
my_device_info *my_dev;
|
my_device_info *my_dev;
|
||||||
bool enhanced;
|
|
||||||
|
|
||||||
} driver_cookie;
|
} driver_cookie;
|
||||||
|
|
||||||
/* NB global variables are valid only while driver is loaded */
|
/* NB global variables are valid only while driver is loaded */
|
||||||
@@ -459,13 +458,72 @@ set_leds(my_device_info *my_dev, uint8* data)
|
|||||||
|
|
||||||
st = usb->send_request (my_dev->dev,
|
st = usb->send_request (my_dev->dev,
|
||||||
USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_CLASS,
|
USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_CLASS,
|
||||||
0x09,
|
USB_REQUEST_HID_SET_REPORT,
|
||||||
0x200 | report_id, my_dev->ifno, actual,
|
0x200 | report_id, my_dev->ifno, actual,
|
||||||
&leds, actual, &actual);
|
&leds, actual, &actual);
|
||||||
DPRINTF_INFO ((MY_ID "set_leds: leds=0x%02x, st=%d, len=%d\n",
|
DPRINTF_INFO ((MY_ID "set_leds: leds=0x%02x, st=%d, len=%d\n",
|
||||||
leds, (int) st, (int)actual));
|
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
|
callback: got a report, issue next request
|
||||||
@@ -509,10 +567,11 @@ usb_callback(void *cookie, uint32 status,
|
|||||||
#endif
|
#endif
|
||||||
my_dev->timestamp = system_time ();
|
my_dev->timestamp = system_time ();
|
||||||
|
|
||||||
if (my_dev->is_keyboard)
|
if (my_dev->is_keyboard) {
|
||||||
interpret_kb_buffer(my_dev);
|
interpret_kb_buffer(my_dev);
|
||||||
|
memcpy(my_dev->last_buffer, my_dev->buffer, my_dev->total_report_size);
|
||||||
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);
|
release_sem (my_dev->sem_lock);
|
||||||
}
|
}
|
||||||
@@ -622,7 +681,6 @@ hid_device_added(const usb_device *dev, void **cookie)
|
|||||||
close (fd);
|
close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX check application type */
|
|
||||||
/* Generic Desktop : Keyboard or Mouse */
|
/* Generic Desktop : Keyboard or Mouse */
|
||||||
|
|
||||||
if (memcmp (rep_desc, "\x05\x01\x09\x06", 4) != 0 &&
|
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 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);
|
&my_dev->num_axes, &my_dev->num_hats, &my_dev->num_buttons);
|
||||||
DPRINTF_INFO ((MY_ID "%d axes, %d hats, %d buttons\n",
|
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 */
|
/* get initial state */
|
||||||
|
|
||||||
@@ -762,7 +820,6 @@ hid_device_open(const char *name, uint32 flags,
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
acquire_sem (my_dev->sem_lock);
|
acquire_sem (my_dev->sem_lock);
|
||||||
cookie->enhanced = false;
|
|
||||||
cookie->my_dev = my_dev;
|
cookie->my_dev = my_dev;
|
||||||
cookie->next = my_dev->open_fds;
|
cookie->next = my_dev->open_fds;
|
||||||
my_dev->open_fds = cookie;
|
my_dev->open_fds = cookie;
|
||||||
@@ -817,9 +874,9 @@ hid_device_control(driver_cookie *cookie, uint32 op,
|
|||||||
if (!my_dev->active)
|
if (!my_dev->active)
|
||||||
return B_ERROR; /* already unplugged */
|
return B_ERROR; /* already unplugged */
|
||||||
|
|
||||||
if (my_dev->is_keyboard) {
|
if (my_dev->is_keyboard)
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 0x270f:
|
case KB_READ:
|
||||||
err = acquire_sem_etc(my_dev->sem_cb, 1, B_CAN_INTERRUPT, 0LL);
|
err = acquire_sem_etc(my_dev->sem_cb, 1, B_CAN_INTERRUPT, 0LL);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
@@ -827,18 +884,31 @@ hid_device_control(driver_cookie *cookie, uint32 op,
|
|||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2711:
|
case KB_SET_LEDS:
|
||||||
set_leds(my_dev, (uint8 *)arg);
|
set_leds(my_dev, (uint8 *)arg);
|
||||||
break;
|
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:
|
default:
|
||||||
/* not implemented */
|
/* not implemented */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -339,79 +339,3 @@ end:
|
|||||||
*first_report_id = item_state.report_id;
|
*first_report_id = item_state.report_id;
|
||||||
return SUCCESS;
|
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"
|
report "instruction"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* control types for game controllers */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
TYPE_NONE, TYPE_HAT, TYPE_AXIS, TYPE_AXIS_X, TYPE_AXIS_Y, TYPE_BUTTON
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned int usage_page, usage_id;
|
unsigned int usage_page, usage_id;
|
||||||
@@ -168,10 +162,3 @@ int parse_report_descriptor
|
|||||||
size_t *num_insns,
|
size_t *num_insns,
|
||||||
size_t *total_report_size,
|
size_t *total_report_size,
|
||||||
int *first_report_id);
|
int *first_report_id);
|
||||||
|
|
||||||
int count_controls
|
|
||||||
(report_insn *insns,
|
|
||||||
size_t num_insns,
|
|
||||||
int *num_axes,
|
|
||||||
int *num_hats,
|
|
||||||
int *num_buttons);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user