Merge branch 'ptraccel-fixes' into for-keith

This commit is contained in:
Peter Hutterer 2013-02-08 14:10:52 +10:00
commit 0d5bb88260
6 changed files with 190 additions and 124 deletions

View File

@ -776,11 +776,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
* @param[in,out] mask Valuator data for this event, modified in-place.
*/
static void
moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
{
int i;
Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
/* for abs devices in relative mode, we've just scaled wrong, since we
mapped the device's shape into the screen shape. Undo this. */
if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
double ratio = 1.0 * screenInfo.width/screenInfo.height;
if (ratio > 1.0) {
double y;
if (valuator_mask_fetch_double(mask, 1, &y)) {
y *= ratio;
valuator_mask_set_double(mask, 1, y);
}
} else {
double x;
if (valuator_mask_fetch_double(mask, 0, &x)) {
x *= ratio;
valuator_mask_set_double(mask, 0, x);
}
}
}
/* calc other axes, clip, drop back into valuators */
for (i = 0; i < valuator_mask_size(mask); i++) {
double val = dev->last.valuators[i];
@ -1386,7 +1408,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
if ((flags & POINTER_NORAW) == 0)
set_raw_valuators(raw, &mask, raw->valuators.data);
moveRelative(pDev, &mask);
moveRelative(pDev, flags, &mask);
}
/* valuators are in device coordinate system in absolute coordinates */

View File

@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
/*#define PTRACCEL_DEBUGGING*/
#ifdef PTRACCEL_DEBUGGING
#define DebugAccelF ErrorF
#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__)
#else
#define DebugAccelF(...) /* */
#endif
@ -421,7 +421,7 @@ void
InitTrackers(DeviceVelocityPtr vel, int ntracker)
{
if (ntracker < 1) {
ErrorF("(dix ptracc) invalid number of trackers\n");
ErrorF("invalid number of trackers\n");
return;
}
free(vel->tracker);
@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
vel->tracker[n].dy = 0.0;
vel->tracker[n].time = cur_t;
vel->tracker[n].dir = GetDirection(dx, dy);
DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n",
dx, dy, vel->tracker[n].dir,
cur_t - vel->tracker[vel->cur_tracker].time);
vel->cur_tracker = n;
@ -614,7 +614,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
/* bail out if data is too old and protect from overrun */
if (age_ms >= vel->reset_time || age_ms < 0) {
DebugAccelF("(dix prtacc) query: tracker too old\n");
DebugAccelF("query: tracker too old (reset after %d, age is %d)\n",
vel->reset_time, age_ms);
break;
}
@ -626,7 +627,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
*/
dir &= tracker->dir;
if (dir == 0) { /* we've changed octant of movement (e.g. NE → NW) */
DebugAccelF("(dix prtacc) query: no longer linear\n");
DebugAccelF("query: no longer linear\n");
/* instead of breaking it we might also inspect the partition after,
* but actual improvement with this is probably rare. */
break;
@ -647,7 +648,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
velocity_diff / (initial_velocity + tracker_velocity) >=
vel->max_rel_diff) {
/* we're not in range, quit - it won't get better. */
DebugAccelF("(dix prtacc) query: tracker too different:"
DebugAccelF("query: tracker too different:"
" old %2.2f initial %2.2f diff: %2.2f\n",
tracker_velocity, initial_velocity, velocity_diff);
break;
@ -660,14 +661,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
}
}
if (offset == vel->num_tracker) {
DebugAccelF("(dix prtacc) query: last tracker in effect\n");
DebugAccelF("query: last tracker in effect\n");
used_offset = vel->num_tracker - 1;
}
if (used_offset >= 0) {
#ifdef PTRACCEL_DEBUGGING
MotionTracker *tracker = TRACKER(vel, used_offset);
DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n",
used_offset, tracker->dx, tracker->dy,
cur_t - tracker->time);
#endif
@ -693,6 +694,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
velocity = QueryTrackers(vel, time);
DebugAccelF("velocity is %f\n", velocity);
vel->velocity = velocity;
return velocity == 0;
}
@ -768,7 +771,7 @@ ComputeAcceleration(DeviceIntPtr dev,
double result;
if (vel->velocity <= 0) {
DebugAccelF("(dix ptracc) profile skipped\n");
DebugAccelF("profile skipped\n");
/*
* If we have no idea about device velocity, don't pretend it.
*/
@ -792,14 +795,14 @@ ComputeAcceleration(DeviceIntPtr dev,
threshold,
acc);
result /= 6.0f;
DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
vel->velocity, vel->last_velocity, result);
}
else {
result = BasicComputeAcceleration(dev, vel,
vel->velocity, threshold, acc);
DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
vel->velocity, res);
DebugAccelF("profile sample [%.2f] is %.3f\n",
vel->velocity, result);
}
return result;
@ -1050,11 +1053,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
DeviceVelocityPtr
GetDevicePredictableAccelData(DeviceIntPtr dev)
{
/*sanity check */
if (!dev) {
ErrorF("[dix] accel: DeviceIntPtr was NULL");
return NULL;
}
BUG_RETURN_VAL(!dev, NULL);
if (dev->valuator &&
dev->valuator->accelScheme.AccelSchemeProc ==
acceleratePointerPredictable &&
@ -1113,6 +1113,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
(double) dev->ptrfeed->ctrl.num /
(double) dev->ptrfeed->ctrl.den);
DebugAccelF("mult is %f\n", mult);
if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
if (mult > 1.0f && soften)
ApplySoftening(velocitydata, &dx, &dy);
@ -1122,8 +1123,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
valuator_mask_set_double(val, 0, mult * dx);
if (dy != 0.0)
valuator_mask_set_double(val, 1, mult * dy);
DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
mult * dy);
DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy);
}
}
}

View File

@ -250,6 +250,7 @@ extern char **xstrtokenize(const char *str, const char *separators);
extern void FormatInt64(int64_t num, char *string);
extern void FormatUInt64(uint64_t num, char *string);
extern void FormatUInt64Hex(uint64_t num, char *string);
extern void FormatDouble(double dbl, char *string);
/**
* Compare the two version numbers comprising of major.minor.

View File

@ -298,7 +298,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
continue;
}
switch (f[++f_idx]) {
f_idx++;
/* silently swallow length modifiers */
while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
f_idx++;
switch (f[f_idx]) {
case 's':
string_arg = va_arg(args, char*);
p_len = strlen_sigsafe(string_arg);
@ -345,7 +351,16 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
case 'f':
{
double d = va_arg(args, double);
FormatDouble(d, number);
p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
}
break;
default:
va_arg(args, char*);
string[s_idx++] = '%';

View File

@ -1990,6 +1990,38 @@ FormatUInt64(uint64_t num, char *string)
string[len] = '\0';
}
/**
* Format a double number as %.2f.
*/
void
FormatDouble(double dbl, char *string)
{
int slen = 0;
uint64_t frac;
frac = (dbl > 0 ? dbl : -dbl) * 100.0;
frac %= 100;
/* write decimal part to string */
if (dbl < 0 && dbl > -1)
string[slen++] = '-';
FormatInt64((int64_t)dbl, &string[slen]);
while(string[slen] != '\0')
slen++;
/* append fractional part, but only if we have enough characters. We
* expect string to be 21 chars (incl trailing \0) */
if (slen <= 17) {
string[slen++] = '.';
if (frac < 10)
string[slen++] = '0';
FormatUInt64(frac, &string[slen]);
}
}
/* Format a number into a hexadecimal string in a signal safe manner. The string
* should be at least 17 characters in order to handle all uint64_t values. */
void

View File

@ -41,15 +41,22 @@ struct signed_number_format_test {
char string[21];
};
struct float_number_format_test {
double number;
char string[21];
};
static Bool
check_signed_number_format_test(const struct signed_number_format_test *test)
check_signed_number_format_test(long int number)
{
char string[21];
char expected[21];
FormatInt64(test->number, string);
if(strncmp(string, test->string, 21) != 0) {
fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n",
test->number, test->string, string);
sprintf(expected, "%ld", number);
FormatInt64(number, string);
if(strncmp(string, expected, 21) != 0) {
fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n",
number, expected, string);
return FALSE;
}
@ -57,125 +64,90 @@ check_signed_number_format_test(const struct signed_number_format_test *test)
}
static Bool
check_number_format_test(const struct number_format_test *test)
check_float_format_test(double number)
{
char string[21];
char expected[21];
FormatUInt64(test->number, string);
if(strncmp(string, test->string, 21) != 0) {
/* we currently always print float as .2f */
sprintf(expected, "%.2f", number);
FormatDouble(number, string);
if(strncmp(string, expected, 21) != 0) {
fprintf(stderr, "Failed to convert %f to string (%s vs %s)\n",
number, expected, string);
return FALSE;
}
return TRUE;
}
static Bool
check_number_format_test(long unsigned int number)
{
char string[21];
char expected[21];
sprintf(expected, "%lu", number);
FormatUInt64(number, string);
if(strncmp(string, expected, 21) != 0) {
fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n",
test->number, test->string, string);
number, expected, string);
return FALSE;
}
FormatUInt64Hex(test->number, string);
if(strncmp(string, test->hex_string, 17) != 0) {
fprintf(stderr,
"Failed to convert %ju to hexadecimal string (%s vs %s)\n",
test->number, test->hex_string, string);
sprintf(expected, "%lx", number);
FormatUInt64Hex(number, string);
if(strncmp(string, expected, 17) != 0) {
fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
number, expected, string);
return FALSE;
}
return TRUE;
}
/* FIXME: max range stuff */
double float_tests[] = { 0, 5, 0.1, 0.01, 5.2342, 10.2301,
-1, -2.00, -0.6023, -1203.30
};
static void
number_formatting(void)
{
int i;
struct number_format_test unsigned_tests[] = {
{ /* Zero */
0,
"0",
"0",
},
{ /* Single digit number */
5,
"5",
"5",
},
{ /* Two digit decimal number */
12,
"12",
"c",
},
{ /* Two digit hex number */
37,
"37",
"25",
},
{ /* Large < 32 bit number */
0xC90B2,
"823474",
"c90b2",
},
{ /* Large > 32 bit number */
0x15D027BF211B37A,
"98237498237498234",
"15d027bf211b37a",
},
{ /* Maximum 64-bit number */
0xFFFFFFFFFFFFFFFF,
"18446744073709551615",
"ffffffffffffffff",
},
long unsigned int unsigned_tests[] = { 0,/* Zero */
5, /* Single digit number */
12, /* Two digit decimal number */
37, /* Two digit hex number */
0xC90B2, /* Large < 32 bit number */
0x15D027BF211B37A, /* Large > 32 bit number */
0xFFFFFFFFFFFFFFFF, /* Maximum 64-bit number */
};
struct signed_number_format_test signed_tests[] = {
{ /* Zero */
0,
"0",
},
{ /* Single digit number */
5,
"5",
},
{ /* Two digit decimal number */
12,
"12",
},
{ /* Two digit hex number */
37,
"37",
},
{ /* Large < 32 bit number */
0xC90B2,
"823474",
},
{ /* Large > 32 bit number */
0x15D027BF211B37A,
"98237498237498234",
},
{ /* Maximum 64-bit signed number */
0x7FFFFFFFFFFFFFFF,
"9223372036854775807",
},
{ /* Single digit number */
-1,
"-1",
},
{ /* Two digit decimal number */
-12,
"-12",
},
{ /* Large < 32 bit number */
-0xC90B2,
"-823474",
},
{ /* Large > 32 bit number */
-0x15D027BF211B37A,
"-98237498237498234",
},
{ /* Maximum 64-bit number */
-0x7FFFFFFFFFFFFFFF,
"-9223372036854775807",
},
};
long int signed_tests[] = { 0,/* Zero */
5, /* Single digit number */
12, /* Two digit decimal number */
37, /* Two digit hex number */
0xC90B2, /* Large < 32 bit number */
0x15D027BF211B37A, /* Large > 32 bit number */
0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
-1, /* Single digit number */
-12, /* Two digit decimal number */
-0xC90B2, /* Large < 32 bit number */
-0x15D027BF211B37A, /* Large > 32 bit number */
-0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
} ;
for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
assert(check_number_format_test(unsigned_tests + i));
assert(check_number_format_test(unsigned_tests[i]));
for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
assert(check_signed_number_format_test(signed_tests + i));
assert(check_signed_number_format_test(signed_tests[i]));
for (i = 0; i < sizeof(float_tests) / sizeof(float_tests[0]); i++)
assert(check_float_format_test(float_tests[i]));
}
#pragma GCC diagnostic ignored "-Wformat-security"
@ -292,6 +264,30 @@ static void logging_format(void)
ptr <<= 1;
} while(ptr);
for (i = 0; i < sizeof(float_tests)/sizeof(float_tests[0]); i++) {
double d = float_tests[i];
char expected[30];
sprintf(expected, "(EE) %.2f\n", d);
LogMessageVerbSigSafe(X_ERROR, -1, "%f\n", d);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
/* test for length modifiers, we just ignore them atm */
LogMessageVerbSigSafe(X_ERROR, -1, "%.3f\n", d);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
LogMessageVerbSigSafe(X_ERROR, -1, "%3f\n", d);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
LogMessageVerbSigSafe(X_ERROR, -1, "%.0f\n", d);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
}
LogClose(EXIT_NO_ERROR);
unlink(log_file_path);