libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmKeyboard.c 5.6KB

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