Merge remote-tracking branch 'whot/for-keith'

This commit is contained in:
Keith Packard 2012-08-27 08:06:09 -07:00
commit a557edca61
6 changed files with 270 additions and 25 deletions

View File

@ -1327,6 +1327,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
RawDeviceEvent *raw; RawDeviceEvent *raw;
double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */
double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */
int sx, sy; /* for POINTER_SCREEN */
ValuatorMask mask; ValuatorMask mask;
ScreenPtr scr; ScreenPtr scr;
@ -1369,8 +1370,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
/* valuators are in driver-native format (rel or abs) */ /* valuators are in driver-native format (rel or abs) */
if (flags & POINTER_ABSOLUTE) { if (flags & POINTER_ABSOLUTE) {
if (flags & POINTER_SCREEN) /* valuators are in screen coords */ if (flags & POINTER_SCREEN) { /* valuators are in screen coords */
sx = valuator_mask_get(&mask, 0);
sy = valuator_mask_get(&mask, 1);
scale_from_screen(pDev, &mask); scale_from_screen(pDev, &mask);
}
transformAbsolute(pDev, &mask); transformAbsolute(pDev, &mask);
clipAbsolute(pDev, &mask); clipAbsolute(pDev, &mask);
@ -1388,6 +1392,18 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
/* valuators are in device coordinate system in absolute coordinates */ /* valuators are in device coordinate system in absolute coordinates */
scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny); scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
/* #53037 XWarpPointer's scaling back and forth between screen and
device may leave us with rounding errors. End result is that the
pointer doesn't end up on the pixel it should.
Avoid this by forcing screenx/screeny back to what the input
coordinates were.
*/
if (flags & POINTER_SCREEN) {
screenx = sx;
screeny = sy;
}
scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
&mask, &devx, &devy, &screenx, &screeny); &mask, &devx, &devy, &screenx, &screeny);

View File

@ -247,6 +247,7 @@ padding_for_int32(const int bytes)
extern char **xstrtokenize(const char *str, const char *separators); 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 FormatUInt64(uint64_t num, char *string);
extern void FormatUInt64Hex(uint64_t num, char *string); extern void FormatUInt64Hex(uint64_t num, char *string);

View File

@ -575,7 +575,7 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
miPointerPtr pPointer; miPointerPtr pPointer;
if (!pDev || !pDev->coreEvents) if (!pDev)
return NULL; return NULL;
pPointer = MIPOINTER(pDev); pPointer = MIPOINTER(pDev);

View File

@ -290,6 +290,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
int p_len; int p_len;
int i; int i;
uint64_t ui; uint64_t ui;
int64_t si;
for (; f_idx < f_len && s_idx < size - 1; f_idx++) { for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
if (f[f_idx] != '%') { if (f[f_idx] != '%') {
@ -311,6 +312,15 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
FormatUInt64(ui, number); FormatUInt64(ui, number);
p_len = strlen_sigsafe(number); p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i];
break;
case 'i':
case 'd':
si = va_arg(args, int);
FormatInt64(si, number);
p_len = strlen_sigsafe(number);
for (i = 0; i < p_len && s_idx < size - 1; i++) for (i = 0; i < p_len && s_idx < size - 1; i++)
string[s_idx++] = number[i]; string[s_idx++] = number[i];
break; break;
@ -364,7 +374,7 @@ LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
if (verb < 0 || logFileVerbosity >= verb) { if (verb < 0 || logFileVerbosity >= verb) {
if (inSignalContext && logFileFd >= 0) { if (inSignalContext && logFileFd >= 0) {
write(logFileFd, buf, len); write(logFileFd, buf, len);
#ifdef WIN32 #ifndef WIN32
if (logFlush && logSync) if (logFlush && logSync)
fsync(logFileFd); fsync(logFileFd);
#endif #endif
@ -457,6 +467,7 @@ LogMessageTypeVerbString(MessageType type, int verb)
void void
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args) LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
{ {
static unsigned int warned;
const char *type_str; const char *type_str;
char buf[1024]; char buf[1024];
const size_t size = sizeof(buf); const size_t size = sizeof(buf);
@ -464,13 +475,17 @@ LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
size_t len = 0; size_t len = 0;
if (inSignalContext) { if (inSignalContext) {
BUG_WARN_MSG(inSignalContext, if (warned < 3) {
"Warning: attempting to log data in a signal unsafe " BUG_WARN_MSG(inSignalContext,
"manner while in signal context. Please update to check " "Warning: attempting to log data in a signal unsafe "
"inSignalContext and/or use LogMessageVerbSigSafe() or " "manner while in signal context.\nPlease update to check "
"ErrorFSigSafe(). The offending log format message is:\n" "inSignalContext and/or use LogMessageVerbSigSafe() or "
"%s\n", format); "ErrorFSigSafe().\nThe offending log format message is:\n"
return; "%s\n", format);
warned++;
if (warned == 3)
LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
}
} }
type_str = LogMessageTypeVerbString(type, verb); type_str = LogMessageTypeVerbString(type, verb);
@ -556,6 +571,7 @@ void
LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format, LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
va_list msg_args, const char *hdr_format, va_list hdr_args) va_list msg_args, const char *hdr_format, va_list hdr_args)
{ {
static unsigned int warned;
const char *type_str; const char *type_str;
char buf[1024]; char buf[1024];
const size_t size = sizeof(buf); const size_t size = sizeof(buf);
@ -563,13 +579,17 @@ LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
size_t len = 0; size_t len = 0;
if (inSignalContext) { if (inSignalContext) {
BUG_WARN_MSG(inSignalContext, if (warned < 3) {
"Warning: attempting to log data in a signal unsafe " BUG_WARN_MSG(inSignalContext,
"manner while in signal context. Please update to check " "Warning: attempting to log data in a signal unsafe "
"inSignalContext and/or use LogMessageVerbSigSafe(). The " "manner while in signal context.\nPlease update to check "
"offending header and log message formats are:\n%s %s\n", "inSignalContext and/or use LogMessageVerbSigSafe().\nThe "
hdr_format, msg_format); "offending header and log message formats are:\n%s %s\n",
return; hdr_format, msg_format);
warned++;
if (warned == 3)
LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
}
} }
type_str = LogMessageTypeVerbString(type, verb); type_str = LogMessageTypeVerbString(type, verb);

View File

@ -1924,6 +1924,20 @@ xstrtokenize(const char *str, const char *separators)
return NULL; return NULL;
} }
/* Format a signed number into a string in a signal safe manner. The string
* should be at least 21 characters in order to handle all int64_t values.
*/
void
FormatInt64(int64_t num, char *string)
{
if (num < 0) {
string[0] = '-';
num *= -1;
string++;
}
FormatUInt64(num, string);
}
/* Format a number into a string in a signal safe manner. The string should be /* Format a number into a string in a signal safe manner. The string should be
* at least 21 characters in order to handle all uint64_t values. */ * at least 21 characters in order to handle all uint64_t values. */
void void

View File

@ -26,6 +26,7 @@
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <unistd.h>
#include "assert.h" #include "assert.h"
#include "misc.h" #include "misc.h"
@ -35,6 +36,26 @@ struct number_format_test {
char hex_string[17]; char hex_string[17];
}; };
struct signed_number_format_test {
int64_t number;
char string[21];
};
static Bool
check_signed_number_format_test(const struct signed_number_format_test *test)
{
char string[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);
return FALSE;
}
return TRUE;
}
static Bool static Bool
check_number_format_test(const struct number_format_test *test) check_number_format_test(const struct number_format_test *test)
{ {
@ -57,11 +78,11 @@ check_number_format_test(const struct number_format_test *test)
return TRUE; return TRUE;
} }
static Bool static void
number_formatting(void) number_formatting(void)
{ {
int i; int i;
struct number_format_test tests[] = { struct number_format_test unsigned_tests[] = {
{ /* Zero */ { /* Zero */
0, 0,
"0", "0",
@ -99,17 +120,190 @@ number_formatting(void)
}, },
}; };
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) struct signed_number_format_test signed_tests[] = {
if (!check_number_format_test(tests + i)) { /* Zero */
return FALSE; 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",
},
};
return TRUE; for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); 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));
}
static void logging_format(void)
{
const char *log_file_path = "/tmp/Xorg-logging-test.log";
const char *str = "%s %d %u %% %p %i";
char buf[1024];
int i;
unsigned int ui;
FILE *f;
char read_buf[2048];
char *logmsg;
uintptr_t ptr;
/* set up buf to contain ".....end" */
memset(buf, '.', sizeof(buf));
strcpy(&buf[sizeof(buf) - 4], "end");
LogInit(log_file_path, NULL);
assert(f = fopen(log_file_path, "r"));
#define read_log_msg(msg) \
fgets(read_buf, sizeof(read_buf), f); \
msg = strchr(read_buf, ']') + 2; /* advance past [time.stamp] */
/* boring test message */
LogMessageVerbSigSafe(X_ERROR, -1, "test message\n");
read_log_msg(logmsg);
assert(strcmp(logmsg, "(EE) test message\n") == 0);
/* long buf is truncated to "....en\n" */
#pragma GCC diagnostic ignored "-Wformat-security"
LogMessageVerbSigSafe(X_ERROR, -1, buf);
#pragma GCC diagnostic pop "-Wformat-security"
read_log_msg(logmsg);
assert(strcmp(&logmsg[strlen(logmsg) - 3], "en\n") == 0);
/* same thing, this time as string substitution */
LogMessageVerbSigSafe(X_ERROR, -1, "%s", buf);
read_log_msg(logmsg);
assert(strcmp(&logmsg[strlen(logmsg) - 3], "en\n") == 0);
/* strings containing placeholders should just work */
LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", str);
read_log_msg(logmsg);
assert(strcmp(logmsg, "(EE) %s %d %u %% %p %i\n") == 0);
/* string substitution */
LogMessageVerbSigSafe(X_ERROR, -1, "%s\n", "substituted string");
read_log_msg(logmsg);
assert(strcmp(logmsg, "(EE) substituted string\n") == 0);
/* number substitution */
ui = 0;
do {
char expected[30];
sprintf(expected, "(EE) %u\n", ui);
LogMessageVerbSigSafe(X_ERROR, -1, "%u\n", ui);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
if (ui == 0)
ui = 1;
else
ui <<= 1;
} while(ui);
/* signed number substitution */
i = 0;
do {
char expected[30];
sprintf(expected, "(EE) %d\n", i);
LogMessageVerbSigSafe(X_ERROR, -1, "%d\n", i);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
sprintf(expected, "(EE) %d\n", i | INT_MIN);
LogMessageVerbSigSafe(X_ERROR, -1, "%d\n", i | INT_MIN);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
if (i == 0)
i = 1;
else
i <<= 1;
} while(i > INT_MIN);
/* hex number substitution */
ui = 0;
do {
char expected[30];
sprintf(expected, "(EE) %x\n", ui);
LogMessageVerbSigSafe(X_ERROR, -1, "%x\n", ui);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
if (ui == 0)
ui = 1;
else
ui <<= 1;
} while(ui);
/* pointer substitution */
/* we print a null-pointer differently to printf */
LogMessageVerbSigSafe(X_ERROR, -1, "%p\n", NULL);
read_log_msg(logmsg);
assert(strcmp(logmsg, "(EE) 0x0\n") == 0);
ptr = 1;
do {
char expected[30];
sprintf(expected, "(EE) %p\n", (void*)ptr);
LogMessageVerbSigSafe(X_ERROR, -1, "%p\n", (void*)ptr);
read_log_msg(logmsg);
assert(strcmp(logmsg, expected) == 0);
ptr <<= 1;
} while(ptr);
LogClose(EXIT_NO_ERROR);
unlink(log_file_path);
#undef read_log_msg
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int ok = number_formatting(); number_formatting();
logging_format();
return ok ? 0 : 1; return 0;
} }