Changeset View
Standalone View
sys/dev/usb/input/ums.c
Show First 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | struct ums_info { | ||||
uint32_t sc_flags; | uint32_t sc_flags; | ||||
#define UMS_FLAG_X_AXIS 0x0001 | #define UMS_FLAG_X_AXIS 0x0001 | ||||
#define UMS_FLAG_Y_AXIS 0x0002 | #define UMS_FLAG_Y_AXIS 0x0002 | ||||
#define UMS_FLAG_Z_AXIS 0x0004 | #define UMS_FLAG_Z_AXIS 0x0004 | ||||
#define UMS_FLAG_T_AXIS 0x0008 | #define UMS_FLAG_T_AXIS 0x0008 | ||||
#define UMS_FLAG_SBU 0x0010 /* spurious button up events */ | #define UMS_FLAG_SBU 0x0010 /* spurious button up events */ | ||||
#define UMS_FLAG_REVZ 0x0020 /* Z-axis is reversed */ | #define UMS_FLAG_REVZ 0x0020 /* Z-axis is reversed */ | ||||
#define UMS_FLAG_W_AXIS 0x0040 | #define UMS_FLAG_W_AXIS 0x0040 | ||||
#define UMS_FLAG_X_ABS 0x0100 | |||||
#define UMS_FLAG_Y_ABS 0x0200 | |||||
#define UMS_FLAG_Z_ABS 0x0400 | |||||
uint8_t sc_iid_w; | uint8_t sc_iid_w; | ||||
uint8_t sc_iid_x; | uint8_t sc_iid_x; | ||||
uint8_t sc_iid_y; | uint8_t sc_iid_y; | ||||
uint8_t sc_iid_z; | uint8_t sc_iid_z; | ||||
uint8_t sc_iid_t; | uint8_t sc_iid_t; | ||||
uint8_t sc_iid_btn[UMS_BUTTON_MAX]; | uint8_t sc_iid_btn[UMS_BUTTON_MAX]; | ||||
uint8_t sc_buttons; | uint8_t sc_buttons; | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) | ||||
struct usb_page_cache *pc; | struct usb_page_cache *pc; | ||||
uint8_t *buf = sc->sc_temp; | uint8_t *buf = sc->sc_temp; | ||||
int32_t buttons = 0; | int32_t buttons = 0; | ||||
int32_t buttons_found = 0; | int32_t buttons_found = 0; | ||||
#ifdef EVDEV_SUPPORT | #ifdef EVDEV_SUPPORT | ||||
int32_t buttons_reported = 0; | int32_t buttons_reported = 0; | ||||
#endif | #endif | ||||
int32_t dw = 0; | int32_t dw = 0; | ||||
int32_t dx = 0; | int32_t dx = sc->sc_status.dx; | ||||
int32_t dy = 0; | int32_t dy = sc->sc_status.dy; | ||||
int32_t dz = 0; | int32_t dz = sc->sc_status.dz; | ||||
int32_t dt = 0; | int32_t dt = 0; | ||||
uint8_t i; | uint8_t i; | ||||
uint8_t id; | uint8_t id; | ||||
int len; | int len; | ||||
int changed = 0; | |||||
uint32_t abs_flags = 0; | |||||
usbd_xfer_status(xfer, &len, NULL, NULL, NULL); | usbd_xfer_status(xfer, &len, NULL, NULL, NULL); | ||||
switch (USB_GET_STATE(xfer)) { | switch (USB_GET_STATE(xfer)) { | ||||
case USB_ST_TRANSFERRED: | case USB_ST_TRANSFERRED: | ||||
DPRINTFN(6, "sc=%p actlen=%d\n", sc, len); | DPRINTFN(6, "sc=%p actlen=%d\n", sc, len); | ||||
if (len > (int)sizeof(sc->sc_temp)) { | if (len > (int)sizeof(sc->sc_temp)) { | ||||
Show All 25 Lines | if (sc->sc_iid) { | ||||
if (sc->sc_info[0].sc_flags & UMS_FLAG_SBU) { | if (sc->sc_info[0].sc_flags & UMS_FLAG_SBU) { | ||||
if ((*buf == 0x14) || (*buf == 0x15)) { | if ((*buf == 0x14) || (*buf == 0x15)) { | ||||
goto tr_setup; | goto tr_setup; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
repeat: | repeat: | ||||
abs_flags |= info->sc_flags & (UMS_FLAG_X_ABS | UMS_FLAG_Y_ABS | UMS_FLAG_Z_ABS); | |||||
if ((info->sc_flags & UMS_FLAG_W_AXIS) && | if ((info->sc_flags & UMS_FLAG_W_AXIS) && | ||||
(id == info->sc_iid_w)) | (id == info->sc_iid_w)) { | ||||
dw += hid_get_data(buf, len, &info->sc_loc_w); | dw += hid_get_data(buf, len, &info->sc_loc_w); | ||||
changed += dw != 0; | |||||
} | |||||
if ((info->sc_flags & UMS_FLAG_X_AXIS) && | if ((info->sc_flags & UMS_FLAG_X_AXIS) && | ||||
(id == info->sc_iid_x)) | (id == info->sc_iid_x)) { | ||||
if (info->sc_flags & UMS_FLAG_X_ABS) | |||||
dx = hid_get_data(buf, len, &info->sc_loc_x); | |||||
else | |||||
dx += hid_get_data(buf, len, &info->sc_loc_x); | dx += hid_get_data(buf, len, &info->sc_loc_x); | ||||
changed += dx != sc->sc_status.dx; | |||||
} | |||||
if ((info->sc_flags & UMS_FLAG_Y_AXIS) && | if ((info->sc_flags & UMS_FLAG_Y_AXIS) && | ||||
(id == info->sc_iid_y)) | (id == info->sc_iid_y)) { | ||||
if (info->sc_flags & UMS_FLAG_Y_ABS) | |||||
dy = -hid_get_data(buf, len, &info->sc_loc_y); | dy = -hid_get_data(buf, len, &info->sc_loc_y); | ||||
else | |||||
dy -= hid_get_data(buf, len, &info->sc_loc_y); | |||||
changed += dy != sc->sc_status.dy; | |||||
} | |||||
if ((info->sc_flags & UMS_FLAG_Z_AXIS) && | if ((info->sc_flags & UMS_FLAG_Z_AXIS) && | ||||
(id == info->sc_iid_z)) { | (id == info->sc_iid_z)) { | ||||
int32_t temp; | int32_t temp; | ||||
temp = hid_get_data(buf, len, &info->sc_loc_z); | temp = hid_get_data(buf, len, &info->sc_loc_z); | ||||
if (info->sc_flags & UMS_FLAG_REVZ) | if (info->sc_flags & UMS_FLAG_REVZ) | ||||
temp = -temp; | temp = -temp; | ||||
if (info->sc_flags & UMS_FLAG_Z_ABS) | |||||
dz = -temp; | |||||
else | |||||
dz -= temp; | dz -= temp; | ||||
changed += dz != sc->sc_status.dz; | |||||
} | } | ||||
if ((info->sc_flags & UMS_FLAG_T_AXIS) && | if ((info->sc_flags & UMS_FLAG_T_AXIS) && | ||||
(id == info->sc_iid_t)) { | (id == info->sc_iid_t)) { | ||||
dt -= hid_get_data(buf, len, &info->sc_loc_t); | dt -= hid_get_data(buf, len, &info->sc_loc_t); | ||||
/* T-axis is translated into button presses */ | /* T-axis is translated into button presses */ | ||||
buttons_found |= (1UL << 5) | (1UL << 6); | buttons_found |= (1UL << 5) | (1UL << 6); | ||||
changed += dt != 0; | |||||
} | } | ||||
for (i = 0; i < info->sc_buttons; i++) { | for (i = 0; i < info->sc_buttons; i++) { | ||||
uint32_t mask; | uint32_t mask; | ||||
mask = 1UL << UMS_BUT(i); | mask = 1UL << UMS_BUT(i); | ||||
/* check for correct button ID */ | /* check for correct button ID */ | ||||
if (id != info->sc_iid_btn[i]) | if (id != info->sc_iid_btn[i]) | ||||
continue; | continue; | ||||
/* check for button pressed */ | /* check for button pressed */ | ||||
if (hid_get_data(buf, len, &info->sc_loc_btn[i])) | if (hid_get_data(buf, len, &info->sc_loc_btn[i])) | ||||
buttons |= mask; | buttons |= mask; | ||||
/* register button mask */ | /* register button mask */ | ||||
buttons_found |= mask; | buttons_found |= mask; | ||||
} | } | ||||
if (++info != &sc->sc_info[UMS_INFO_MAX]) | if (++info != &sc->sc_info[UMS_INFO_MAX]) | ||||
goto repeat; | goto repeat; | ||||
#ifdef EVDEV_SUPPORT | #ifdef EVDEV_SUPPORT | ||||
buttons_reported = buttons; | buttons_reported = buttons; | ||||
#endif | #endif | ||||
/* keep old button value(s) for non-detected buttons */ | /* keep old button value(s) for non-detected buttons */ | ||||
buttons |= sc->sc_status.button & ~buttons_found; | buttons |= sc->sc_status.button & ~buttons_found; | ||||
changed += buttons != sc->sc_status.button; | |||||
if (dx || dy || dz || dt || dw || | if (changed) { | ||||
(buttons != sc->sc_status.button)) { | int32_t old_dx = sc->sc_status.dx; | ||||
int32_t old_dy = sc->sc_status.dy; | |||||
int32_t old_dz = sc->sc_status.dz; | |||||
DPRINTFN(6, "x:%d y:%d z:%d t:%d w:%d buttons:0x%08x\n", | DPRINTFN(6, "x:%d y:%d z:%d t:%d w:%d buttons:0x%08x\n", | ||||
dx, dy, dz, dt, dw, buttons); | dx, dy, dz, dt, dw, buttons); | ||||
/* translate T-axis into button presses until further */ | /* translate T-axis into button presses until further */ | ||||
if (dt > 0) { | if (dt > 0) { | ||||
ums_put_queue(sc, 0, 0, 0, 0, buttons); | ums_put_queue(sc, 0, 0, 0, 0, buttons); | ||||
buttons |= 1UL << 5; | buttons |= 1UL << 5; | ||||
} else if (dt < 0) { | } else if (dt < 0) { | ||||
ums_put_queue(sc, 0, 0, 0, 0, buttons); | ums_put_queue(sc, 0, 0, 0, 0, buttons); | ||||
buttons |= 1UL << 6; | buttons |= 1UL << 6; | ||||
} | } | ||||
sc->sc_status.button = buttons; | sc->sc_status.button = buttons; | ||||
sc->sc_status.dx += dx; | sc->sc_status.dx = dx; | ||||
sc->sc_status.dy += dy; | sc->sc_status.dy = dy; | ||||
sc->sc_status.dz += dz; | sc->sc_status.dz = dz; | ||||
/* | /* | ||||
* sc->sc_status.dt += dt; | * sc->sc_status.dt += dt; | ||||
* no way to export this yet | * no way to export this yet | ||||
*/ | */ | ||||
if (!(abs_flags & UMS_FLAG_X_ABS)) | |||||
dx -= old_dx; | |||||
if (!(abs_flags & UMS_FLAG_Y_ABS)) | |||||
dy -= old_dy; | |||||
if (!(abs_flags & UMS_FLAG_Z_ABS)) | |||||
dz -= old_dz; | |||||
/* | /* | ||||
* The Qtronix keyboard has a built in PS/2 | * The Qtronix keyboard has a built in PS/2 | ||||
* port for a mouse. The firmware once in a | * port for a mouse. The firmware once in a | ||||
* while posts a spurious button up | * while posts a spurious button up | ||||
* event. This event we ignore by doing a | * event. This event we ignore by doing a | ||||
* timeout for 50 msecs. If we receive | * timeout for 50 msecs. If we receive | ||||
* dx=dy=dz=buttons=0 before we add the event | * dx=dy=dz=buttons=0 before we add the event | ||||
* to the queue. In any other case we delete | * to the queue. In any other case we delete | ||||
* the timeout event. | * the timeout event. | ||||
*/ | */ | ||||
if ((sc->sc_info[0].sc_flags & UMS_FLAG_SBU) && | if ((sc->sc_info[0].sc_flags & UMS_FLAG_SBU) && | ||||
(dx == 0) && (dy == 0) && (dz == 0) && (dt == 0) && | (dx == 0) && (dy == 0) && (dz == 0) && (dt == 0) && | ||||
(dw == 0) && (buttons == 0)) { | (dw == 0) && (buttons == 0)) { | ||||
usb_callout_reset(&sc->sc_callout, hz / 20, | usb_callout_reset(&sc->sc_callout, hz / 20, | ||||
&ums_put_queue_timeout, sc); | &ums_put_queue_timeout, sc); | ||||
} else { | } else { | ||||
usb_callout_stop(&sc->sc_callout); | usb_callout_stop(&sc->sc_callout); | ||||
/* sysmouse does not support absolute positioning */ | |||||
if (!(abs_flags & (UMS_FLAG_X_ABS | UMS_FLAG_Y_ABS | UMS_FLAG_Z_ABS))) | |||||
ums_put_queue(sc, dx, dy, dz, dt, buttons); | ums_put_queue(sc, dx, dy, dz, dt, buttons); | ||||
#ifdef EVDEV_SUPPORT | #ifdef EVDEV_SUPPORT | ||||
ums_evdev_push(sc, dx, dy, dz, dt, | ums_evdev_push(sc, dx, dy, dz, dt, | ||||
buttons_reported); | buttons_reported); | ||||
#endif | #endif | ||||
} | } | ||||
} | } | ||||
case USB_ST_SETUP: | case USB_ST_SETUP: | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | ums_hid_parse(struct ums_softc *sc, device_t dev, const uint8_t *buf, | ||||
struct ums_info *info = &sc->sc_info[index]; | struct ums_info *info = &sc->sc_info[index]; | ||||
uint32_t flags; | uint32_t flags; | ||||
uint8_t i; | uint8_t i; | ||||
uint8_t j; | uint8_t j; | ||||
if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), | if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), | ||||
hid_input, index, &info->sc_loc_x, &flags, &info->sc_iid_x)) { | hid_input, index, &info->sc_loc_x, &flags, &info->sc_iid_x)) { | ||||
if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | switch (flags & MOUSE_FLAGS_MASK) { | ||||
case 0: | |||||
info->sc_flags |= UMS_FLAG_X_ABS; | |||||
case MOUSE_FLAGS: | |||||
info->sc_flags |= UMS_FLAG_X_AXIS; | info->sc_flags |= UMS_FLAG_X_AXIS; | ||||
} | } | ||||
} | } | ||||
if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), | if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), | ||||
hid_input, index, &info->sc_loc_y, &flags, &info->sc_iid_y)) { | hid_input, index, &info->sc_loc_y, &flags, &info->sc_iid_y)) { | ||||
if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | switch (flags & MOUSE_FLAGS_MASK) { | ||||
case 0: | |||||
info->sc_flags |= UMS_FLAG_Y_ABS; | |||||
case MOUSE_FLAGS: | |||||
info->sc_flags |= UMS_FLAG_Y_AXIS; | info->sc_flags |= UMS_FLAG_Y_AXIS; | ||||
} | } | ||||
hselasky: add "default:" and "break;" and "/* FALLTHROUGH */" to the sc_flags checks. | |||||
} | } | ||||
/* Try the wheel first as the Z activator since it's tradition. */ | /* Try the wheel first as the Z activator since it's tradition. */ | ||||
if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | ||||
HUG_WHEEL), hid_input, index, &info->sc_loc_z, &flags, | HUG_WHEEL), hid_input, index, &info->sc_loc_z, &flags, | ||||
&info->sc_iid_z) || | &info->sc_iid_z) || | ||||
hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | ||||
HUG_TWHEEL), hid_input, index, &info->sc_loc_z, &flags, | HUG_TWHEEL), hid_input, index, &info->sc_loc_z, &flags, | ||||
&info->sc_iid_z)) { | &info->sc_iid_z)) { | ||||
if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | |||||
switch (flags & MOUSE_FLAGS_MASK) { | |||||
case 0: | |||||
info->sc_flags |= UMS_FLAG_Z_ABS; | |||||
case MOUSE_FLAGS: | |||||
info->sc_flags |= UMS_FLAG_Z_AXIS; | info->sc_flags |= UMS_FLAG_Z_AXIS; | ||||
} | } | ||||
/* | /* | ||||
* We might have both a wheel and Z direction, if so put | * We might have both a wheel and Z direction, if so put | ||||
* put the Z on the W coordinate. | * put the Z on the W coordinate. | ||||
*/ | */ | ||||
if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | ||||
HUG_Z), hid_input, index, &info->sc_loc_w, &flags, | HUG_Z), hid_input, index, &info->sc_loc_w, &flags, | ||||
&info->sc_iid_w)) { | &info->sc_iid_w)) { | ||||
if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | ||||
info->sc_flags |= UMS_FLAG_W_AXIS; | info->sc_flags |= UMS_FLAG_W_AXIS; | ||||
} | } | ||||
} | } | ||||
} else if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | } else if (hid_locate(buf, len, HID_USAGE2(HUP_GENERIC_DESKTOP, | ||||
HUG_Z), hid_input, index, &info->sc_loc_z, &flags, | HUG_Z), hid_input, index, &info->sc_loc_z, &flags, | ||||
&info->sc_iid_z)) { | &info->sc_iid_z)) { | ||||
if ((flags & MOUSE_FLAGS_MASK) == MOUSE_FLAGS) { | switch (flags & MOUSE_FLAGS_MASK) { | ||||
case 0: | |||||
info->sc_flags |= UMS_FLAG_Z_ABS; | |||||
case MOUSE_FLAGS: | |||||
info->sc_flags |= UMS_FLAG_Z_AXIS; | info->sc_flags |= UMS_FLAG_Z_AXIS; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* The Microsoft Wireless Intellimouse 2.0 reports it's wheel | * The Microsoft Wireless Intellimouse 2.0 reports it's wheel | ||||
* using 0x0048, which is HUG_TWHEEL, and seems to expect you | * using 0x0048, which is HUG_TWHEEL, and seems to expect you | ||||
* to know that the byte after the wheel is the tilt axis. | * to know that the byte after the wheel is the tilt axis. | ||||
* There are no other HID axis descriptors other than X,Y and | * There are no other HID axis descriptors other than X,Y and | ||||
Show All 39 Lines | ums_hid_parse(struct ums_softc *sc, device_t dev, const uint8_t *buf, | ||||
if (i > sc->sc_buttons) | if (i > sc->sc_buttons) | ||||
sc->sc_buttons = i; | sc->sc_buttons = i; | ||||
if (info->sc_flags == 0) | if (info->sc_flags == 0) | ||||
return; | return; | ||||
/* announce information about the mouse */ | /* announce information about the mouse */ | ||||
device_printf(dev, "%d buttons and [%s%s%s%s%s] coordinates ID=%u\n", | device_printf(dev, "%d buttons and [%s%s%s%s%s]%s coordinates ID=%u\n", | ||||
(info->sc_buttons), | (info->sc_buttons), | ||||
(info->sc_flags & UMS_FLAG_X_AXIS) ? "X" : "", | (info->sc_flags & UMS_FLAG_X_AXIS) ? "X" : "", | ||||
(info->sc_flags & UMS_FLAG_Y_AXIS) ? "Y" : "", | (info->sc_flags & UMS_FLAG_Y_AXIS) ? "Y" : "", | ||||
(info->sc_flags & UMS_FLAG_Z_AXIS) ? "Z" : "", | (info->sc_flags & UMS_FLAG_Z_AXIS) ? "Z" : "", | ||||
(info->sc_flags & UMS_FLAG_T_AXIS) ? "T" : "", | (info->sc_flags & UMS_FLAG_T_AXIS) ? "T" : "", | ||||
(info->sc_flags & UMS_FLAG_W_AXIS) ? "W" : "", | (info->sc_flags & UMS_FLAG_W_AXIS) ? "W" : "", | ||||
(info->sc_flags & (UMS_FLAG_X_ABS | UMS_FLAG_Y_ABS | UMS_FLAG_Z_ABS)) ? " (absolute)" : "", | |||||
info->sc_iid_x); | info->sc_iid_x); | ||||
} | } | ||||
static int | static int | ||||
ums_attach(device_t dev) | ums_attach(device_t dev) | ||||
{ | { | ||||
struct usb_attach_arg *uaa = device_get_ivars(dev); | struct usb_attach_arg *uaa = device_get_ivars(dev); | ||||
struct ums_softc *sc = device_get_softc(dev); | struct ums_softc *sc = device_get_softc(dev); | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | for (j = 0; j < UMS_INFO_MAX; j++) { | ||||
} | } | ||||
} | } | ||||
DPRINTF("size=%d, id=%d\n", isize, sc->sc_iid); | DPRINTF("size=%d, id=%d\n", isize, sc->sc_iid); | ||||
#endif | #endif | ||||
err = usb_fifo_attach(uaa->device, sc, &sc->sc_mtx, | err = usb_fifo_attach(uaa->device, sc, &sc->sc_mtx, | ||||
&ums_fifo_methods, &sc->sc_fifo, | &ums_fifo_methods, &sc->sc_fifo, | ||||
device_get_unit(dev), -1, uaa->info.bIfaceIndex, | device_get_unit(dev), -1, uaa->info.bIfaceIndex, | ||||
UID_ROOT, GID_OPERATOR, 0644); | UID_ROOT, GID_OPERATOR, 0644); | ||||
Not Done Inline ActionsAre there any reasons to allocate fifo in absolute mode? wulf_cicgroup.ru: Are there any reasons to allocate fifo in absolute mode? | |||||
Not Done Inline ActionsThis is not my code, so I have no idea. Changes to this should be done in a different commit. vi_endrift.com: This is not my code, so I have no idea. Changes to this should be done in a different commit. | |||||
Not Done Inline Actionsusb_fifo_attach() here creates /dev/umsX character device which is silent in absolute mode according to proposed changes wulf_cicgroup.ru: usb_fifo_attach() here creates /dev/umsX character device which is silent in absolute mode… | |||||
if (err) | if (err) | ||||
goto detach; | goto detach; | ||||
#ifdef EVDEV_SUPPORT | #ifdef EVDEV_SUPPORT | ||||
info = &sc->sc_info[0]; | |||||
sc->sc_evdev = evdev_alloc(); | sc->sc_evdev = evdev_alloc(); | ||||
evdev_set_name(sc->sc_evdev, device_get_desc(dev)); | evdev_set_name(sc->sc_evdev, device_get_desc(dev)); | ||||
evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev)); | evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev)); | ||||
evdev_set_id(sc->sc_evdev, BUS_USB, uaa->info.idVendor, | evdev_set_id(sc->sc_evdev, BUS_USB, uaa->info.idVendor, | ||||
uaa->info.idProduct, 0); | uaa->info.idProduct, 0); | ||||
evdev_set_serial(sc->sc_evdev, usb_get_serial(uaa->device)); | evdev_set_serial(sc->sc_evdev, usb_get_serial(uaa->device)); | ||||
evdev_set_methods(sc->sc_evdev, sc, &ums_evdev_methods); | evdev_set_methods(sc->sc_evdev, sc, &ums_evdev_methods); | ||||
evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER); | evdev_support_prop(sc->sc_evdev, INPUT_PROP_POINTER); | ||||
Not Done Inline ActionsWhat is the type of your absolute device? For touchscreens INPUT_PROP_DIRECT should be set, not INPUT_PROP_POINTER wulf_cicgroup.ru: What is the type of your absolute device? For touchscreens INPUT_PROP_DIRECT should be set, not… | |||||
evdev_support_event(sc->sc_evdev, EV_SYN); | evdev_support_event(sc->sc_evdev, EV_SYN); | ||||
if (info->sc_flags & (UMS_FLAG_X_ABS | UMS_FLAG_Y_ABS | UMS_FLAG_Z_ABS)) | |||||
evdev_support_event(sc->sc_evdev, EV_ABS); | |||||
evdev_support_event(sc->sc_evdev, EV_REL); | evdev_support_event(sc->sc_evdev, EV_REL); | ||||
Not Done Inline ActionsI think, no need to set EV_REL when no relative axes are used wulf_cicgroup.ru: I think, no need to set EV_REL when no relative axes are used | |||||
Not Done Inline ActionsThere may still be some relative axes present. I can check. vi_endrift.com: There may still be some relative axes present. I can check. | |||||
Not Done Inline ActionsActually, the code as-is always pushes a relative event for HWHEEL, assuming HWHEEL is present. It's probably possible to avoid setting EV_REL if not needed, but it might just add unneeded complexity. vi_endrift.com: Actually, the code as-is always pushes a relative event for HWHEEL, assuming HWHEEL is present. | |||||
Not Done Inline Actions
No. HWHEEL events are filtered out at evdev layer if HWHEEL has not been advertised at device registration. evdev_push is called unconditionaly here just to skip extra useless checking
I recommend to compare evdev description with Linux-derived one and set exactly the same properties. In several cases e.g. xf86-input-evdev software uses libmagic-alike routines to detect device types and quirks and setting different device description can bring incompatibilities. wulf_cicgroup.ru: > the code as-is always pushes a relative event for HWHEEL, assuming HWHEEL is present
No. | |||||
evdev_support_event(sc->sc_evdev, EV_KEY); | evdev_support_event(sc->sc_evdev, EV_KEY); | ||||
info = &sc->sc_info[0]; | if (info->sc_flags & UMS_FLAG_X_AXIS) { | ||||
if (info->sc_flags & UMS_FLAG_X_ABS) | |||||
if (info->sc_flags & UMS_FLAG_X_AXIS) | evdev_support_abs(sc->sc_evdev, ABS_X, 0, 0, 0x7fff, 0, 0, 0); | ||||
Not Done Inline ActionsYou should parse HID descriptor for logical reporting range and physical resolution and advertise it here wulf_cicgroup.ru: You should parse HID descriptor for logical reporting range and physical resolution and… | |||||
Not Done Inline ActionsYep, I was basing this change off of another driver that had a TODO there. I can actually parse it out though. vi_endrift.com: Yep, I was basing this change off of another driver that had a TODO there. I can actually parse… | |||||
else | |||||
evdev_support_rel(sc->sc_evdev, REL_X); | evdev_support_rel(sc->sc_evdev, REL_X); | ||||
} | |||||
if (info->sc_flags & UMS_FLAG_Y_AXIS) | if (info->sc_flags & UMS_FLAG_Y_AXIS) { | ||||
if (info->sc_flags & UMS_FLAG_Y_ABS) | |||||
evdev_support_abs(sc->sc_evdev, ABS_Y, 0, 0, 0x7fff, 0, 0, 0); | |||||
else | |||||
evdev_support_rel(sc->sc_evdev, REL_Y); | evdev_support_rel(sc->sc_evdev, REL_Y); | ||||
} | |||||
if (info->sc_flags & UMS_FLAG_Z_AXIS) | if (info->sc_flags & UMS_FLAG_Z_AXIS) { | ||||
evdev_support_rel(sc->sc_evdev, REL_WHEEL); | if (info->sc_flags & UMS_FLAG_Z_ABS) | ||||
evdev_support_abs(sc->sc_evdev, ABS_Z, 0, 0, 0x7fff, 0, 0, 0); | |||||
else | |||||
evdev_support_rel(sc->sc_evdev, REL_Z); | |||||
} | |||||
if (info->sc_flags & UMS_FLAG_T_AXIS) | if (info->sc_flags & UMS_FLAG_T_AXIS) | ||||
evdev_support_rel(sc->sc_evdev, REL_HWHEEL); | evdev_support_rel(sc->sc_evdev, REL_HWHEEL); | ||||
for (i = 0; i < info->sc_buttons; i++) | for (i = 0; i < info->sc_buttons; i++) | ||||
evdev_support_key(sc->sc_evdev, BTN_MOUSE + i); | evdev_support_key(sc->sc_evdev, BTN_MOUSE + i); | ||||
err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx); | err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx); | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | |||||
#ifdef EVDEV_SUPPORT | #ifdef EVDEV_SUPPORT | ||||
static void | static void | ||||
ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy, | ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy, | ||||
int32_t dz, int32_t dt, int32_t buttons) | int32_t dz, int32_t dt, int32_t buttons) | ||||
{ | { | ||||
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) { | if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) { | ||||
/* Push evdev event */ | /* Push evdev event */ | ||||
if (sc->sc_info[0].sc_flags & UMS_FLAG_X_ABS) | |||||
evdev_push_event(sc->sc_evdev, EV_ABS, ABS_X, dx); | |||||
Not Done Inline ActionsYou can use evdev_push_abs(sc->sc_evdev, ABS_X, dx); here to be consistent with relative case wulf_cicgroup.ru: You can use
```
evdev_push_abs(sc->sc_evdev, ABS_X, dx);
```
here to be consistent with… | |||||
Not Done Inline ActionsI did not think that exists? But I just checked and it does. vi_endrift.com: I did not think that exists? But I just checked and it does. | |||||
else | |||||
evdev_push_rel(sc->sc_evdev, REL_X, dx); | evdev_push_rel(sc->sc_evdev, REL_X, dx); | ||||
if (sc->sc_info[0].sc_flags & UMS_FLAG_Y_ABS) | |||||
evdev_push_event(sc->sc_evdev, EV_ABS, ABS_Y, -dy); | |||||
else | |||||
evdev_push_rel(sc->sc_evdev, REL_Y, -dy); | evdev_push_rel(sc->sc_evdev, REL_Y, -dy); | ||||
if (sc->sc_info[0].sc_flags & UMS_FLAG_Z_ABS) | |||||
evdev_push_event(sc->sc_evdev, EV_ABS, ABS_WHEEL, -dx); | |||||
Not Done Inline Actions-dz ? wulf_cicgroup.ru: -dz ? | |||||
Not Done Inline ActionsNoted, thanks. vi_endrift.com: Noted, thanks. | |||||
else | |||||
evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz); | evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz); | ||||
evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt); | evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt); | ||||
evdev_push_mouse_btn(sc->sc_evdev, | evdev_push_mouse_btn(sc->sc_evdev, | ||||
(buttons & ~MOUSE_STDBUTTONS) | | (buttons & ~MOUSE_STDBUTTONS) | | ||||
(buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) | | (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) | | ||||
(buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) | | (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) | | ||||
(buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0)); | (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0)); | ||||
evdev_sync(sc->sc_evdev); | evdev_sync(sc->sc_evdev); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 291 Lines • Show Last 20 Lines |
add "default:" and "break;" and "/* FALLTHROUGH */" to the sc_flags checks.