Read multiple events at once.
Before: Both drivers currently do one read(2) per event, but since we use a "sync" event we have a least two of them for ws(4) but more commonly 3 for ws(4) and 4 for synaptics(4). most of the code and ok mpi@
This commit is contained in:
parent
a74e8629b1
commit
d1fc35bb69
@ -36,6 +36,14 @@ extern int priv_open_device(const char *);
|
|||||||
|
|
||||||
#define DEFAULT_WSMOUSE_DEV "/dev/wsmouse0"
|
#define DEFAULT_WSMOUSE_DEV "/dev/wsmouse0"
|
||||||
|
|
||||||
|
#define NWSEVENTS 16
|
||||||
|
|
||||||
|
struct wsconscomm_proto_data {
|
||||||
|
struct wscons_event events[NWSEVENTS];
|
||||||
|
size_t events_count;
|
||||||
|
size_t events_pos;
|
||||||
|
};
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
WSConsIsTouchpad(InputInfoPtr pInfo, const char *device)
|
WSConsIsTouchpad(InputInfoPtr pInfo, const char *device)
|
||||||
{
|
{
|
||||||
@ -72,23 +80,42 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static size_t
|
||||||
WSConsReadEvent(InputInfoPtr pInfo, struct wscons_event *event)
|
WSConsReadEvents(InputInfoPtr pInfo)
|
||||||
{
|
{
|
||||||
Bool rc = TRUE;
|
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
|
||||||
|
struct wsconscomm_proto_data *proto_data = priv->proto_data;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
len = read(pInfo->fd, event, sizeof(struct wscons_event));
|
proto_data->events_count = proto_data->events_pos = 0;
|
||||||
|
len = read(pInfo->fd, proto_data->events, sizeof(proto_data->events));
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
if (errno != EAGAIN)
|
if (errno != EAGAIN)
|
||||||
xf86IDrvMsg(pInfo, X_ERROR, "read error %s\n", strerror(errno));
|
xf86IDrvMsg(pInfo, X_ERROR, "read error %s\n", strerror(errno));
|
||||||
rc = FALSE;
|
|
||||||
} else if (len % sizeof(struct wscons_event)) {
|
} else if (len % sizeof(struct wscons_event)) {
|
||||||
xf86IDrvMsg(pInfo, X_ERROR, "read error, invalid number of bytes\n");
|
xf86IDrvMsg(pInfo, X_ERROR, "read error, invalid number of bytes\n");
|
||||||
rc = FALSE;
|
} else {
|
||||||
|
proto_data->events_count = len / sizeof(struct wscons_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return proto_data->events_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wscons_event *
|
||||||
|
WSConsGetEvent(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
|
||||||
|
struct wsconscomm_proto_data *proto_data = priv->proto_data;
|
||||||
|
struct wscons_event *event;
|
||||||
|
|
||||||
|
if (proto_data->events_count == 0 && WSConsReadEvents(pInfo) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
event = &proto_data->events[proto_data->events_pos];
|
||||||
|
proto_data->events_pos++;
|
||||||
|
proto_data->events_count--;
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
@ -128,16 +155,17 @@ WSConsReadHwState(InputInfoPtr pInfo,
|
|||||||
struct CommData *comm, struct SynapticsHwState *hwRet)
|
struct CommData *comm, struct SynapticsHwState *hwRet)
|
||||||
{
|
{
|
||||||
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
|
SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
|
||||||
|
struct wsconscomm_proto_data *proto_data = priv->proto_data;
|
||||||
struct SynapticsHwState *hw = comm->hwState;
|
struct SynapticsHwState *hw = comm->hwState;
|
||||||
struct wscons_event event;
|
struct wscons_event *event;
|
||||||
Bool v;
|
Bool v;
|
||||||
|
|
||||||
while (WSConsReadEvent(pInfo, &event)) {
|
while ((event = WSConsGetEvent(pInfo)) != NULL) {
|
||||||
switch (event.type) {
|
switch (event->type) {
|
||||||
case WSCONS_EVENT_MOUSE_UP:
|
case WSCONS_EVENT_MOUSE_UP:
|
||||||
case WSCONS_EVENT_MOUSE_DOWN:
|
case WSCONS_EVENT_MOUSE_DOWN:
|
||||||
v = (event.type == WSCONS_EVENT_MOUSE_DOWN) ? TRUE : FALSE;
|
v = (event->type == WSCONS_EVENT_MOUSE_DOWN) ? TRUE : FALSE;
|
||||||
switch (event.value) {
|
switch (event->value) {
|
||||||
case 0:
|
case 0:
|
||||||
hw->left = v;
|
hw->left = v;
|
||||||
break;
|
break;
|
||||||
@ -180,25 +208,25 @@ WSConsReadHwState(InputInfoPtr pInfo,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
|
||||||
hw->x = event.value;
|
hw->x = event->value;
|
||||||
hw->cumulative_dx = hw->x;
|
hw->cumulative_dx = hw->x;
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
|
||||||
hw->y = priv->maxy - event.value + priv->miny;
|
hw->y = priv->maxy - event->value + priv->miny;
|
||||||
hw->cumulative_dy = hw->y;
|
hw->cumulative_dy = hw->y;
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
|
||||||
hw->z = event.value;
|
hw->z = event->value;
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
|
||||||
if (priv->model == MODEL_ELANTECH) {
|
if (priv->model == MODEL_ELANTECH) {
|
||||||
/* Elantech touchpads report number of fingers directly. */
|
/* Elantech touchpads report number of fingers directly. */
|
||||||
hw->fingerWidth = 5;
|
hw->fingerWidth = 5;
|
||||||
hw->numFingers = event.value;
|
hw->numFingers = event->value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* XXX magic number mapping which is mirrored in pms driver */
|
/* XXX magic number mapping which is mirrored in pms driver */
|
||||||
switch (event.value) {
|
switch (event->value) {
|
||||||
case 0:
|
case 0:
|
||||||
hw->fingerWidth = 5;
|
hw->fingerWidth = 5;
|
||||||
hw->numFingers = 2;
|
hw->numFingers = 2;
|
||||||
@ -208,7 +236,7 @@ WSConsReadHwState(InputInfoPtr pInfo,
|
|||||||
hw->numFingers = 3;
|
hw->numFingers = 3;
|
||||||
break;
|
break;
|
||||||
case 4 ... 5:
|
case 4 ... 5:
|
||||||
hw->fingerWidth = event.value;
|
hw->fingerWidth = event->value;
|
||||||
hw->numFingers = 1;
|
hw->numFingers = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -226,7 +254,8 @@ WSConsReadHwState(InputInfoPtr pInfo,
|
|||||||
hw->fingerWidth = 5;
|
hw->fingerWidth = 5;
|
||||||
hw->numFingers = 2;
|
hw->numFingers = 2;
|
||||||
}
|
}
|
||||||
hw->millis = 1000 * event.time.tv_sec + event.time.tv_nsec / 1000000;
|
hw->millis = 1000 * event->time.tv_sec +
|
||||||
|
event->time.tv_nsec / 1000000;
|
||||||
SynapticsCopyHwState(hwRet, hw);
|
SynapticsCopyHwState(hwRet, hw);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
@ -263,7 +292,16 @@ WSConsReadDevDimensions(InputInfoPtr pInfo)
|
|||||||
struct wsmouse_calibcoords wsmc;
|
struct wsmouse_calibcoords wsmc;
|
||||||
int wsmouse_type;
|
int wsmouse_type;
|
||||||
|
|
||||||
|
priv->proto_data = calloc(1, sizeof(struct wsconscomm_proto_data));
|
||||||
|
if (priv->proto_data == NULL) {
|
||||||
|
xf86IDrvMsg(pInfo, X_ERROR, "failed to allocate protocol data (%s)\n",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &wsmc) != 0) {
|
if (ioctl(pInfo->fd, WSMOUSEIO_GCALIBCOORDS, &wsmc) != 0) {
|
||||||
|
free(priv->proto_data);
|
||||||
|
priv->proto_data = NULL;
|
||||||
xf86IDrvMsg(pInfo, X_ERROR, "failed to query axis range (%s)\n",
|
xf86IDrvMsg(pInfo, X_ERROR, "failed to query axis range (%s)\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
/* $OpenBSD: ws.c,v 1.61 2015/02/17 08:21:14 matthieu Exp $ */
|
/* $OpenBSD: ws.c,v 1.62 2015/08/29 08:48:29 shadchin Exp $ */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -457,78 +457,94 @@ wsDeviceOff(DeviceIntPtr pWS)
|
|||||||
pWS->public.on = FALSE;
|
pWS->public.on = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static size_t
|
||||||
wsReadEvent(InputInfoPtr pInfo, struct wscons_event *event)
|
wsReadEvents(InputInfoPtr pInfo)
|
||||||
{
|
{
|
||||||
Bool rc = TRUE;
|
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
len = read(pInfo->fd, event, sizeof(struct wscons_event));
|
priv->events_count = priv->events_pos = 0;
|
||||||
if (len <= 0) {
|
len = read(pInfo->fd, priv->events, sizeof(priv->events));
|
||||||
|
if (len < 0) {
|
||||||
if (errno != EAGAIN)
|
if (errno != EAGAIN)
|
||||||
xf86IDrvMsgVerb(pInfo, X_ERROR, 4, "read error %s\n",
|
xf86IDrvMsg(pInfo, X_ERROR, "read error %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
rc = FALSE;
|
} else if (len % sizeof(struct wscons_event)) {
|
||||||
} else if (len != sizeof(struct wscons_event)) {
|
|
||||||
xf86IDrvMsg(pInfo, X_ERROR,
|
xf86IDrvMsg(pInfo, X_ERROR,
|
||||||
"read error, invalid number of bytes\n");
|
"read error, invalid number of bytes\n");
|
||||||
rc = FALSE;
|
} else {
|
||||||
|
priv->events_count = len / sizeof(struct wscons_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return priv->events_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wscons_event *
|
||||||
|
wsGetEvent(InputInfoPtr pInfo)
|
||||||
|
{
|
||||||
|
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
|
||||||
|
struct wscons_event *event;
|
||||||
|
|
||||||
|
if (priv->events_count == 0 && wsReadEvents(pInfo) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
event = &priv->events[priv->events_pos];
|
||||||
|
priv->events_pos++;
|
||||||
|
priv->events_count--;
|
||||||
|
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
wsReadHwState(InputInfoPtr pInfo, wsHwState *hw)
|
wsReadHwState(InputInfoPtr pInfo, wsHwState *hw)
|
||||||
{
|
{
|
||||||
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
|
WSDevicePtr priv = (WSDevicePtr)pInfo->private;
|
||||||
struct wscons_event event;
|
struct wscons_event *event;
|
||||||
|
|
||||||
bzero(hw, sizeof(wsHwState));
|
bzero(hw, sizeof(wsHwState));
|
||||||
|
|
||||||
hw->buttons = priv->lastButtons;
|
hw->buttons = priv->lastButtons;
|
||||||
hw->ax = priv->old_ax;
|
hw->ax = priv->old_ax;
|
||||||
hw->ay = priv->old_ay;
|
hw->ay = priv->old_ay;
|
||||||
|
|
||||||
while (wsReadEvent(pInfo, &event)) {
|
while ((event = wsGetEvent(pInfo)) != NULL) {
|
||||||
switch (event.type) {
|
switch (event->type) {
|
||||||
case WSCONS_EVENT_MOUSE_UP:
|
case WSCONS_EVENT_MOUSE_UP:
|
||||||
hw->buttons &= ~(1 << event.value);
|
hw->buttons &= ~(1 << event->value);
|
||||||
DBG(4, ErrorF("Button %d up %x\n", event.value,
|
DBG(4, ErrorF("Button %d up %x\n", event->value,
|
||||||
hw->buttons));
|
hw->buttons));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_DOWN:
|
case WSCONS_EVENT_MOUSE_DOWN:
|
||||||
hw->buttons |= (1 << event.value);
|
hw->buttons |= (1 << event->value);
|
||||||
DBG(4, ErrorF("Button %d down %x\n", event.value,
|
DBG(4, ErrorF("Button %d down %x\n", event->value,
|
||||||
hw->buttons));
|
hw->buttons));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_DELTA_X:
|
case WSCONS_EVENT_MOUSE_DELTA_X:
|
||||||
hw->dx = event.value;
|
hw->dx = event->value;
|
||||||
DBG(4, ErrorF("Relative X %d\n", event.value));
|
DBG(4, ErrorF("Relative X %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_DELTA_Y:
|
case WSCONS_EVENT_MOUSE_DELTA_Y:
|
||||||
hw->dy = -event.value;
|
hw->dy = -event->value;
|
||||||
DBG(4, ErrorF("Relative Y %d\n", event.value));
|
DBG(4, ErrorF("Relative Y %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_DELTA_Z:
|
case WSCONS_EVENT_MOUSE_DELTA_Z:
|
||||||
hw->dz = event.value;
|
hw->dz = event->value;
|
||||||
DBG(4, ErrorF("Relative Z %d\n", event.value));
|
DBG(4, ErrorF("Relative Z %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_DELTA_W:
|
case WSCONS_EVENT_MOUSE_DELTA_W:
|
||||||
hw->dw = event.value;
|
hw->dw = event->value;
|
||||||
DBG(4, ErrorF("Relative W %d\n", event.value));
|
DBG(4, ErrorF("Relative W %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
|
||||||
hw->ax = event.value;
|
hw->ax = event->value;
|
||||||
if (priv->inv_x)
|
if (priv->inv_x)
|
||||||
hw->ax = priv->max_x - hw->ax + priv->min_x;
|
hw->ax = priv->max_x - hw->ax + priv->min_x;
|
||||||
DBG(4, ErrorF("Absolute X %d\n", event.value));
|
DBG(4, ErrorF("Absolute X %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
|
||||||
hw->ay = event.value;
|
hw->ay = event->value;
|
||||||
if (priv->inv_y)
|
if (priv->inv_y)
|
||||||
hw->ay = priv->max_y - hw->ay + priv->min_y;
|
hw->ay = priv->max_y - hw->ay + priv->min_y;
|
||||||
DBG(4, ErrorF("Absolute Y %d\n", event.value));
|
DBG(4, ErrorF("Absolute Y %d\n", event->value));
|
||||||
break;
|
break;
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
|
||||||
case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
|
||||||
@ -539,7 +555,7 @@ wsReadHwState(InputInfoPtr pInfo, wsHwState *hw)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
xf86IDrvMsg(pInfo, X_WARNING,
|
xf86IDrvMsg(pInfo, X_WARNING,
|
||||||
"bad wsmouse event type=%d\n", event.type);
|
"bad wsmouse event type=%d\n", event->type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
|
@ -32,6 +32,8 @@ extern int ws_debug_level;
|
|||||||
|
|
||||||
#define WS_NOMAP 0
|
#define WS_NOMAP 0
|
||||||
|
|
||||||
|
#define NWSEVENTS 16 /* size of buffer */
|
||||||
|
|
||||||
/* axis specific data for wheel */
|
/* axis specific data for wheel */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int negative;
|
int negative;
|
||||||
@ -84,6 +86,10 @@ typedef struct WSDevice {
|
|||||||
Time expires; /* time of expiry */
|
Time expires; /* time of expiry */
|
||||||
Time timeout;
|
Time timeout;
|
||||||
} emulateWheel;
|
} emulateWheel;
|
||||||
|
|
||||||
|
struct wscons_event events[NWSEVENTS];
|
||||||
|
size_t events_count;
|
||||||
|
size_t events_pos;
|
||||||
} WSDeviceRec, *WSDevicePtr;
|
} WSDeviceRec, *WSDevicePtr;
|
||||||
|
|
||||||
/* Middle mouse button emulation */
|
/* Middle mouse button emulation */
|
||||||
|
Loading…
Reference in New Issue
Block a user