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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
