libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cmKeyboard.c 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmKeyboard.h"
  4. #include <termios.h>
  5. //#include <stropts.h>
  6. #include <sys/ioctl.h>
  7. //#include <linux/kd.h>
  8. //#include <linux/keyboard.h>
  9. #include <unistd.h>
  10. struct termios new_settings;
  11. struct termios stored_settings;
  12. void set_keypress(void)
  13. {
  14. struct termios new_settings;
  15. tcgetattr(0,&stored_settings);
  16. new_settings = stored_settings;
  17. new_settings.c_lflag &= (~ICANON);
  18. new_settings.c_lflag &= (~ECHO);
  19. new_settings.c_cc[VTIME] = 0;
  20. //int i;
  21. //for(i=0; i<NCCS; ++i)
  22. // printf("%i ",new_settings.c_cc[i]);
  23. //printf("\n");
  24. tcgetattr(0,&stored_settings);
  25. new_settings.c_cc[VMIN] = 1;
  26. tcsetattr(0,TCSANOW,&new_settings);
  27. }
  28. void reset_keypress(void)
  29. {
  30. tcsetattr(0,TCSANOW,&stored_settings);
  31. }
  32. #define CM_KB_TBL_CNT (10)
  33. unsigned _cmKbTbl[][CM_KB_TBL_CNT] =
  34. {
  35. // alt ctl code
  36. { 3, 27, 91, 68, 0, 0, 0, 0, 0, kLeftArrowKId },
  37. { 3, 27, 91, 67, 0, 0, 0, 0, 0, kRightArrowKId },
  38. { 3, 27, 91, 65, 0, 0, 0, 0, 0, kUpArrowKId },
  39. { 3, 27, 91, 66, 0, 0, 0, 0, 0, kDownArrowKId },
  40. { 3, 27, 79, 72, 0, 0, 0, 0, 0, kHomeKId },
  41. { 3, 27, 79, 70, 0, 0, 0, 0, 0, kEndKId },
  42. { 4, 27, 91, 53, 126, 0, 0, 0, 0, kPgUpKId },
  43. { 4, 27, 91, 54, 126, 0, 0, 0, 0, kPgDownKId },
  44. { 4, 27, 91, 50, 126, 0, 0, 0, 0, kInsertKId },
  45. { 4, 27, 91, 51, 126, 0, 0, 0, 0, kDeleteKId },
  46. { 6, 27, 91, 49, 59, 53, 68, 0, 1, kLeftArrowKId },
  47. { 6, 27, 91, 49, 59, 53, 67, 0, 1, kRightArrowKId },
  48. { 6, 27, 91, 49, 59, 53, 65, 0, 1, kUpArrowKId },
  49. { 6, 27, 91, 49, 59, 53, 66, 0, 1, kDownArrowKId },
  50. { 6, 27, 91, 53, 59, 53, 126, 0, 1, kPgUpKId },
  51. { 6, 27, 91, 54, 59, 53, 126, 0, 1, kPgDownKId },
  52. { 4, 27, 91, 51, 59, 53, 126, 0, 1, kDeleteKId },
  53. { 0, 0, 0, 0, 0, 0, 0, 0, 0, kInvalidKId }
  54. };
  55. void cmKeyPress( cmKbRecd* p )
  56. {
  57. const int bufN = 16;
  58. char buf[bufN];
  59. int n,j, k;
  60. int rc;
  61. char c;
  62. if( p != NULL )
  63. {
  64. p->code = kInvalidKId;
  65. p->ch = 0;
  66. p->ctlFl = false;
  67. p->altFl = false;
  68. }
  69. set_keypress();
  70. // block for the first character
  71. if((rc = read(0, &c, 1 )) == 1)
  72. buf[0]=c;
  73. // loop in non-blocking for successive characters
  74. new_settings.c_cc[VMIN] = 0;
  75. tcsetattr(0,TCSANOW,&new_settings);
  76. for(n=1; n<bufN; ++n)
  77. if(read(0,&c,1) == 1 )
  78. buf[n] = c;
  79. else
  80. break;
  81. new_settings.c_cc[VMIN] = 1;
  82. tcsetattr(0,TCSANOW,&new_settings);
  83. /*
  84. for(j=0; j<n; ++j)
  85. printf("{%c (%i)} ",buf[j],buf[j]);
  86. printf(" :%i\f\n",n);
  87. fflush(stdout);
  88. */
  89. if( p != NULL )
  90. {
  91. // translate the keypress
  92. if( n == 1)
  93. {
  94. p->code = kAsciiKId;
  95. p->ch = buf[0];
  96. p->ctlFl = buf[0] <= 31;
  97. }
  98. else
  99. {
  100. for(j=0; _cmKbTbl[j][0] != 0; ++j)
  101. if( _cmKbTbl[j][0] == n )
  102. {
  103. for(k=1; k<=n; ++k)
  104. if( _cmKbTbl[j][k] != buf[k-1] )
  105. break;
  106. // if the key was found
  107. if( k==n+1 )
  108. {
  109. p->code = _cmKbTbl[j][ CM_KB_TBL_CNT - 1 ];
  110. p->ctlFl = _cmKbTbl[j][ CM_KB_TBL_CNT - 2 ];
  111. break;
  112. }
  113. }
  114. }
  115. }
  116. reset_keypress();
  117. }
  118. void cmKbTest()
  119. {
  120. set_keypress();
  121. int c = 0;
  122. int r;
  123. while( c != 'q' )
  124. {
  125. printf("0>"); fflush(stdout);
  126. r = read(0, &c, 1 );
  127. printf("0: %c (%i)\r\n",(char)c,c);
  128. new_settings.c_cc[VMIN] = 0;
  129. tcsetattr(0,TCSANOW,&new_settings);
  130. if( r == 1 && c == 27 )
  131. {
  132. r = read(0, &c, 1 );
  133. printf("1: %c (%i)\n",(char)c,c);
  134. if( r == 1 && c == '[' )
  135. {
  136. r = read(0, &c, 1 );
  137. printf("2: %c (%i)\n",(char)c,c);
  138. }
  139. }
  140. new_settings.c_cc[VMIN] = 1;
  141. tcsetattr(0,TCSANOW,&new_settings);
  142. }
  143. reset_keypress();
  144. }
  145. // Note: this technique does not work because the
  146. void testKb2()
  147. {
  148. set_keypress();
  149. fd_set rfds;
  150. struct timeval tv;
  151. int retval;
  152. int c=0;
  153. while( c != 'q' )
  154. {
  155. int i = 0;
  156. printf(">");
  157. do
  158. {
  159. /* Watch stdin (fd 0) to see when it has input. */
  160. FD_ZERO(&rfds);
  161. FD_SET(0, &rfds);
  162. // don't wait
  163. tv.tv_sec = 0;
  164. tv.tv_usec = 0;
  165. retval = select(1, &rfds, NULL, NULL, i==0 ? NULL : &tv);
  166. // Don't rely on the value of tv now - it may have been overwritten by select
  167. // if an error occurred
  168. if (retval == -1)
  169. perror("select()");
  170. else
  171. {
  172. // if data is waiting
  173. if (retval)
  174. {
  175. c = getchar();
  176. printf("%i %c (%i) ",i,(char)c,c);
  177. ++i;
  178. }
  179. else
  180. {
  181. printf("\n");
  182. break; // no data available
  183. }
  184. }
  185. } while( 1 );
  186. }
  187. reset_keypress();
  188. }
  189. // Based on: // From: http://www.flipcode.com/archives/_kbhit_for_Linux.shtml
  190. int cmIsKeyWaiting()
  191. {
  192. static const int STDIN = 0;
  193. static bool initialized = false;
  194. struct timeval timeout;
  195. fd_set rdset;
  196. if (! initialized)
  197. {
  198. // Use termios to turn off line buffering
  199. struct termios term;
  200. tcgetattr(STDIN, &term);
  201. term.c_lflag &= ~ICANON;
  202. tcsetattr(STDIN, TCSANOW, &term);
  203. setbuf(stdin, NULL);
  204. initialized = true;
  205. }
  206. FD_ZERO(&rdset);
  207. FD_SET(STDIN, &rdset);
  208. timeout.tv_sec = 0;
  209. timeout.tv_usec = 0;
  210. // time out immediately if STDIN is not ready.
  211. return select(STDIN + 1, &rdset, NULL, NULL, &timeout);
  212. }