freejoy.linux.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // freejoy.linux.c
  2. #include "freejoy.h"
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <pthread.h>
  7. #include <sys/ioctl.h>
  8. #include <linux/joystick.h>
  9. struct linuxjoy
  10. {
  11. pthread_t thread;
  12. int threadid;
  13. int open,fd,fp;
  14. char name[256];
  15. int buttoncount,axiscount;
  16. int button;
  17. float axis[16];
  18. };
  19. typedef struct linuxjoy linuxjoy;
  20. typedef struct js_event js_event;
  21. typedef struct sched_param sched_param;
  22. void *joythread(void *v)
  23. {
  24. linuxjoy *j;
  25. js_event js;
  26. int n,b;
  27. int policy;
  28. sched_param sched;
  29. pthread_getschedparam(pthread_self(),&policy,&sched);
  30. sched.sched_priority++;
  31. policy=SCHED_RR;
  32. pthread_setschedparam(pthread_self(),policy,&sched);
  33. j=(linuxjoy*)v;
  34. while (j->open)
  35. {
  36. b=sizeof(struct js_event)-j->fp;
  37. n=read(j->fd,&js,b);
  38. if (n<=0) break;
  39. if (n<b) {j->fp+=b;continue;}
  40. j->fp=0;
  41. switch (js.type & ~JS_EVENT_INIT)
  42. {
  43. case JS_EVENT_AXIS:
  44. n=js.number;
  45. if (n>=0 && n<16) j->axis[n]=js.value/32767.0;
  46. break;
  47. case JS_EVENT_BUTTON:
  48. n=1<<js.number;
  49. if (js.value) j->button|=n;else j->button&=~n;
  50. break;
  51. }
  52. }
  53. close(j->fd);
  54. j->fd=0;
  55. return 0;
  56. }
  57. linuxjoy *getjoy(int n)
  58. {
  59. linuxjoy *j;
  60. char fname[16];
  61. int fd;
  62. sprintf(fname,"/dev/js%d",n);
  63. fd=open(fname,O_RDONLY);
  64. if (fd==-1) {
  65. sprintf(fname,"/dev/input/js%d",n);
  66. fd=open(fname,O_RDONLY);
  67. if (fd==-1) return 0;
  68. }
  69. j=(linuxjoy*)calloc(1,sizeof(struct linuxjoy));
  70. j->fd=fd;
  71. ioctl(fd,JSIOCGNAME(256),&j->name);
  72. ioctl(fd,JSIOCGAXES,&j->axiscount);
  73. ioctl(fd,JSIOCGBUTTONS,&j->buttoncount);
  74. // fcntl(fd,F_SETFL,O_NONBLOCK);
  75. j->open=1;
  76. pthread_attr_t attr;
  77. pthread_attr_init(&attr);
  78. // pthread_attr_setschedpolicy(&attr,SCHED_RR);
  79. // pthread_attr_getschedparam(&attr);
  80. // printf("mypid=%x\n",getpid());
  81. // pthread_attr_setschedparam(&attr,1);
  82. j->threadid=pthread_create(&j->thread,&attr,joythread,(void*)j);
  83. return j;
  84. }
  85. void updatejoy(linuxjoy *j,int *buttons,float *axis)
  86. {
  87. *buttons=j->button;
  88. memcpy(axis,j->axis,16*4);
  89. }
  90. void freejoy(struct linuxjoy *j)
  91. {
  92. int timeout=5;
  93. j->open=0;
  94. while (timeout-- && j->fd) sleep(1);
  95. // close(j->fd);
  96. }
  97. // standard freejoy interface
  98. int ljoyopen;
  99. int ljoycount;
  100. linuxjoy *ljoys[8];
  101. int JoyCount()
  102. {
  103. linuxjoy *j;
  104. int i,n;
  105. if (!ljoyopen)
  106. {
  107. n=0;
  108. for (i=0;i<8;i++)
  109. {
  110. j=getjoy(i);
  111. if (j) ljoys[n++]=j;
  112. }
  113. ljoycount=n;
  114. ljoyopen=1;
  115. }
  116. return ljoycount;
  117. }
  118. char *JoyCName(int port)
  119. {
  120. if (port>=0 && port<ljoycount) return ljoys[port]->name;
  121. return 0;
  122. }
  123. int JoyButtonCaps(int port)
  124. {
  125. if (port>=0 && port<ljoycount) return (1<<ljoys[port]->buttoncount)-1;
  126. return 0;
  127. }
  128. int JoyAxisCaps(int port)
  129. {
  130. if (port>=0 && port<ljoycount) return (1<<ljoys[port]->axiscount)-1;
  131. return 0;
  132. }
  133. int ReadJoy(int port,int *buttons,float *axis)
  134. {
  135. if (port<0 || port>=ljoycount) return 0;
  136. updatejoy (ljoys[port],buttons,axis);
  137. return 1;
  138. }
  139. void WriteJoy(int port,int channel,float value)
  140. {
  141. }