static int mx_query(int fd, u8 b1, u8 *res) { u8 buf[6] = { first_byte, 0x81, b1, 0, 0, 0 }; int i; send_report(fd, 0x10, buf, 6); query_report(fd, 0x10, res, 6); for (int i = 0; i < 6; i++) res[i] = res[i+1]; if (( (res[0] != 0x02 && res[0] != 0x01 && res[0] != 0x00) || res[1] != 0x81 || (res[2] != 0xb1 && res[2] != 0x08) ) && ( (res[0] != 0x02 && res[0] != 0x01 && res[0] != 0x00) || res[1] != 0x81 || (res[2] != 0x0d && res[2] != 0x08) )) { printf("bad answer:"); for (i = 0; i < 6; ++i) { printf("%02X ", res[i]); } printf("\n"); return 0; } return 1; }
static int mx_query(int fd, int b1, int *res) { int buf[6] = { first_byte, 0x81, b1, 0, 0, 0 }; send_report(fd, 0x10, buf, 6); res[0] = -1; query_report(fd, 0x10, res, 6); if ((res[0] != 0x01 || res[1] != 0x81 || res[2] != 0xb1) && (res[0] != 0x02 || res[1] != 0x81 || (res[2] != 0x0d && res[2] != 0x08))) { printf("bad answer (%02x %02x %02x...)\n", res[0], res[1], res[2]); return 0; } return 1; }
static void configure(int handle, int argc, char **argv) { int i, arg1, arg2; for (i = 1; i < argc; ++i) { int perm = 0x80; char *cmd = argv[i]; if (strneq(cmd, "temp-", 5)) perm = 0, cmd += 5; if (streq(cmd, "free")) { mx_cmd(handle, perm + 1, 0, 0); } else if (streq(cmd, "click")) { mx_cmd(handle, perm + 2, 0, 0); } else if (strneq(cmd, "manual", 6)) { twoargs(cmd + 6, &arg1, &arg2, 0, 0, 15); if (arg1 != arg2) mx_cmd(handle, perm + 7, arg1 * 16 + arg2, 0); else mx_cmd(handle, perm + 8, arg1, 0); } else if (strneq(cmd, "auto", 4)) { twoargs(cmd + 4, &arg1, &arg2, 0, 0, 50); mx_cmd(handle, perm + 5, arg1, arg2); } else if (strneq(argv[i], "soft-free", 9)) { twoargs(argv[i] + 9, &arg1, &arg2, 0, 0, 255); mx_cmd(handle, 3, arg1, arg2); } else if (strneq(argv[i], "soft-click", 10)) { twoargs(argv[i] + 10, &arg1, &arg2, 0, 0, 255); mx_cmd(handle, 4, arg1, arg2); } else if (strneq(argv[i], "reconnect", 9)) { static const int cmd[] = { 0xff, 0x80, 0xb2, 1, 0, 0 }; twoargs(argv[i] + 9, &arg1, &arg2, 0, 0, 255); send_report(handle, 0x10, cmd, 6); printf("Reconnection initiated\n"); printf(" - Turn off the mouse\n"); printf(" - Press and hold the left mouse button\n"); printf(" - Turn on the mouse\n"); printf(" - Press the right button 5 times\n"); printf(" - Release the left mouse button\n"); wait_report(handle, 60000); } else if (strneq(argv[i], "mode", 4)) { int buf[6]; if (mx_query(handle, 0x08, buf)) { if (buf[5] & 1) printf("click-by-click\n"); else printf("free spinning\n"); } } else if (strneq(argv[i], "battery", 7)) { int buf[6]; if (mx_query(handle, 0x0d, buf)) { char str[32], *st; switch (buf[5]) { case 0x30: st = "running on battery"; break; case 0x50: st = "charging"; break; case 0x90: st = "fully charged"; break; default: sprintf(st = str, "status %02x", buf[5]); } printf("battery level %d%%, %s\n", buf[3], st); } } /*** debug commands ***/ else if (strneq(argv[i], "raw", 3)) { int buf[256], n; n = nargs(argv[i] + 3, buf, 256, 0, 0, 255); send_report(handle, buf[0], buf+1, n-1); } else if (strneq(argv[i], "query", 5)) { int buf[256], j; twoargs(argv[i] + 5, &arg1, &arg2, -1, 0, 255); if (arg1 == -1) arg1 = 0x10, arg2 = 6; query_report(handle, arg1, buf, arg2); printf("report %02x:", arg1); for (j = 0; j < arg2; ++j) printf(" %02x", buf[j]); printf("\n"); } else if (strneq(argv[i], "dump", 4)) { twoargs(cmd + 4, &arg1, &arg2, 3, -1, 24*60*60); if (arg1 > 0) arg1 *= 1000; while (wait_for_input(handle, arg1) > 0) { struct hiddev_usage_ref uref; if (read(handle, &uref, sizeof(uref)) == sizeof(uref)) printf("read: type=%u, id=%u, field=%08x, usage=%08x," " code=%08x, value=%u\n", uref.report_type, uref.report_id, uref.field_index, uref.usage_index, uref.usage_code, uref.value); } } else if (strneq(argv[i], "sleep", 5)) { twoargs(argv[i] + 5, &arg1, &arg2, 1, 0, 255); sleep(arg1); } else fatal("unknown option `%s'", argv[i]); } }