Advertisement
Guest User

Absum

a guest
Dec 4th, 2007
477
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.37 KB | None | 0 0
  1. Index: spacenavd/spnavd.c
  2. ===================================================================
  3. --- spacenavd/spnavd.c (revision 7)
  4. +++ spacenavd/spnavd.c (working copy)
  5. @@ -17,6 +17,7 @@
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. +#include <stdbool.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <signal.h>
  13. @@ -29,19 +30,22 @@
  14. #include <sys/socket.h>
  15. #include <sys/un.h>
  16. #include <sys/time.h>
  17. +#include <pwd.h>
  18.  
  19. #include <linux/types.h>
  20. #include <linux/input.h>
  21.  
  22. +#include "configparser.h"
  23. +
  24. /* sometimes the rotation events are missing from linux/input.h */
  25. #ifndef REL_RX
  26. -#define REL_RX 3
  27. +#define REL_RX 3
  28. #endif
  29. #ifndef REL_RY
  30. -#define REL_RY 4
  31. +#define REL_RY 4
  32. #endif
  33. #ifndef REL_RZ
  34. -#define REL_RZ 5
  35. +#define REL_RZ 5
  36. #endif
  37.  
  38.  
  39. @@ -50,9 +54,9 @@
  40. #include <X11/Xutil.h>
  41.  
  42. enum cmd_msg {
  43. - CMD_NONE,
  44. - CMD_APP_WINDOW = 27695, /* set client window */
  45. - CMD_APP_SENS /* set app sensitivity */
  46. + CMD_NONE,
  47. + CMD_APP_WINDOW = 27695, /* set client window */
  48. + CMD_APP_SENS /* set app sensitivity */
  49. };
  50. #endif
  51.  
  52. @@ -60,19 +64,20 @@
  53. enum {CLIENT_X11, CLIENT_UNIX};
  54.  
  55. struct client {
  56. - int type;
  57. + int type;
  58.  
  59. - int sock; /* UNIX domain socket */
  60. + int sock; /* UNIX domain socket */
  61. #ifdef USE_X11
  62. - Window win; /* X11 client window */
  63. + Window win; /* X11 client window */
  64. #endif
  65.  
  66. - float sens; /* sensitivity */
  67. + float sens; /* sensitivity */
  68.  
  69. - struct client *next;
  70. + struct client *next;
  71. };
  72.  
  73.  
  74. +void set_led(void);
  75. void daemonize(void);
  76. int select_all(fd_set *rd_set, fd_set *except_set);
  77. void handle_events(fd_set *rd_set, fd_set *except_set);
  78. @@ -102,7 +107,7 @@
  79. int dev_fd;
  80. char dev_name[128];
  81. unsigned char evtype_mask[(EV_MAX + 7) / 8];
  82. -#define TEST_BIT(b, ar) (ar[b / 8] & (1 << (b % 8)))
  83. +#define TEST_BIT(b, ar) (ar[b / 8] & (1 << (b % 8)))
  84.  
  85. int evrel[6];
  86. int evbut[24];
  87. @@ -114,773 +119,886 @@
  88. Window win;
  89. Atom event_motion, event_bpress, event_brelease, event_cmd;
  90.  
  91. -float x11_sens = 1.0; /* XXX This stands in for the client sensitivity. Due
  92. - * to the bad design of the original magellan protocol,
  93. - * we can't know which client requested the sensitivity
  94. - * change, so we have to keep it global for all X
  95. - * clients.
  96. - */
  97. +float x11_sens = 1.0; /* XXX This stands in for the client sensitivity. Due
  98. + * to the bad design of the original magellan protocol,
  99. + * we can't know which client requested the sensitivity
  100. + * change, so we have to keep it global for all X
  101. + * clients.
  102. + */
  103. #endif
  104.  
  105. struct client *client_list;
  106.  
  107. -/* global configuration options */
  108. -float sensitivity = 1.0;
  109. -int dead_threshold = 2;
  110. -
  111. -
  112. int main(int argc, char **argv)
  113. {
  114. - int i, become_daemon = 1;
  115. + int i, become_daemon = 1;
  116. + struct passwd *pw;
  117. + const char *home;
  118. + const char *file;
  119. + char *path;
  120.  
  121. - for(i=1; i<argc; i++) {
  122. - if(argv[i][0] == '-' && argv[i][2] == 0) {
  123. - switch(argv[i][1]) {
  124. - case 'd':
  125. - become_daemon = !become_daemon;
  126. - break;
  127. + for(i=1; i<argc; i++) {
  128. + if(argv[i][0] == '-' && argv[i][2] == 0) {
  129. + switch(argv[i][1]) {
  130. + case 'd':
  131. + become_daemon = !become_daemon;
  132. + break;
  133.  
  134. - case 'h':
  135. - printf("usage: %s [options]\n", argv[0]);
  136. - printf("options:\n");
  137. - printf(" -d\tdo not daemonize\n");
  138. - printf(" -h\tprint this usage information\n");
  139. - return 0;
  140. + case 'h':
  141. + printf("usage: %s [options]\n", argv[0]);
  142. + printf("options:\n");
  143. + printf(" -d\tdo not daemonize\n");
  144. + printf(" -h\tprint this usage information\n");
  145. + return 0;
  146.  
  147. - default:
  148. - fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
  149. - return 1;
  150. - }
  151. - } else {
  152. - fprintf(stderr, "unexpected argument: %s\n", argv[i]);
  153. - return 1;
  154. - }
  155. - }
  156. + default:
  157. + fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
  158. + return 1;
  159. + }
  160. + } else {
  161. + fprintf(stderr, "unexpected argument: %s\n", argv[i]);
  162. + return 1;
  163. + }
  164. + }
  165.  
  166. - if(become_daemon) {
  167. - daemonize();
  168. - }
  169. + if(become_daemon) {
  170. + daemonize();
  171. + }
  172.  
  173. - read_cfg("/etc/spnavrc");
  174. + pw = getpwuid(getuid());
  175. + if(!pw) {
  176. + printf("user not listed in /etc/passwd\n");
  177. + }
  178. + home = pw->pw_dir;
  179. + file = ".spacenavrc";
  180.  
  181. - if(!(client_list = malloc(sizeof *client_list))) {
  182. - perror("failed to allocate client list");
  183. - return 1;
  184. - }
  185. - client_list->next = 0;
  186. + path = alloca(strlen(home) + strlen(file) + 2);
  187. + sprintf(path, "%s/%s", home, file);
  188. + if((read_cfg(path) == -1)&&(read_cfg("/etc/spnavrc") == -1)) {
  189. + printf("Could not find config files; using defaults.\n");
  190. + }
  191.  
  192. - signal(SIGINT, sig_handler);
  193. - signal(SIGTERM, sig_handler);
  194. - signal(SIGHUP, sig_handler);
  195. - signal(SIGUSR1, sig_handler);
  196. - signal(SIGUSR2, sig_handler);
  197.  
  198. - /* initialize the input device and the X11 connection (if available) */
  199. - if(init_dev() == -1) {
  200. - return 1;
  201. - }
  202. - init_unix();
  203. + if(!(client_list = malloc(sizeof *client_list))) {
  204. + perror("failed to allocate client list");
  205. + return 1;
  206. + }
  207. + client_list->next = 0;
  208. +
  209. + signal(SIGINT, sig_handler);
  210. + signal(SIGTERM, sig_handler);
  211. + signal(SIGHUP, sig_handler);
  212. + signal(SIGUSR1, sig_handler);
  213. + signal(SIGUSR2, sig_handler);
  214. +
  215. + /* initialize the input device and the X11 connection (if available) */
  216. + if(init_dev() == -1) {
  217. + return 1;
  218. + }
  219. + init_unix();
  220. #ifdef USE_X11
  221. - init_x11();
  222. + init_x11();
  223. #endif
  224.  
  225. - /* event handling loop */
  226. - while(1) {
  227. - fd_set rd_set, except_set;
  228. + /* event handling loop */
  229. + while(1) {
  230. + fd_set rd_set, except_set;
  231.  
  232. - if(dev_fd == -1) {
  233. - if(init_dev() == -1) {
  234. - sleep(30);
  235. - continue;
  236. - }
  237. - }
  238. + if(dev_fd == -1) {
  239. + if(init_dev() == -1) {
  240. + sleep(30);
  241. + continue;
  242. + }
  243. + }
  244.  
  245. - if(select_all(&rd_set, &except_set) >= 0) {
  246. - handle_events(&rd_set, &except_set);
  247. - }
  248. - }
  249. + if(led_changed) {
  250. + set_led();
  251. + }
  252.  
  253. + if(select_all(&rd_set, &except_set) >= 0) {
  254. + handle_events(&rd_set, &except_set);
  255. + }
  256. + }
  257. +
  258. #ifdef USE_X11
  259. - close_x11();
  260. + close_x11();
  261. #endif
  262. - return 0;
  263. + return 0;
  264. }
  265.  
  266. +void set_led(void)
  267. +{
  268. + struct input_event led_ev;
  269. + int retval = 0;
  270. + led_changed = false;
  271. + led_ev.type = EV_LED;
  272. + led_ev.code = LED_MISC;
  273. + led_ev.value = (int)use_led;
  274. + retval = write(dev_fd, &led_ev, sizeof(struct input_event));
  275. +/*
  276. + if (retval > -1) {
  277. + printf("Led set to: %s!\n", btoa(use_led));
  278. + } else {
  279. + printf("Could not set led!\n");
  280. + }
  281. +*/
  282. +}
  283. +
  284. void daemonize(void)
  285. {
  286. - int i, pid;
  287. + int i, pid;
  288.  
  289. - if((pid = fork()) == -1) {
  290. - perror("failed to fork");
  291. - exit(1);
  292. - } else if(pid) {
  293. - exit(0);
  294. - }
  295. + if((pid = fork()) == -1) {
  296. + perror("failed to fork");
  297. + exit(1);
  298. + } else if(pid) {
  299. + exit(0);
  300. + }
  301.  
  302. - setsid();
  303. - chdir("/");
  304. + setsid();
  305. + chdir("/");
  306.  
  307. - /* redirect standard input/output/error */
  308. - for(i=0; i<3; i++) {
  309. - close(i);
  310. - }
  311. + /* redirect standard input/output/error */
  312. + for(i=0; i<3; i++) {
  313. + close(i);
  314. + }
  315.  
  316. - open("/dev/zero", O_RDONLY);
  317. - if(open("/tmp/spnav.log", O_WRONLY | O_CREAT | O_TRUNC, 0644) == -1) {
  318. - open("/dev/null", O_WRONLY);
  319. - }
  320. - dup(1);
  321. + open("/dev/zero", O_RDONLY);
  322. + if(open("/tmp/spnav.log", O_WRONLY | O_CREAT | O_TRUNC, 0644) == -1) {
  323. + open("/dev/null", O_WRONLY);
  324. + }
  325. + dup(1);
  326.  
  327. - setvbuf(stdout, 0, _IOLBF, 0);
  328. - setvbuf(stderr, 0, _IONBF, 0);
  329. + setvbuf(stdout, 0, _IOLBF, 0);
  330. + setvbuf(stderr, 0, _IONBF, 0);
  331. }
  332.  
  333. int select_all(fd_set *rd_set, fd_set *except_set)
  334. {
  335. - int ret;
  336. - int max_fd, xcon;
  337. - struct client *cptr;
  338. + int ret;
  339. + int max_fd, xcon;
  340. + struct client *cptr;
  341.  
  342. - FD_ZERO(rd_set);
  343. - FD_ZERO(except_set);
  344. + FD_ZERO(rd_set);
  345. + FD_ZERO(except_set);
  346.  
  347. - /* set the device file descriptors */
  348. - FD_SET(dev_fd, rd_set);
  349. - FD_SET(dev_fd, except_set);
  350. - max_fd = dev_fd;
  351. + /* set the device file descriptors */
  352. + FD_SET(dev_fd, rd_set);
  353. + FD_SET(dev_fd, except_set);
  354. + max_fd = dev_fd;
  355.  
  356. - /* if we have a listening socket... */
  357. - if(lsock) {
  358. - /* ... set the listening socket itself for incoming connections */
  359. - FD_SET(lsock, rd_set);
  360. - if(lsock > max_fd) max_fd = lsock;
  361. + /* if we have a listening socket... */
  362. + if(lsock) {
  363. + /* ... set the listening socket itself for incoming connections */
  364. + FD_SET(lsock, rd_set);
  365. + if(lsock > max_fd) max_fd = lsock;
  366.  
  367. - /* ... and set all the client's sockets too */
  368. - cptr = client_list->next;
  369. - while(cptr) {
  370. - if(cptr->type == CLIENT_UNIX) {
  371. - FD_SET(cptr->sock, rd_set);
  372. - FD_SET(cptr->sock, except_set);
  373. + /* ... and set all the client's sockets too */
  374. + cptr = client_list->next;
  375. + while(cptr) {
  376. + if(cptr->type == CLIENT_UNIX) {
  377. + FD_SET(cptr->sock, rd_set);
  378. + FD_SET(cptr->sock, except_set);
  379.  
  380. - if(cptr->sock > max_fd) {
  381. - max_fd = cptr->sock;
  382. - }
  383. - }
  384. - cptr = cptr->next;
  385. - }
  386. - }
  387. + if(cptr->sock > max_fd) {
  388. + max_fd = cptr->sock;
  389. + }
  390. + }
  391. + cptr = cptr->next;
  392. + }
  393. + }
  394.  
  395. - /* also if we have an X11 connection, select that as well */
  396. + /* also if we have an X11 connection, select that as well */
  397. #ifdef USE_X11
  398. - if(dpy) {
  399. - xcon = ConnectionNumber(dpy);
  400. - FD_SET(xcon, rd_set);
  401. - FD_SET(xcon, except_set);
  402. -
  403. - if(xcon > max_fd) {
  404. - max_fd = xcon;
  405. - }
  406. - }
  407. + if(dpy) {
  408. + xcon = ConnectionNumber(dpy);
  409. + FD_SET(xcon, rd_set);
  410. + FD_SET(xcon, except_set);
  411. +
  412. + if(xcon > max_fd) {
  413. + max_fd = xcon;
  414. + }
  415. + }
  416. #endif
  417.  
  418. - /* wait indefinitely */
  419. - do {
  420. - ret = select(max_fd + 1, rd_set, 0, except_set, 0);
  421. - } while(ret == -1 && errno == EINTR);
  422. + /* wait indefinitely */
  423. + do {
  424. + ret = select(max_fd + 1, rd_set, 0, except_set, 0);
  425. + } while(ret == -1 && errno == EINTR);
  426.  
  427. - return ret;
  428. + return ret;
  429. }
  430.  
  431. +/* A function to react to button presses. */
  432. +void handle_button_event(int bid, int value)
  433. +{
  434. + if(value == 1) {
  435. + enum button_actions btn = NONE;
  436. + switch(bid) {
  437. + case 0:
  438. + btn = button0;
  439. + break;
  440. + case 1:
  441. + btn = button1;
  442. + break;
  443. + }
  444. + switch (btn) {
  445. + case LOCK_TRANSLATION:
  446. + lock_translate = !lock_translate;
  447. + break;
  448. + case LOCK_ROTATION:
  449. + lock_rotate = !lock_rotate;
  450. + break;
  451. + case SWITCH_LED:
  452. + led_changed = true;
  453. + use_led = !use_led;
  454. + break;
  455. + case NONE:
  456. + default:
  457. + break;
  458. + }
  459. + }
  460. +}
  461. +
  462. +/* Modify the values from the device according to current settings. */
  463. +int modify_rel_value(int idx, int orgvalue)
  464. +{
  465. + int val = orgvalue;
  466. + if(sensitivity != 1.0) {
  467. + val = (int)((float)orgvalue * sensitivity);
  468. + }
  469. +
  470. + if (lock_rotate) {
  471. + switch(idx){
  472. + case REL_RY:
  473. + case REL_RZ:
  474. + case REL_RX:
  475. + val = 0;
  476. + }
  477. + }
  478. + if (lock_translate) {
  479. + switch(idx){
  480. + case REL_Y:
  481. + case REL_Z:
  482. + case REL_X:
  483. + val = 0;
  484. + }
  485. + }
  486. +
  487. + if(inverts[idx]) {
  488. + val = -val;
  489. + }
  490. +
  491. + return val;
  492. +}
  493. +
  494. void handle_events(fd_set *rd_set, fd_set *except_set)
  495. {
  496. - int xcon, rdbytes = 0;
  497. - struct input_event inp;
  498. - static struct input_event prev_inp;
  499. - static int inp_events_pending;
  500. - struct client *cptr;
  501. + int xcon, rdbytes = 0;
  502. + struct input_event inp;
  503. + static struct input_event prev_inp;
  504. + static int inp_events_pending;
  505. + struct client *cptr;
  506.  
  507. - if(lsock) {
  508. - if(FD_ISSET(lsock, rd_set)) {
  509. - /* got incoming connection */
  510. - int s;
  511. + if(lsock) {
  512. + if(FD_ISSET(lsock, rd_set)) {
  513. + /* got incoming connection */
  514. + int s;
  515.  
  516. - if((s = accept(lsock, 0, 0)) == -1) {
  517. - perror("error while accepting connection");
  518. - } else {
  519. - if(add_client(CLIENT_UNIX, &s) == -1) {
  520. - perror("failed to add client");
  521. - }
  522. - }
  523. - }
  524. + if((s = accept(lsock, 0, 0)) == -1) {
  525. + perror("error while accepting connection");
  526. + } else {
  527. + if(add_client(CLIENT_UNIX, &s) == -1) {
  528. + perror("failed to add client");
  529. + }
  530. + }
  531. + }
  532.  
  533. - /* check all UNIX clients */
  534. - cptr = client_list;
  535. - while(cptr->next) {
  536. - struct client *client = cptr->next;
  537. + /* check all UNIX clients */
  538. + cptr = client_list;
  539. + while(cptr->next) {
  540. + struct client *client = cptr->next;
  541.  
  542. - if(client->type == CLIENT_UNIX) {
  543. - if(FD_ISSET(client->sock, rd_set)) {
  544. - /* Got data from a client. Currently the only thing the client may set
  545. - * is sensitivity. So get it directly.
  546. - */
  547. - while((rdbytes = read(client->sock, &client->sens, sizeof client->sens)) <= 0 && errno == EINTR);
  548. - if(rdbytes <= 0) { /* something went wrong... disconnect client */
  549. - cptr->next = client->next;
  550. - close(client->sock);
  551. - free(client);
  552. - }
  553. - }
  554. + if(client->type == CLIENT_UNIX) {
  555. + if(FD_ISSET(client->sock, rd_set)) {
  556. + /* Got data from a client. Currently the only thing the client may set
  557. + * is sensitivity. So get it directly.
  558. + */
  559. + while((rdbytes = read(client->sock, &client->sens, sizeof client->sens)) <= 0 && errno == EINTR);
  560. + if(rdbytes <= 0) { /* something went wrong... disconnect client */
  561. + cptr->next = client->next;
  562. + close(client->sock);
  563. + free(client);
  564. + }
  565. + }
  566.  
  567. - if(FD_ISSET(client->sock, except_set)) {
  568. - /* got an exception on that socket, disconnect... */
  569. - cptr->next = client->next;
  570. - close(client->sock);
  571. - free(client);
  572. - }
  573. - }
  574. - cptr = cptr->next;
  575. - }
  576. - }
  577. + if(FD_ISSET(client->sock, except_set)) {
  578. + /* got an exception on that socket, disconnect... */
  579. + cptr->next = client->next;
  580. + close(client->sock);
  581. + free(client);
  582. + }
  583. + }
  584. + cptr = cptr->next;
  585. + }
  586. + }
  587.  
  588. #ifdef USE_X11
  589. - xcon = ConnectionNumber(dpy);
  590. + xcon = ConnectionNumber(dpy);
  591.  
  592. - /* process any pending X events */
  593. - if(dpy && FD_ISSET(xcon, rd_set)) {
  594. - while(XPending(dpy)) {
  595. - XEvent xev;
  596. - XNextEvent(dpy, &xev);
  597. + /* process any pending X events */
  598. + if(dpy && FD_ISSET(xcon, rd_set)) {
  599. + while(XPending(dpy)) {
  600. + XEvent xev;
  601. + XNextEvent(dpy, &xev);
  602.  
  603. - if(xev.type == ClientMessage && xev.xclient.message_type == event_cmd) {
  604. - unsigned int win_id;
  605. + if(xev.type == ClientMessage && xev.xclient.message_type == event_cmd) {
  606. + unsigned int win_id;
  607.  
  608. - switch(xev.xclient.data.s[2]) {
  609. - case CMD_APP_WINDOW:
  610. - win_id = xev.xclient.data.s[1];
  611. - win_id |= (unsigned int)xev.xclient.data.s[0] << 16;
  612. + switch(xev.xclient.data.s[2]) {
  613. + case CMD_APP_WINDOW:
  614. + win_id = xev.xclient.data.s[1];
  615. + win_id |= (unsigned int)xev.xclient.data.s[0] << 16;
  616.  
  617. - set_client_window((Window)win_id);
  618. - break;
  619. + set_client_window((Window)win_id);
  620. + break;
  621.  
  622. - case CMD_APP_SENS:
  623. - x11_sens = *(float*)xev.xclient.data.s; /* see decl of x11_sens for details */
  624. - break;
  625. + case CMD_APP_SENS:
  626. + x11_sens = *(float*)xev.xclient.data.s; /* see decl of x11_sens for details */
  627. + break;
  628.  
  629. - default:
  630. - break;
  631. - }
  632. - }
  633. - }
  634. - }
  635. + default:
  636. + break;
  637. + }
  638. + }
  639. + }
  640. + }
  641.  
  642. - /* detect errors in the X11 connection */
  643. - if(dpy && FD_ISSET(xcon, except_set)) {
  644. - fprintf(stderr, "X11 socket exception?\n");
  645. - close_x11();
  646. - dpy = 0;
  647. - }
  648. + /* detect errors in the X11 connection */
  649. + if(dpy && FD_ISSET(xcon, except_set)) {
  650. + fprintf(stderr, "X11 socket exception?\n");
  651. + close_x11();
  652. + dpy = 0;
  653. + }
  654. #endif
  655.  
  656. - /* read any pending data from the device */
  657. - if(FD_ISSET(dev_fd, rd_set)) {
  658. - do {
  659. - rdbytes = read(dev_fd, &inp, sizeof inp);
  660. - } while(rdbytes == -1 && errno == EINTR);
  661. - }
  662. + /* read any pending data from the device */
  663. + if(FD_ISSET(dev_fd, rd_set)) {
  664. + do {
  665. + rdbytes = read(dev_fd, &inp, sizeof inp);
  666. + } while(rdbytes == -1 && errno == EINTR);
  667. + }
  668.  
  669. - /* and detect exceptions on the device (disconnect?) */
  670. - if(FD_ISSET(dev_fd, except_set) || rdbytes == -1) {
  671. - perror("read error");
  672. - close(dev_fd);
  673. - dev_fd = -1;
  674. - }
  675. + /* and detect exceptions on the device (disconnect?) */
  676. + if(FD_ISSET(dev_fd, except_set) || rdbytes == -1) {
  677. + perror("read error");
  678. + close(dev_fd);
  679. + dev_fd = -1;
  680. + }
  681.  
  682. - /* if we actually got an event, update our state, and send the appropriate events to all clients */
  683. - if(rdbytes > 0) {
  684. - int val;
  685. - int idx, sign = -1;
  686. + /* if we actually got an event, update our state, and send the appropriate events to all clients */
  687. + if(rdbytes > 0) {
  688. + int val;
  689. + int idx, sign = -1;
  690.  
  691. - switch(inp.type) {
  692. - case EV_REL:
  693. - if(abs(inp.value) < dead_threshold) {
  694. - break;
  695. - }
  696. + switch(inp.type) {
  697. + case EV_REL:
  698. + if ((lock_rotate)&&(lock_translate)) {
  699. + break;
  700. + }
  701.  
  702. - idx = inp.code - REL_X;
  703. - val = inp.value;
  704. - if(sensitivity != 1.0) {
  705. - val = (int)((float)inp.value * sensitivity);
  706. - }
  707. + if(abs(inp.value) < dead_threshold) {
  708. + break;
  709. + }
  710.  
  711. - switch(idx) {
  712. - case REL_RY:
  713. - idx = REL_RZ; break;
  714. - case REL_RZ:
  715. - idx = REL_RY; break;
  716. - case REL_Y:
  717. - idx = REL_Z; break;
  718. - case REL_Z:
  719. - idx = REL_Y; break;
  720. - default:
  721. - sign = 1;
  722. - break;
  723. - }
  724. + idx = inp.code - REL_X;
  725. + val = modify_rel_value(idx, inp.value);
  726.  
  727. - evrel[idx] = sign * val;
  728. - prev_inp = inp;
  729. - inp_events_pending = 1;
  730. - break;
  731. + switch(idx) {
  732. + case REL_RY:
  733. + idx = REL_RZ; break;
  734. + case REL_RZ:
  735. + idx = REL_RY; break;
  736. + case REL_Y:
  737. + idx = REL_Z; break;
  738. + case REL_Z:
  739. + idx = REL_Y; break;
  740. + default:
  741. + sign = 1;
  742. + break;
  743. + }
  744.  
  745. - case EV_KEY:
  746. - idx = inp.code - BTN_0;
  747. - evbut[idx] = inp.value;
  748. - prev_inp = inp;
  749. - inp_events_pending = 1;
  750. - break;
  751. + evrel[idx] = sign * val;
  752. + prev_inp = inp;
  753. + inp_events_pending = 1;
  754. + break;
  755.  
  756. - case EV_SYN:
  757. - if(inp_events_pending) {
  758. - inp_events_pending = 0;
  759. + case EV_KEY:
  760. + idx = inp.code - BTN_0;
  761. + handle_button_event(idx, inp.value);
  762. + evbut[idx] = inp.value;
  763. + prev_inp = inp;
  764. + inp_events_pending = 1;
  765. + break;
  766.  
  767. - send_uevent(&prev_inp);
  768. + case EV_SYN:
  769. + if(inp_events_pending) {
  770. + inp_events_pending = 0;
  771. +
  772. + send_uevent(&prev_inp);
  773. #ifdef USE_X11
  774. - /* if we are connected to an X server, send the appropriate X event */
  775. - send_xevent(&prev_inp);
  776. + /* if we are connected to an X server, send the appropriate X event */
  777. + send_xevent(&prev_inp);
  778. #endif/* USE_X11 */
  779. - }
  780. - break;
  781. + }
  782. + break;
  783.  
  784. - default:
  785. - break;
  786. - }
  787. + default:
  788. + break;
  789. + }
  790.  
  791. - }
  792. + }
  793.  
  794. }
  795.  
  796. int add_client(int type, void *cdata)
  797. {
  798. - struct client *client;
  799. + struct client *client;
  800.  
  801. #ifdef USE_X11
  802. - if(!cdata || (type != CLIENT_UNIX && type != CLIENT_X11))
  803. + if(!cdata || (type != CLIENT_UNIX && type != CLIENT_X11))
  804. #else
  805. - if(!cdata || type != CLIENT_UNIX)
  806. + if(!cdata || type != CLIENT_UNIX)
  807. #endif
  808. - {
  809. - return -1;
  810. - }
  811. + {
  812. + return -1;
  813. + }
  814.  
  815. - if(!(client = malloc(sizeof *client))) {
  816. - return -1;
  817. - }
  818. + if(!(client = malloc(sizeof *client))) {
  819. + return -1;
  820. + }
  821.  
  822. - client->type = type;
  823. - if(type == CLIENT_UNIX) {
  824. - client->sock = *(int*)cdata;
  825. + client->type = type;
  826. + if(type == CLIENT_UNIX) {
  827. + client->sock = *(int*)cdata;
  828. #ifdef USE_X11
  829. - } else {
  830. - client->win = *(Window*)cdata;
  831. + } else {
  832. + client->win = *(Window*)cdata;
  833. #endif
  834. - }
  835. + }
  836.  
  837. - client->sens = 1.0f;
  838. - client->next = client_list->next;
  839. - client_list->next = client;
  840. + client->sens = 1.0f;
  841. + client->next = client_list->next;
  842. + client_list->next = client;
  843.  
  844. - return 0;
  845. + return 0;
  846. }
  847.  
  848. int init_dev(void)
  849. {
  850. - char *dev_path;
  851. + char *dev_path;
  852.  
  853. - if(!(dev_path = get_dev_path())) {
  854. - fprintf(stderr, "failed to find the spaceball device file\n");
  855. - return -1;
  856. - }
  857. - printf("using device: %s\n", dev_path);
  858. + if(!(dev_path = get_dev_path())) {
  859. + fprintf(stderr, "failed to find the spaceball device file\n");
  860. + return -1;
  861. + }
  862. + printf("using device: %s\n", dev_path);
  863.  
  864. - if(open_dev(dev_path) == -1) {
  865. - return -1;
  866. - }
  867. - printf("device name: %s\n", dev_name);
  868. + if(open_dev(dev_path) == -1) {
  869. + return -1;
  870. + }
  871. + printf("device name: %s\n", dev_name);
  872.  
  873. - return 0;
  874. + return 0;
  875. }
  876.  
  877. -#define SOCK_NAME "/tmp/spacenav_usock"
  878. +#define SOCK_NAME "/tmp/spacenav_usock"
  879. int init_unix(void)
  880. {
  881. - int s;
  882. - mode_t prev_umask;
  883. - struct sockaddr_un addr;
  884. + int s;
  885. + mode_t prev_umask;
  886. + struct sockaddr_un addr;
  887.  
  888. - if(lsock) return 0;
  889. + if(lsock) return 0;
  890.  
  891. - if((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
  892. - perror("failed to create socket");
  893. - return -1;
  894. - }
  895. + if((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
  896. + perror("failed to create socket");
  897. + return -1;
  898. + }
  899.  
  900. - unlink(SOCK_NAME); /* in case it already exists */
  901. + unlink(SOCK_NAME); /* in case it already exists */
  902.  
  903. - memset(&addr, 0, sizeof addr);
  904. - addr.sun_family = AF_UNIX;
  905. - strcpy(addr.sun_path, SOCK_NAME);
  906. + memset(&addr, 0, sizeof addr);
  907. + addr.sun_family = AF_UNIX;
  908. + strcpy(addr.sun_path, SOCK_NAME);
  909.  
  910. - prev_umask = umask(0);
  911. + prev_umask = umask(0);
  912.  
  913. - if(bind(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
  914. - fprintf(stderr, "failed to bind unix socket: %s: %s\n", SOCK_NAME, strerror(errno));
  915. - return -1;
  916. - }
  917. + if(bind(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
  918. + fprintf(stderr, "failed to bind unix socket: %s: %s\n", SOCK_NAME, strerror(errno));
  919. + return -1;
  920. + }
  921.  
  922. - umask(prev_umask);
  923. + umask(prev_umask);
  924.  
  925. - if(listen(s, 8) == -1) {
  926. - perror("listen failed");
  927. - return -1;
  928. - }
  929. + if(listen(s, 8) == -1) {
  930. + perror("listen failed");
  931. + return -1;
  932. + }
  933.  
  934. - lsock = s;
  935. - return 0;
  936. + lsock = s;
  937. + return 0;
  938. }
  939.  
  940.  
  941. enum {
  942. - UEV_TYPE_MOTION,
  943. - UEV_TYPE_PRESS,
  944. - UEV_TYPE_RELEASE
  945. + UEV_TYPE_MOTION,
  946. + UEV_TYPE_PRESS,
  947. + UEV_TYPE_RELEASE
  948. };
  949.  
  950. /* send an event to all UNIX clients */
  951. void send_uevent(struct input_event *inp)
  952. {
  953. - static struct timeval prev_motion_time;
  954. - struct client *citer;
  955. - int i, data[8];
  956. - unsigned int period;
  957. + static struct timeval prev_motion_time;
  958. + struct client *citer;
  959. + int i, data[8];
  960. + unsigned int period;
  961.  
  962. - if(!lsock) return;
  963. + if(!lsock) return;
  964.  
  965. - if(inp->type == EV_REL) {
  966. - period = msec_dif(inp->time, prev_motion_time);
  967. - prev_motion_time = inp->time;
  968. - }
  969. + if(inp->type == EV_REL) {
  970. + period = msec_dif(inp->time, prev_motion_time);
  971. + prev_motion_time = inp->time;
  972. + }
  973.  
  974. - citer = client_list->next;
  975. - while(citer) {
  976. - if(citer->type == CLIENT_UNIX) {
  977. - float motion_mul;
  978. + citer = client_list->next;
  979. + while(citer) {
  980. + if(citer->type == CLIENT_UNIX) {
  981. + float motion_mul;
  982.  
  983. - switch(inp->type) {
  984. - case EV_REL:
  985. - data[0] = UEV_TYPE_MOTION;
  986. + switch(inp->type) {
  987. + case EV_REL:
  988. + data[0] = UEV_TYPE_MOTION;
  989.  
  990. - motion_mul = citer->sens * sensitivity;
  991. - for(i=0; i<6; i++) {
  992. - float val = (float)evrel[i] * motion_mul;
  993. - data[i + 1] = (int)val;
  994. - }
  995. - data[7] = period;
  996. - break;
  997. + motion_mul = citer->sens * sensitivity;
  998. + for(i=0; i<6; i++) {
  999. + float val = (float)evrel[i] * motion_mul;
  1000. + data[i + 1] = (int)val;
  1001. + }
  1002. + data[7] = period;
  1003. + break;
  1004.  
  1005. - case EV_KEY:
  1006. - data[0] = inp->value ? UEV_TYPE_PRESS : UEV_TYPE_RELEASE;
  1007. - data[1] = inp->code - BTN_0;
  1008. - break;
  1009. + case EV_KEY:
  1010. + data[0] = inp->value ? UEV_TYPE_PRESS : UEV_TYPE_RELEASE;
  1011. + data[1] = inp->code - BTN_0;
  1012. + break;
  1013.  
  1014. - default:
  1015. - fprintf(stderr, "BUG! this shouldn't happen\n");
  1016. - exit(1);
  1017. - }
  1018. + default:
  1019. + fprintf(stderr, "BUG! this shouldn't happen\n");
  1020. + exit(1);
  1021. + }
  1022.  
  1023. - while(write(citer->sock, data, sizeof data) == -1 && errno == EINTR);
  1024. - }
  1025. - citer = citer->next;
  1026. - }
  1027. + while(write(citer->sock, data, sizeof data) == -1 && errno == EINTR);
  1028. + }
  1029. + citer = citer->next;
  1030. + }
  1031. }
  1032.  
  1033.  
  1034. #ifdef USE_X11
  1035. int init_x11(void)
  1036. {
  1037. - int i, screen, scr_count;
  1038. - Window root;
  1039. - XSetWindowAttributes xattr;
  1040. - Atom wm_delete, cmd_type;
  1041. - XTextProperty tp_wname;
  1042. - XClassHint class_hint;
  1043. - char *win_title = "Magellan Window";
  1044. + int i, screen, scr_count;
  1045. + Window root;
  1046. + XSetWindowAttributes xattr;
  1047. + Atom wm_delete, cmd_type;
  1048. + XTextProperty tp_wname;
  1049. + XClassHint class_hint;
  1050. + char *win_title = "Magellan Window";
  1051.  
  1052. - if(dpy) return 0;
  1053. + if(dpy) return 0;
  1054.  
  1055. - if(!(dpy = XOpenDisplay(":0"))) {
  1056. - fprintf(stderr, "failed to open X11 display: \":0\"\n");
  1057. - return -1;
  1058. - }
  1059. - scr_count = ScreenCount(dpy);
  1060. - screen = DefaultScreen(dpy);
  1061. - root = RootWindow(dpy, screen);
  1062. + if(!(dpy = XOpenDisplay(":0"))) {
  1063. + fprintf(stderr, "failed to open X11 display: \":0\"\n");
  1064. + return -1;
  1065. + }
  1066. + scr_count = ScreenCount(dpy);
  1067. + screen = DefaultScreen(dpy);
  1068. + root = RootWindow(dpy, screen);
  1069.  
  1070. - /* intern the various atoms used for communicating with the magellan clients */
  1071. - event_motion = XInternAtom(dpy, "MotionEvent", False);
  1072. - event_bpress = XInternAtom(dpy, "ButtonPressEvent", False);
  1073. - event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False);
  1074. - event_cmd = XInternAtom(dpy, "CommandEvent", False);
  1075. + /* intern the various atoms used for communicating with the magellan clients */
  1076. + event_motion = XInternAtom(dpy, "MotionEvent", False);
  1077. + event_bpress = XInternAtom(dpy, "ButtonPressEvent", False);
  1078. + event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False);
  1079. + event_cmd = XInternAtom(dpy, "CommandEvent", False);
  1080.  
  1081. - /* Create a dummy window, so that clients are able to send us events
  1082. - * through the magellan API. No need to map the window.
  1083. - */
  1084. - xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen);
  1085. - xattr.colormap = DefaultColormap(dpy, screen);
  1086. + /* Create a dummy window, so that clients are able to send us events
  1087. + * through the magellan API. No need to map the window.
  1088. + */
  1089. + xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen);
  1090. + xattr.colormap = DefaultColormap(dpy, screen);
  1091.  
  1092. - win = XCreateWindow(dpy, root, 0, 0, 10, 10, 0, CopyFromParent, InputOutput,
  1093. - DefaultVisual(dpy, screen), CWColormap | CWBackPixel | CWBorderPixel, &xattr);
  1094. + win = XCreateWindow(dpy, root, 0, 0, 10, 10, 0, CopyFromParent, InputOutput,
  1095. + DefaultVisual(dpy, screen), CWColormap | CWBackPixel | CWBorderPixel, &xattr);
  1096.  
  1097. - wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1098. - XSetWMProtocols(dpy, win, &wm_delete, 1);
  1099. + wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  1100. + XSetWMProtocols(dpy, win, &wm_delete, 1);
  1101.  
  1102. - XStringListToTextProperty(&win_title, 1, &tp_wname);
  1103. - XSetWMName(dpy, win, &tp_wname);
  1104. - XFree(tp_wname.value);
  1105. + XStringListToTextProperty(&win_title, 1, &tp_wname);
  1106. + XSetWMName(dpy, win, &tp_wname);
  1107. + XFree(tp_wname.value);
  1108.  
  1109. - class_hint.res_name = "magellan";
  1110. - class_hint.res_class = "magellan_win";
  1111. - XSetClassHint(dpy, win, &class_hint);
  1112. + class_hint.res_name = "magellan";
  1113. + class_hint.res_class = "magellan_win";
  1114. + XSetClassHint(dpy, win, &class_hint);
  1115.  
  1116. - /* I believe this is a bit hackish, but the magellan API expects to find the CommandEvent
  1117. - * property on the root window, containing our window id.
  1118. - * The API doesn't look for a specific property type, so I made one up here (MagellanCmdType).
  1119. - */
  1120. - cmd_type = XInternAtom(dpy, "MagellanCmdType", False);
  1121. - for(i=0; i<scr_count; i++) {
  1122. - Window root = RootWindow(dpy, i);
  1123. - XChangeProperty(dpy, root, event_cmd, cmd_type, 32, PropModeReplace, (unsigned char*)&win, 1);
  1124. - }
  1125. - XFlush(dpy);
  1126. + /* I believe this is a bit hackish, but the magellan API expects to find the CommandEvent
  1127. + * property on the root window, containing our window id.
  1128. + * The API doesn't look for a specific property type, so I made one up here (MagellanCmdType).
  1129. + */
  1130. + cmd_type = XInternAtom(dpy, "MagellanCmdType", False);
  1131. + for(i=0; i<scr_count; i++) {
  1132. + Window root = RootWindow(dpy, i);
  1133. + XChangeProperty(dpy, root, event_cmd, cmd_type, 32, PropModeReplace, (unsigned char*)&win, 1);
  1134. + }
  1135. + XFlush(dpy);
  1136.  
  1137. - return 0;
  1138. + return 0;
  1139. }
  1140.  
  1141. void close_x11(void)
  1142. {
  1143. - int i, scr_count;
  1144. + int i, scr_count;
  1145.  
  1146. - if(!dpy) return;
  1147. + if(!dpy) return;
  1148.  
  1149. - /* first delete all the CommandEvent properties from all root windows */
  1150. - scr_count = ScreenCount(dpy);
  1151. - for(i=0; i<scr_count; i++) {
  1152. - Window root = RootWindow(dpy, i);
  1153. - XDeleteProperty(dpy, root, event_cmd);
  1154. - }
  1155. + /* first delete all the CommandEvent properties from all root windows */
  1156. + scr_count = ScreenCount(dpy);
  1157. + for(i=0; i<scr_count; i++) {
  1158. + Window root = RootWindow(dpy, i);
  1159. + XDeleteProperty(dpy, root, event_cmd);
  1160. + }
  1161.  
  1162. - XDestroyWindow(dpy, win);
  1163. - XCloseDisplay(dpy);
  1164. - dpy = 0;
  1165. + XDestroyWindow(dpy, win);
  1166. + XCloseDisplay(dpy);
  1167. + dpy = 0;
  1168. }
  1169.  
  1170. void send_xevent(struct input_event *inp)
  1171. {
  1172. - static struct timeval prev_motion_time;
  1173. - struct client *citer;
  1174. - int (*prev_xerr_handler)(Display*, XErrorEvent*);
  1175. - int i;
  1176. - XEvent xevent;
  1177. - unsigned int period;
  1178. + static struct timeval prev_motion_time;
  1179. + struct client *citer;
  1180. + int (*prev_xerr_handler)(Display*, XErrorEvent*);
  1181. + int i;
  1182. + XEvent xevent;
  1183. + unsigned int period;
  1184.  
  1185. - if(!dpy) return;
  1186. + if(!dpy) return;
  1187.  
  1188. - if(inp->type == EV_REL) {
  1189. - period = msec_dif(inp->time, prev_motion_time);
  1190. - prev_motion_time = inp->time;
  1191. - }
  1192. + if(inp->type == EV_REL) {
  1193. + period = msec_dif(inp->time, prev_motion_time);
  1194. + prev_motion_time = inp->time;
  1195. + }
  1196.  
  1197. - /* We can get a BadWindow exception, if any of the registered clients exit
  1198. - * without notice. Thus we must install a custom handler to avoid crashing
  1199. - * the daemon when that happens. Also catch_badwin (see below) removes that
  1200. - * client from the list, to avoid perpetually trying to send events to an
  1201. - * invalid window.
  1202. - */
  1203. - prev_xerr_handler = XSetErrorHandler(catch_badwin);
  1204. + /* We can get a BadWindow exception, if any of the registered clients exit
  1205. + * without notice. Thus we must install a custom handler to avoid crashing
  1206. + * the daemon when that happens. Also catch_badwin (see below) removes that
  1207. + * client from the list, to avoid perpetually trying to send events to an
  1208. + * invalid window.
  1209. + */
  1210. + prev_xerr_handler = XSetErrorHandler(catch_badwin);
  1211.  
  1212. - xevent.type = ClientMessage;
  1213. - xevent.xclient.send_event = False;
  1214. - xevent.xclient.display = dpy;
  1215. + xevent.type = ClientMessage;
  1216. + xevent.xclient.send_event = False;
  1217. + xevent.xclient.display = dpy;
  1218.  
  1219. - citer = client_list->next;
  1220. - while(citer) {
  1221. - if(citer->type != CLIENT_X11) {
  1222. - citer = citer->next;
  1223. - continue;
  1224. - }
  1225. + citer = client_list->next;
  1226. + while(citer) {
  1227. + if(citer->type != CLIENT_X11) {
  1228. + citer = citer->next;
  1229. + continue;
  1230. + }
  1231.  
  1232. - xevent.xclient.window = citer->win;
  1233. + xevent.xclient.window = citer->win;
  1234.  
  1235. - switch(inp->type) {
  1236. - case EV_REL:
  1237. - xevent.xclient.message_type = event_motion;
  1238. - xevent.xclient.format = 16;
  1239. + switch(inp->type) {
  1240. + case EV_REL:
  1241. + xevent.xclient.message_type = event_motion;
  1242. + xevent.xclient.format = 16;
  1243.  
  1244. - for(i=0; i<6; i++) {
  1245. - float val = (float)evrel[i] * x11_sens * sensitivity;
  1246. - xevent.xclient.data.s[i + 2] = (short)val;
  1247. - }
  1248. - xevent.xclient.data.s[0] = xevent.xclient.data.s[1] = 0;
  1249. - xevent.xclient.data.s[8] = period;
  1250. - break;
  1251. + if(rotate_translation[3] != 0.0) {
  1252. + float *newxyz;
  1253. + newxyz = rotate_around(
  1254. + evrel[REL_X],
  1255. + evrel[REL_Y],
  1256. + evrel[REL_Z],
  1257. + rotate_translation[0],
  1258. + rotate_translation[1],
  1259. + rotate_translation[2],
  1260. + rotate_translation[3]);
  1261. + evrel[REL_X] = newxyz[0];
  1262. + evrel[REL_Y] = newxyz[1];
  1263. + evrel[REL_Z] = newxyz[2];
  1264. + }
  1265.  
  1266. - case EV_KEY:
  1267. - xevent.xclient.message_type = inp->value ? event_bpress : event_brelease;
  1268. - xevent.xclient.format = 16;
  1269. - xevent.xclient.data.s[2] = inp->code - BTN_0;
  1270. - break;
  1271. + for(i=0; i<6; i++) {
  1272. + float val = (float)evrel[i] * x11_sens * sensitivity;
  1273. + xevent.xclient.data.s[i + 2] = (short)val;
  1274. + }
  1275. + xevent.xclient.data.s[0] = xevent.xclient.data.s[1] = 0;
  1276. + xevent.xclient.data.s[8] = period;
  1277. + break;
  1278.  
  1279. - default:
  1280. - fprintf(stderr, "BUG! this shouldn't happen\n");
  1281. - exit(1);
  1282. - }
  1283. + case EV_KEY:
  1284. + xevent.xclient.message_type = inp->value ? event_bpress : event_brelease;
  1285. + xevent.xclient.format = 16;
  1286. + xevent.xclient.data.s[2] = inp->code - BTN_0;
  1287. + break;
  1288.  
  1289. - XSendEvent(dpy, citer->win, False, 0, &xevent);
  1290. - citer = citer->next;
  1291. - }
  1292. + default:
  1293. + fprintf(stderr, "BUG! this shouldn't happen\n");
  1294. + exit(1);
  1295. + }
  1296.  
  1297. - XSync(dpy, False);
  1298. - XSetErrorHandler(prev_xerr_handler);
  1299. + XSendEvent(dpy, citer->win, False, 0, &xevent);
  1300. + citer = citer->next;
  1301. + }
  1302. +
  1303. + XSync(dpy, False);
  1304. + XSetErrorHandler(prev_xerr_handler);
  1305. }
  1306.  
  1307. /* X11 error handler for bad-windows */
  1308. int catch_badwin(Display *dpy, XErrorEvent *err)
  1309. {
  1310. - char buf[256];
  1311. + char buf[256];
  1312.  
  1313. - if(err->error_code == BadWindow) {
  1314. - remove_client_window((Window)err->resourceid);
  1315. - } else {
  1316. - XGetErrorText(dpy, err->error_code, buf, sizeof buf);
  1317. - fprintf(stderr, "Caught unexpected X error: %s\n", buf);
  1318. - }
  1319. - return 0;
  1320. + if(err->error_code == BadWindow) {
  1321. + remove_client_window((Window)err->resourceid);
  1322. + } else {
  1323. + XGetErrorText(dpy, err->error_code, buf, sizeof buf);
  1324. + fprintf(stderr, "Caught unexpected X error: %s\n", buf);
  1325. + }
  1326. + return 0;
  1327. }
  1328.  
  1329.  
  1330. /* adds a new X11 client to the list, IF it does not already exist */
  1331. void set_client_window(Window win)
  1332. {
  1333. - int i, scr_count;
  1334. - struct client *cnode;
  1335. + int i, scr_count;
  1336. + struct client *cnode;
  1337.  
  1338. - /* When a magellan application exits, the SDK sets another window to avoid
  1339. - * crashing the original proprietary daemon. The new free SDK will set
  1340. - * consistently the root window for that purpose, which we can ignore here
  1341. - * easily.
  1342. - */
  1343. - scr_count = ScreenCount(dpy);
  1344. - for(i=0; i<scr_count; i++) {
  1345. - if(win == RootWindow(dpy, i)) {
  1346. - return;
  1347. - }
  1348. - }
  1349. + /* When a magellan application exits, the SDK sets another window to avoid
  1350. + * crashing the original proprietary daemon. The new free SDK will set
  1351. + * consistently the root window for that purpose, which we can ignore here
  1352. + * easily.
  1353. + */
  1354. + scr_count = ScreenCount(dpy);
  1355. + for(i=0; i<scr_count; i++) {
  1356. + if(win == RootWindow(dpy, i)) {
  1357. + return;
  1358. + }
  1359. + }
  1360.  
  1361. - cnode = client_list->next;
  1362. - while(cnode) {
  1363. - if(cnode->win == win) {
  1364. - return;
  1365. - }
  1366. - cnode = cnode->next;
  1367. - }
  1368. + cnode = client_list->next;
  1369. + while(cnode) {
  1370. + if(cnode->win == win) {
  1371. + return;
  1372. + }
  1373. + cnode = cnode->next;
  1374. + }
  1375.  
  1376. - add_client(CLIENT_X11, &win);
  1377. + add_client(CLIENT_X11, &win);
  1378. }
  1379.  
  1380. void remove_client_window(Window win)
  1381. {
  1382. - struct client *cnode, *tmp;
  1383. + struct client *cnode, *tmp;
  1384.  
  1385. - cnode = client_list;
  1386. - while(cnode->next) {
  1387. - if(cnode->next->win == win) {
  1388. - tmp = cnode->next;
  1389. - cnode->next = tmp->next;
  1390. - free(tmp);
  1391. - return;
  1392. - }
  1393. - cnode = cnode->next;
  1394. - }
  1395. + cnode = client_list;
  1396. + while(cnode->next) {
  1397. + if(cnode->next->win == win) {
  1398. + tmp = cnode->next;
  1399. + cnode->next = tmp->next;
  1400. + free(tmp);
  1401. + return;
  1402. + }
  1403. + cnode = cnode->next;
  1404. + }
  1405. }
  1406. #endif
  1407.  
  1408. int open_dev(const char *path)
  1409. {
  1410. - if((dev_fd = open(path, O_RDWR)) == -1) {
  1411. - if((dev_fd = open(path, O_RDONLY)) == -1) {
  1412. - perror("failed to open device");
  1413. - return -1;
  1414. - }
  1415. - fprintf(stderr, "opened device read-only, LEDs won't work\n");
  1416. - }
  1417. + if((dev_fd = open(path, O_RDWR)) == -1) {
  1418. + if((dev_fd = open(path, O_RDONLY)) == -1) {
  1419. + perror("failed to open device");
  1420. + return -1;
  1421. + }
  1422. + fprintf(stderr, "opened device read-only, LEDs won't work\n");
  1423. + }
  1424.  
  1425. - if(ioctl(dev_fd, EVIOCGNAME(sizeof(dev_name)), dev_name) == -1) {
  1426. - perror("EVIOCGNAME ioctl failed\n");
  1427. - return -1;
  1428. - }
  1429. + if(ioctl(dev_fd, EVIOCGNAME(sizeof(dev_name)), dev_name) == -1) {
  1430. + perror("EVIOCGNAME ioctl failed\n");
  1431. + return -1;
  1432. + }
  1433.  
  1434. - if(ioctl(dev_fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) {
  1435. - perror("EVIOCGBIT ioctl failed\n");
  1436. - return -1;
  1437. - }
  1438. + if(ioctl(dev_fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) {
  1439. + perror("EVIOCGBIT ioctl failed\n");
  1440. + return -1;
  1441. + }
  1442.  
  1443. - if(!TEST_BIT(EV_REL, evtype_mask)) {
  1444. - fprintf(stderr, "Wrong device, no relative events reported!\n");
  1445. - return -1;
  1446. - }
  1447. - return 0;
  1448. + if(!TEST_BIT(EV_REL, evtype_mask)) {
  1449. + fprintf(stderr, "Wrong device, no relative events reported!\n");
  1450. + return -1;
  1451. + }
  1452. + return 0;
  1453. }
  1454.  
  1455.  
  1456. -#define PROC_DEV "/proc/bus/input/devices"
  1457. +#define PROC_DEV "/proc/bus/input/devices"
  1458. char *get_dev_path(void)
  1459. {
  1460. - static char path[128];
  1461. - int valid_vendor = 0, valid_str = 0;
  1462. - char buf[1024];
  1463. - FILE *fp;
  1464. + static char path[128];
  1465. + int valid_vendor = 0, valid_str = 0;
  1466. + char buf[1024];
  1467. + FILE *fp;
  1468.  
  1469. - if(!(fp = fopen(PROC_DEV, "r"))) {
  1470. - perror("failed to open " PROC_DEV ":");
  1471. - return 0;
  1472. - }
  1473. + if(!(fp = fopen(PROC_DEV, "r"))) {
  1474. + perror("failed to open " PROC_DEV ":");
  1475. + return 0;
  1476. + }
  1477.  
  1478. - while(fgets(buf, sizeof buf, fp)) {
  1479. - if(buf[0] == 'I') {
  1480. - valid_vendor = strstr(buf, "Vendor=046d") != 0;
  1481. - } else if(buf[0] == 'N') {
  1482. - valid_str = strstr(buf, "3Dconnexion") != 0;
  1483. - } else if(buf[0] == 'H' && valid_str && valid_vendor) {
  1484. - char *ptr, *start;
  1485. -
  1486. - if(!(start = strchr(buf, '='))) {
  1487. - continue;
  1488. - }
  1489. - start++;
  1490. + while(fgets(buf, sizeof buf, fp)) {
  1491. + if(buf[0] == 'I') {
  1492. + valid_vendor = strstr(buf, "Vendor=046d") != 0;
  1493. + } else if(buf[0] == 'N') {
  1494. + valid_str = strstr(buf, "3Dconnexion") != 0;
  1495. + } else if(buf[0] == 'H' && valid_str && valid_vendor) {
  1496. + char *ptr, *start;
  1497.  
  1498. - if((ptr = strchr(start, ' '))) {
  1499. - *ptr = 0;
  1500. - }
  1501. - if((ptr = strchr(start, '\n'))) {
  1502. - *ptr = 0;
  1503. - }
  1504. + if(!(start = strchr(buf, '='))) {
  1505. + continue;
  1506. + }
  1507. + start++;
  1508.  
  1509. - snprintf(path, sizeof(path), "/dev/input/%s", start);
  1510. - fclose(fp);
  1511. - return path;
  1512. - }
  1513. - }
  1514. + if((ptr = strchr(start, ' '))) {
  1515. + *ptr = 0;
  1516. + }
  1517. + if((ptr = strchr(start, '\n'))) {
  1518. + *ptr = 0;
  1519. + }
  1520.  
  1521. - fclose(fp);
  1522. - return 0;
  1523. + snprintf(path, sizeof(path), "/dev/input/%s", start);
  1524. + fclose(fp);
  1525. + return path;
  1526. + }
  1527. + }
  1528. +
  1529. + fclose(fp);
  1530. + return 0;
  1531. }
  1532.  
  1533.  
  1534. @@ -889,83 +1007,37 @@
  1535. */
  1536. void sig_handler(int s)
  1537. {
  1538. - switch(s) {
  1539. - case SIGHUP:
  1540. - init_dev();
  1541. - break;
  1542. + switch(s) {
  1543. + case SIGHUP:
  1544. + init_dev();
  1545. + break;
  1546.  
  1547. - case SIGINT:
  1548. - case SIGTERM:
  1549. - close_x11(); /* call to avoid leaving garbage in the X server's root windows */
  1550. - exit(0);
  1551. + case SIGINT:
  1552. + case SIGTERM:
  1553. + close_x11(); /* call to avoid leaving garbage in the X server's root windows */
  1554. + exit(0);
  1555.  
  1556. #ifdef USE_X11
  1557. - case SIGUSR1:
  1558. - init_x11();
  1559. - break;
  1560. + case SIGUSR1:
  1561. + init_x11();
  1562. + break;
  1563.  
  1564. - case SIGUSR2:
  1565. - close_x11();
  1566. - break;
  1567. + case SIGUSR2:
  1568. + close_x11();
  1569. + break;
  1570. #endif
  1571.  
  1572. - default:
  1573. - break;
  1574. - }
  1575. + default:
  1576. + break;
  1577. + }
  1578. }
  1579.  
  1580. unsigned int msec_dif(struct timeval tv1, struct timeval tv2)
  1581. {
  1582. - unsigned int ds, du;
  1583. + unsigned int ds, du;
  1584.  
  1585. - ds = tv2.tv_sec - tv1.tv_sec;
  1586. - du = tv2.tv_usec - tv1.tv_usec;
  1587. - return ds * 1000 + du / 1000;
  1588. + ds = tv2.tv_sec - tv1.tv_sec;
  1589. + du = tv2.tv_usec - tv1.tv_usec;
  1590. + return ds * 1000 + du / 1000;
  1591. }
  1592.  
  1593. -int read_cfg(const char *fname)
  1594. -{
  1595. - FILE *fp;
  1596. - char buf[512];
  1597. -
  1598. - if(!(fp = fopen(fname, "r"))) {
  1599. - fprintf(stderr, "failed to open config file %s: %s. using defaults.\n", fname, strerror(errno));
  1600. - return -1;
  1601. - }
  1602. -
  1603. - while(fgets(buf, sizeof buf, fp)) {
  1604. - char *key_str, *val_str, *line = buf;
  1605. - while(*line == ' ' || *line == '\t') line++;
  1606. -
  1607. - if(!*line || *line == '\n' || *line == '\r' || *line == '#') {
  1608. - continue;
  1609. - }
  1610. -
  1611. - if(!(key_str = strtok(line, " :=\n\t\r"))) {
  1612. - fprintf(stderr, "invalid config line: %s, skipping.\n", line);
  1613. - continue;
  1614. - }
  1615. - if(!(val_str = strtok(0, " :=\n\t\r"))) {
  1616. - fprintf(stderr, "missing value for config key: %s\n", key_str);
  1617. - continue;
  1618. - }
  1619. -
  1620. - if(!isdigit(val_str[0])) {
  1621. - fprintf(stderr, "invalid value (%s), for key: %s. expected a number.\n", val_str, key_str);
  1622. - continue;
  1623. - }
  1624. -
  1625. - if(strcmp(key_str, "dead-zone") == 0) {
  1626. - dead_threshold = atoi(val_str);
  1627. - printf("config: dead-zone = %d\n", dead_threshold);
  1628. - } else if(strcmp(key_str, "sensitivity") == 0) {
  1629. - sensitivity = atof(val_str);
  1630. - printf("config: sensitivity = %.3f\n", sensitivity);
  1631. - } else {
  1632. - fprintf(stderr, "unrecognized config option: %s\n", key_str);
  1633. - }
  1634. - }
  1635. -
  1636. - fclose(fp);
  1637. - return 0;
  1638. -}
  1639. Index: spacenavd/Makefile
  1640. ===================================================================
  1641. --- spacenavd/Makefile (revision 7)
  1642. +++ spacenavd/Makefile (working copy)
  1643. @@ -3,7 +3,7 @@
  1644.  
  1645. CC = gcc
  1646. CFLAGS = -pedantic -Wall -g -DUSE_X11
  1647. -LDFLAGS = -lX11
  1648. +LDFLAGS = -lX11 -lm
  1649.  
  1650. $(bin): $(obj)
  1651. $(CC) $(CFLAGS) -o $@ $(obj) $(LDFLAGS)
  1652.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement