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 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. }