libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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