if (sscanf(t, "0x%x", &i) == 1) { ksym = (KeySym) i;
if (sscanf(t, "0x%x", &ui) == 1) { ksym = (KeySym) ui;
static void buttonparse(int from, char **s) {	char *q;	int to, i;	int modisdown[256];	q = *s;	for (i=0; i<256; i++) {		modisdown[i] = 0;	}	if (*q == ':') {		/* :sym1+sym2+...+symN: format */		int l = 0, n = 0;		char list[1000];		char *t, *kp = q + 1;		KeyCode kcode;		while (*(kp+l) != ':' && *(kp+l) != '\0') {			/* loop to the matching ':' */			l++;			if (l >= 1000) {				rfbLog("buttonparse: keysym list too long: "				    "%s\n", q);				break;			}		}		*(kp+l) = '\0';		strncpy(list, kp, l);		list[l] = '\0';		rfbLog("remap button %d using \"%s\"\n", from, list);		/* loop over tokens separated by '+' */		t = strtok(list, "+");		while (t) {			KeySym ksym;			int i;			if (n >= MAX_BUTTON_EVENTS - 20) {				rfbLog("buttonparse: too many button map "					"events: %s\n", list);				break;			}			if (sscanf(t, "0x%x", &i) == 1) {				ksym = (KeySym) i;	/* hex value */			} else {				X_LOCK;				ksym = XStringToKeysym(t); /* string value */				X_UNLOCK;			}			if (ksym == NoSymbol) {				/* see if Button<N> "keysym" was used: */				if (sscanf(t, "Button%d", &i) == 1) {					rfbLog("   event %d: button %d\n",					    from, n+1, i);					if (i == 0) i = -1; /* bah */					pointer_map[from][n].keysym  = NoSymbol;					pointer_map[from][n].keycode = NoSymbol;					pointer_map[from][n].button = i;					pointer_map[from][n].end    = 0;					pointer_map[from][n].down   = 0;					pointer_map[from][n].up     = 0;				} else {					rfbLog("buttonparse: ignoring unknown "					    "keysym: %s\n", t);					n--;				}			} else {				/*				 * XXX may not work with -modtweak or -xkb				 */				X_LOCK;				kcode = XKeysymToKeycode(dpy, ksym);				pointer_map[from][n].keysym  = ksym;				pointer_map[from][n].keycode = kcode;				pointer_map[from][n].button = 0;				pointer_map[from][n].end    = 0;				if (! ismodkey(ksym) ) {					/* do both down then up */					pointer_map[from][n].down = 1;					pointer_map[from][n].up   = 1;				} else {					if (modisdown[kcode]) {						pointer_map[from][n].down = 0;						pointer_map[from][n].up   = 1;						modisdown[kcode] = 0;					} else {						pointer_map[from][n].down = 1;						pointer_map[from][n].up   = 0;						modisdown[kcode] = 1;					}				}				rfbLog("   event %d: keysym %s (0x%x) -> "				    "keycode 0x%x down=%d up=%d\n", n+1,				    XKeysymToString(ksym), ksym, kcode,				    pointer_map[from][n].down,				    pointer_map[from][n].up);				X_UNLOCK;			}			t = strtok(NULL, "+");			n++;		}		/* we must release any modifiers that are still down: */		for (i=0; i<256; i++) {			kcode = (KeyCode) i;			if (n >= MAX_BUTTON_EVENTS) {				rfbLog("buttonparse: too many button map "					"events: %s\n", list);				break;			}			if (modisdown[kcode]) {				pointer_map[from][n].keysym  = NoSymbol;				pointer_map[from][n].keycode = kcode;				pointer_map[from][n].button = 0;				pointer_map[from][n].end    = 0;				pointer_map[from][n].down = 0;				pointer_map[from][n].up   = 1;				modisdown[kcode] = 0;				n++;			}		}		/* advance the source pointer position */		(*s) += l+2;	} else {		/* single digit format */		char str[2];		str[0] = *q;		str[1] = '\0';		to = atoi(str);		if (to < 1) {			rfbLog("skipping invalid remap button \"%d\" for button"			    " %d from string \"%s\"\n",			    to, from, str);		} else {			rfbLog("remap button %d using \"%s\"\n", from, str);			rfbLog("   button: %d -> %d\n", from, to);			pointer_map[from][0].keysym  = NoSymbol;			pointer_map[from][0].keycode = NoSymbol;			pointer_map[from][0].button = to;			pointer_map[from][0].end    = 0;			pointer_map[from][0].down   = 0;			pointer_map[from][0].up     = 0;		}		/* advance the source pointer position */		(*s)++;	}}