dix: Reallocate touchpoint buffer at input event time [v2]
Now that input is threaded, malloc can be used at event time to resize the touchpoint buffer as needed.x v2: Remove "Need to grow the queue means dropping events." from comment as it no longer applies. (Peter Hutterer) Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
e2df803fca
commit
f84703b50c
54
dix/touch.c
54
dix/touch.c
|
@ -42,9 +42,6 @@
|
||||||
|
|
||||||
#define TOUCH_HISTORY_SIZE 100
|
#define TOUCH_HISTORY_SIZE 100
|
||||||
|
|
||||||
/* If a touch queue resize is needed, the device id's bit is set. */
|
|
||||||
static unsigned char resize_waiting[(MAXDEVICES + 7) / 8];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some documentation about touch points:
|
* Some documentation about touch points:
|
||||||
* The driver submits touch events with it's own (unique) touch point ID.
|
* The driver submits touch events with it's own (unique) touch point ID.
|
||||||
|
@ -74,31 +71,14 @@ static unsigned char resize_waiting[(MAXDEVICES + 7) / 8];
|
||||||
* @return Always True. If we fail to grow we probably will topple over soon
|
* @return Always True. If we fail to grow we probably will topple over soon
|
||||||
* anyway and re-executing this won't help.
|
* anyway and re-executing this won't help.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
TouchResizeQueue(ClientPtr client, void *closure)
|
TouchResizeQueue(DeviceIntPtr dev)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
input_lock();
|
|
||||||
|
|
||||||
/* first two ids are reserved */
|
|
||||||
for (i = 2; i < MAXDEVICES; i++) {
|
|
||||||
DeviceIntPtr dev;
|
|
||||||
DDXTouchPointInfoPtr tmp;
|
DDXTouchPointInfoPtr tmp;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (!BitIsOn(resize_waiting, i))
|
/* Grow sufficiently so we don't need to do it often */
|
||||||
continue;
|
|
||||||
|
|
||||||
ClearBit(resize_waiting, i);
|
|
||||||
|
|
||||||
/* device may have disappeared by now */
|
|
||||||
dixLookupDevice(&dev, i, serverClient, DixWriteAccess);
|
|
||||||
if (!dev)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Need to grow the queue means dropping events. Grow sufficiently so we
|
|
||||||
* don't need to do it often */
|
|
||||||
size = dev->last.num_touches + dev->last.num_touches / 2 + 1;
|
size = dev->last.num_touches + dev->last.num_touches / 2 + 1;
|
||||||
|
|
||||||
tmp = reallocarray(dev->last.touches, size, sizeof(*dev->last.touches));
|
tmp = reallocarray(dev->last.touches, size, sizeof(*dev->last.touches));
|
||||||
|
@ -109,12 +89,9 @@ TouchResizeQueue(ClientPtr client, void *closure)
|
||||||
for (j = dev->last.num_touches; j < size; j++)
|
for (j = dev->last.num_touches; j < size; j++)
|
||||||
TouchInitDDXTouchPoint(dev, &dev->last.touches[j]);
|
TouchInitDDXTouchPoint(dev, &dev->last.touches[j]);
|
||||||
dev->last.num_touches = size;
|
dev->last.num_touches = size;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
input_unlock();
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,6 +149,7 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id)
|
||||||
if (TouchFindByDDXID(dev, ddx_id, FALSE))
|
if (TouchFindByDDXID(dev, ddx_id, FALSE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
for (i = 0; i < dev->last.num_touches; i++) {
|
for (i = 0; i < dev->last.num_touches; i++) {
|
||||||
/* Only emulate pointer events on the first touch */
|
/* Only emulate pointer events on the first touch */
|
||||||
if (dev->last.touches[i].active)
|
if (dev->last.touches[i].active)
|
||||||
|
@ -182,6 +160,11 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id)
|
||||||
if (!emulate_pointer && ti)
|
if (!emulate_pointer && ti)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (ti)
|
||||||
|
break;
|
||||||
|
if (!TouchResizeQueue(dev))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ti) {
|
if (ti) {
|
||||||
int client_id;
|
int client_id;
|
||||||
|
@ -194,21 +177,8 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id)
|
||||||
next_client_id = 1;
|
next_client_id = 1;
|
||||||
ti->client_id = client_id;
|
ti->client_id = client_id;
|
||||||
ti->emulate_pointer = emulate_pointer;
|
ti->emulate_pointer = emulate_pointer;
|
||||||
|
}
|
||||||
return ti;
|
return ti;
|
||||||
}
|
|
||||||
|
|
||||||
/* If we get here, then we've run out of touches and we need to drop the
|
|
||||||
* event (we're inside the SIGIO handler here) schedule a WorkProc to
|
|
||||||
* grow the queue for us for next time. */
|
|
||||||
ErrorFSigSafe("%s: not enough space for touch events (max %u touchpoints). "
|
|
||||||
"Dropping this event.\n", dev->name, dev->last.num_touches);
|
|
||||||
|
|
||||||
if (!BitIsOn(resize_waiting, dev->id)) {
|
|
||||||
SetBit(resize_waiting, dev->id);
|
|
||||||
QueueWorkProc(TouchResizeQueue, serverClient, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue