diff --git a/Makefile.am b/Makefile.am index dd69606..f801fad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,6 +40,8 @@ libcwSRC += src/libcw/cwUi.cpp src/libcw/cwUiTest.cpp endif +libcwHDR += src/libcw/cwKeyboard.h +libcwSRC += src/libcw/cwKeyboard.cpp libcwHDR += src/libcw/cwSerialPortDecls.h src/libcw/cwSerialPort.h src/libcw/cwSerialPortSrv.h libcwSRC += src/libcw/cwSerialPort.cpp src/libcw/cwSerialPortSrv.cpp @@ -56,8 +58,8 @@ libcwHDR += src/libcw/cwMidiPort.h src/libcw/cwAudioD libcwSRC += src/libcw/cwMidiPort.cpp src/libcw/cwMidiAlsa.cpp src/libcw/cwAudioDeviceAlsa.cpp src/libcw/cwAudioDeviceTest.cpp if cwWEBSOCK -libcwHDR += src/libcw/cwIo.h src/libcw/cwIoTest.h src/libcw/cwIoSocketChat.h src/libcw/cwIoAudioPanel.h src/libcw/cwIoAudioMidi.h -libcwSRC += src/libcw/cwIo.cpp src/libcw/cwIoTest.cpp src/libcw/cwIoSocketChat.cpp src/libcw/cwIoAudioPanel.cpp src/libcw/cwIoAudioMidi.cpp +libcwHDR += src/libcw/cwIo.h src/libcw/cwIoTest.h src/libcw/cwIoMinTest.h src/libcw/cwIoSocketChat.h src/libcw/cwIoAudioPanel.h src/libcw/cwIoAudioMidi.h +libcwSRC += src/libcw/cwIo.cpp src/libcw/cwIoTest.cpp src/libcw/cwIoMinTest.cpp src/libcw/cwIoSocketChat.cpp src/libcw/cwIoAudioPanel.cpp src/libcw/cwIoAudioMidi.cpp libcwHDR += src/libcw/cwIoMidiRecordPlay.h src/libcw/cwIoAudioRecordPlay.h src/libcw/cwIoAudioMidiApp.h src/libcw/cwIoFlow.h libcwSRC += src/libcw/cwIoMidiRecordPlay.cpp src/libcw/cwIoAudioRecordPlay.cpp src/libcw/cwIoAudioMidiApp.cpp src/libcw/cwIoFlow.cpp diff --git a/cwIoMinTest.cpp b/cwIoMinTest.cpp new file mode 100644 index 0000000..83981c5 --- /dev/null +++ b/cwIoMinTest.cpp @@ -0,0 +1,134 @@ +#include "cwCommon.h" +#include "cwLog.h" +#include "cwCommonImpl.h" +#include "cwKeyboard.h" +#include "cwMem.h" +#include "cwObject.h" +#include "cwTime.h" +#include "cwMidiDecls.h" +#include "cwMidi.h" +#include "cwUiDecls.h" +#include "cwIo.h" +#include "cwIoMinTest.h" + +namespace cw +{ + enum + { + kThread0Id, + kThread1Id + }; + + typedef struct app_str + { + unsigned n0; + unsigned n1; + io::handle_t ioH; + } app_t; + + void minTestThreadCb( app_t* app, const io::thread_msg_t* tm ) + { + switch( tm->id ) + { + case kThread0Id: + app->n0 += 1; + break; + + case kThread1Id: + app->n1 += 1; + break; + } + } + + // The main application callback + rc_t minTestCb( void* arg, const io::msg_t* m ) + { + rc_t rc = kOkRC; + app_t* app = reinterpret_cast(arg); + + switch( m->tid ) + { + case io::kThreadTId: + minTestThreadCb( app, m->u.thread ); + break; + + case io::kSerialTId: + break; + + case io::kMidiTId: + break; + + case io::kAudioTId: + break; + + case io::kAudioMeterTId: + break; + + case io::kSockTId: + break; + + case io::kWebSockTId: + break; + + case io::kUiTId: + break; + + default: + assert(0); + + } + + return rc; + } +} + + +cw::rc_t cw::min_test( const object_t* cfg ) +{ + rc_t rc; + app_t app = {}; + + + // create the io framework instance + if((rc = create(app.ioH,cfg,minTestCb,&app)) != kOkRC ) + return rc; + + if((rc = threadCreate( app.ioH, kThread0Id, &app )) != kOkRC ) + { + rc = cwLogError(rc,"Thread 0 create failed."); + goto errLabel; + } + + if((rc = threadCreate( app.ioH, kThread1Id, &app )) != kOkRC ) + { + rc = cwLogError(rc,"Thread 1 create failed."); + goto errLabel; + } + + // start the io framework instance + if((rc = start(app.ioH)) != kOkRC ) + { + rc = cwLogError(rc,"Test app start failed."); + goto errLabel; + } + + printf(" to quit.\n"); + + // execuite the io framework + while( !isShuttingDown(app.ioH)) + { + exec(app.ioH); + sleepMs(500); + + if( isKeyWaiting() ) + break; + + printf("%i %i\n",app.n0,app.n1); + } + + errLabel: + destroy(app.ioH); + printf("ioMinTest Done.\n"); + return rc; + +} diff --git a/cwIoMinTest.h b/cwIoMinTest.h new file mode 100644 index 0000000..6461ec9 --- /dev/null +++ b/cwIoMinTest.h @@ -0,0 +1,11 @@ +#ifndef cwIoMinTest_H +#define cwIoMinTest_H + + +namespace cw +{ + rc_t min_test( const object_t* cfg); + +} + +#endif diff --git a/cwKeyboard.cpp b/cwKeyboard.cpp new file mode 100644 index 0000000..31884ce --- /dev/null +++ b/cwKeyboard.cpp @@ -0,0 +1,304 @@ +#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(); + +} diff --git a/cwKeyboard.h b/cwKeyboard.h new file mode 100644 index 0000000..5355828 --- /dev/null +++ b/cwKeyboard.h @@ -0,0 +1,70 @@ +#ifndef cwKeyboard_H +#define cwKeyboard_H + + +namespace cw +{ + + enum + { + kInvalidKId, + kAsciiKId, + kLeftArrowKId, + kRightArrowKId, + kUpArrowKId, + kDownArrowKId, + kHomeKId, + kEndKId, + kPgUpKId, + kPgDownKId, + kInsertKId, + kDeleteKId, + }; + + typedef struct + { + unsigned code; + char ch; + bool ctlFl; + bool altFl; + } cmKbRecd; + + // Set 'p' to NULL if the value of the key is not required. + void keyPress( cmKbRecd* p ); + + + // Return non-zero if a key is waiting to be read otherwise return 0. + // Use getchar() to pick up the key. + // + // Example: + // while( 1 ) + // { + // if( cmIsKeyWaiting() == 0 ) + // usleep(20000); + // else + // { + // char c = getchar(); + // switch(c) + // { + // .... + // } + // } + // + // } + // + // TODO: Note that this function turns off line-buffering on stdin. + // It should be changed to a three function sequence. + // bool org_state = cmSetStdinLineBuffering(false); + // .... + // isKeyWaiting() + // .... + // setStdinLineBuffering(org_state) + int isKeyWaiting(); + + void kbTest1(); + void kbTest2(); + void kbTest3(); + +} + +#endif