[PATCH xi2.1 xserver] Reallocate touches outside of signal context
Chase Douglas
chase.douglas at canonical.com
Thu Feb 10 15:04:20 PST 2011
To be squashed into xi2.1 commit
BeginTouchPoint is called in signal context. Instead, check the
allocation of touches whenever a touch event is handled. If the
allocation is 50% used, double the allocation.
This also fixes a big bug where we were reallocating the entire touch
class, not just the array of touches. It also memsets the new touches.
Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
Xi/exevents.c | 34 ++++++++++++++++++++++++++++++++++
dix/devices.c | 9 ++++++---
dix/inpututils.c | 17 +++++------------
include/inputstr.h | 1 +
4 files changed, 46 insertions(+), 15 deletions(-)
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8185a0e..e391147 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1373,6 +1373,40 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr sourcedev)
if (!t)
return;
+ /* If we hit 50% utilization of touches, double the number of touch
+ * frames. */
+ if (t->active_touches > t->num_touches / 2)
+ {
+ void *tmp;
+
+ tmp = realloc(t->touches, (t->num_touches * 2) * sizeof(*t->touches));
+ if (tmp)
+ {
+ int i;
+
+ t->touches = tmp;
+ memset(t->touches + t->num_touches, 0,
+ t->num_touches * sizeof(*t->touches));
+
+ for (i = t->num_touches; i < t->num_touches * 2; i++)
+ {
+ if (!InitTouchPoint(t, i))
+ {
+ LogMessage(X_ERROR,
+ "%s: failed to initialize new touchpoint %d\n",
+ sourcedev->name, i);
+ break;
+ }
+ }
+ t->num_touches = i;
+
+ LogMessage(X_INFO, "%s: reallocated %d touches\n", sourcedev->name,
+ t->num_touches);
+ } else
+ LogMessage(X_ERROR, "%s: failed to allocate more touches (%d)\n",
+ sourcedev->name, t->num_touches * 2);
+ }
+
if (ev->any.type == ET_TouchOwnership)
touchid = ev->touch_ownership_event.touchid;
else
diff --git a/dix/devices.c b/dix/devices.c
index 2e75b49..105e6b8 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1653,11 +1653,14 @@ InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
touch->max_touches = max_touches;
if (max_touches == 0)
max_touches = 5; /* arbitrary number plucked out of the air */
- touch->touches = calloc(max_touches, sizeof(*touch->touches));
+
+ /* Need cushion for clients who may hold on to touches after they physically
+ * end. So double the initial allocation of touches. */
+ touch->touches = calloc(max_touches * 2, sizeof(*touch->touches));
if (!touch->touches)
goto err;
- touch->num_touches = max_touches;
- for (i = 0; i < max_touches; i++)
+ touch->num_touches = max_touches * 2;
+ for (i = 0; i < touch->num_touches; i++)
InitTouchPoint(touch, i);
touch->mode = mode;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index c2016c0..2b37cae 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -618,7 +618,6 @@ BeginTouchPoint(DeviceIntPtr dev, uint32_t ddx_id)
int i;
TouchClassPtr t = dev->touch;
TouchPointInfoPtr ti;
- void *tmp;
if (!t)
return NULL;
@@ -630,7 +629,6 @@ BeginTouchPoint(DeviceIntPtr dev, uint32_t ddx_id)
if (FindTouchPointByDDXID(dev, ddx_id))
return NULL;
-try_find_touch:
for (i = 0; i < t->num_touches; i++)
{
ti = &t->touches[i];
@@ -638,6 +636,7 @@ try_find_touch:
ti->active = TRUE;
ti->ddx_id = ddx_id;
ti->client_id = t->next_client_id;
+ t->active_touches++;
next_touch_id:
t->next_client_id++;
if (t->next_client_id == 0)
@@ -648,16 +647,8 @@ next_touch_id:
}
}
- /* If we get here, then we've run out of touches: enlarge dev->touch and
- * try again. */
- tmp = realloc(t, (t->num_touches + 1) * sizeof(*t));
- if (tmp)
- {
- dev->touch = tmp;
- t->num_touches++;
- if (InitTouchPoint(t, t->num_touches - 1))
- goto try_find_touch;
- }
+ /* If we get here, then we've run out of touches. */
+ LogMessage(X_WARNING, "%s: no more touches available\n", dev->name);
return NULL;
}
@@ -671,6 +662,7 @@ void
EndTouchPoint(DeviceIntPtr dev, TouchPointInfoPtr ti)
{
int i;
+ TouchClassPtr t = dev->touch;
ti->active = FALSE;
ti->pending_finish = FALSE;
@@ -681,6 +673,7 @@ EndTouchPoint(DeviceIntPtr dev, TouchPointInfoPtr ti)
ti->num_grabs = 0;
ti->client_id = 0;
ti->ddx_id = 0;
+ t->active_touches--;
for (i = 0; i < ti->num_valuators; i++)
ti->valuators[i] = 0;
diff --git a/include/inputstr.h b/include/inputstr.h
index 3d86b34..b23a23b 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -319,6 +319,7 @@ typedef struct _TouchClassRec {
TouchPointInfoPtr touches;
unsigned short num_touches; /* number of allocated touches */
unsigned short max_touches; /* maximum number of touches, may be 0 */
+ unsigned short active_touches; /* number of active touches */
CARD8 mode; /* ::XIDirectTouch, XIDependentTouch */
uint32_t next_client_id; /* next client_id to give out */
int x_axis; /* axis number of x axis */
--
1.7.2.3
More information about the xorg-devel
mailing list