//| Copyright: (C) 2020-2024 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #include "cwCommon.h" #include "cwLog.h" #include "cwCommonImpl.h" #include #include #include #include #include "cwKeyboard.h" namespace cw { struct termios new_settings; struct termios stored_settings; void set_keypress(void) { struct termios new_settings; tcgetattr(0,&stored_settings); new_settings = stored_settings; new_settings.c_lflag &= (~ICANON); new_settings.c_lflag &= (~ECHO); new_settings.c_cc[VTIME] = 0; //int i; //for(i=0; icode = kInvalidKId; p->ch = 0; p->ctlFl = false; p->altFl = false; } set_keypress(); // block for the first character if((rc = read(0, &c, 1 )) == 1) buf[0]=c; // loop in non-blocking for successive characters new_settings.c_cc[VMIN] = 0; tcsetattr(0,TCSANOW,&new_settings); for(n=1; ncode = kAsciiKId; p->ch = buf[0]; p->ctlFl = buf[0] <= 31; } else { for(j=0; _cmKbTbl[j][0] != 0; ++j) if( _cmKbTbl[j][0] == (unsigned)n ) { for(k=1; k<=n; ++k) if( _cmKbTbl[j][k] != (unsigned)buf[k-1] ) break; // if the key was found if( k==n+1 ) { p->code = _cmKbTbl[j][ CM_KB_TBL_CNT - 1 ]; p->ctlFl = _cmKbTbl[j][ CM_KB_TBL_CNT - 2 ]; break; } } } } reset_keypress(); } // Based on: // From: http://www.flipcode.com/archives/_kbhit_for_Linux.shtml int cw::isKeyWaiting() { static const int STDIN = 0; static bool initialized = false; struct timeval timeout; fd_set rdset; if( !initialized ) { // Use termios to turn off line buffering struct termios term; tcgetattr(STDIN, &term); term.c_lflag &= ~ICANON; tcsetattr(STDIN, TCSANOW, &term); setbuf(stdin, NULL); initialized = true; } if(0) { FD_ZERO(&rdset); FD_SET(STDIN, &rdset); timeout.tv_sec = 0; timeout.tv_usec = 0; // time out immediately if STDIN is not ready. return select(STDIN + 1, &rdset, NULL, NULL, &timeout); } else { int bytesWaiting; ioctl(STDIN, FIONREAD, &bytesWaiting); return bytesWaiting; } } void cw::kbTest1() { set_keypress(); int c = 0; int r; printf("'q' to quit\n"); while( c != 'q' ) { printf("0>"); fflush(stdout); r = read(0, &c, 1 ); printf("0: %c (%i)\r\n",(char)c,c); new_settings.c_cc[VMIN] = 0; tcsetattr(0,TCSANOW,&new_settings); if( r == 1 && c == 27 ) { r = read(0, &c, 1 ); printf("1: %c (%i)\n",(char)c,c); if( r == 1 && c == '[' ) { r = read(0, &c, 1 ); printf("2: %c (%i)\n",(char)c,c); } } new_settings.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&new_settings); } reset_keypress(); } void cw::kbTest2() { set_keypress(); fd_set rfds; struct timeval tv; int retval; int c=0; printf("'q' to quit\n"); while( c != 'q' ) { int i = 0; printf(">"); do { // Watch stdin (fd 0) to see when it has input. FD_ZERO(&rfds); FD_SET(0, &rfds); // don't wait tv.tv_sec = 0; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, i==0 ? NULL : &tv); // Don't rely on the value of tv now - it may have been overwritten by select // if an error occurred if (retval == -1) perror("select()"); else { // if data is waiting if (retval) { c = getchar(); printf("%i %c (%i) ",i,(char)c,c); ++i; } else { printf("\n"); break; // no data available } } } while( 1 ); } reset_keypress(); } void cw::kbTest3() { set_keypress(); int i =0; printf(" to quit"); while(1) { cw::sleepMs(500); // sleep milliseconds printf("%i\n",i); i += 1; if( isKeyWaiting() ) break; } reset_keypress(); }