Minor improvement to my old program adding menus for speed change and fixed messages.
The following is the source code.
/* file name = ic7410.c */ /* % gcc ic7410.c -o ic7410 -lncurses */ #include <ncurses.h> #include <stdlib.h> #include <unistd.h> #include <termios.h> #include <string.h> #include <fcntl.h> #include <ctype.h> #define ENTER 10 #define ESCAPE 27 #define NROWMIN 30 #define NCOLMIN 80 #define BUFSIZE 1024 #define BAUDRATE B19200 #define MYRIG "/dev/ttyUSB0" static int speed[]={15,20,25,30,35,40,45,50}; static int nspeed =sizeof(speed) / sizeof(speed[0]); static char *text_array[]={ "cq cq cq de jh1ood jh1ood jh1ood k ", "de jh1ood jh1ood jh1ood k ", "qrz? de jh1ood k ", "ur 5nn ^bk ", "73 tu e e "}; static int ntext =sizeof(text_array) / sizeof(text_array[0]); int fd=-1; void init_curses() { initscr (); start_color(); noecho (); raw (); keypad (stdscr, TRUE); scrollok (stdscr, TRUE); curs_set (0); init_pair (1,COLOR_WHITE,COLOR_BLUE); init_pair (2,COLOR_BLUE,COLOR_WHITE); init_pair (3,COLOR_RED,COLOR_WHITE); init_pair (4,COLOR_BLACK,COLOR_GREEN); } void draw_menubar(WINDOW *menubar) { wbkgd(menubar,COLOR_PAIR(2)); waddstr(menubar," WPM "); wattron(menubar,COLOR_PAIR(3)); waddstr(menubar,"(F1)"); wattroff(menubar,COLOR_PAIR(3)); wmove(menubar,0,20); waddstr(menubar," Messages "); wattron(menubar,COLOR_PAIR(3)); waddstr(menubar,"(F2)"); wattroff(menubar,COLOR_PAIR(3)); } WINDOW **draw_menu1(int start_col) { int i; WINDOW **items; items=(WINDOW **)malloc((nspeed+1)*sizeof(WINDOW *)); items[0]=newwin(nspeed+2,9,1,start_col); wbkgd(items[0],COLOR_PAIR(2)); box(items[0],ACS_VLINE,ACS_HLINE); for (i=1;i<=nspeed;i++) { items[i]=subwin(items[0],1,7,i+1,start_col+1); wprintw(items[i],"%2d WPM",speed[i-1]); } wbkgd(items[1],COLOR_PAIR(1)); wrefresh(items[0]); return items; } WINDOW **draw_menu2(int start_col) { int i; WINDOW **items; items=(WINDOW **)malloc((ntext+1)*sizeof(WINDOW *)); items[0]=newwin(ntext+2,49,1,start_col); wbkgd(items[0],COLOR_PAIR(2)); box(items[0],ACS_VLINE,ACS_HLINE); for (i=1;i<=ntext;i++) { items[i]=subwin(items[0],1,47,i+1,start_col+1); wprintw(items[i],"%s",text_array[i-1]); } wbkgd(items[1],COLOR_PAIR(1)); wrefresh(items[0]); return items; } void delete_menu(WINDOW **items,int count) { int i; for (i=0;i<count;i++) delwin(items[i]); free(items); } int scroll_menu(WINDOW **items,int count) { int key; int selected=0; while (1) { key=getch(); if (key==KEY_DOWN || key==KEY_UP) { wbkgd(items[selected+1],COLOR_PAIR(2)); wnoutrefresh(items[selected+1]); if (key==KEY_DOWN) { selected=(selected+1) % count; } else { selected=(selected+count-1) % count; } wbkgd(items[selected+1],COLOR_PAIR(1)); wnoutrefresh(items[selected+1]); doupdate(); } else if (key==ESCAPE) { return -1; } else if (key==ENTER) { return selected; } } } void send_cw(char* text); /* IC-7410 key speed set */ /* the parameter 0-255 relates to 6wpm-48wpm */ void send_keyspeed(int wpm) { static char output_ks [9] = {0xfe, 0xfe, 0x80, 0x00, 0x14, 0x0c, 0x01, 0x28, /* from 0x00,0x00 to 0x02,0x55 */ 0xfd}; int param, p0, p1, p2; if(wpm < 6) wpm = 6; if(wpm > 48) wpm = 48; param = 255.0 * ((double)wpm - 6.0) / (48.0 - 6.0) + 0.0; p0 = param % 10; p1 = (param/ 10) % 10; p2 = (param/100) % 10; output_ks[6] = p2; output_ks[7] = 16*p1+p0; /* because param=123 goes as 0x01, 0x23 (BCD) */ write(fd, output_ks, 9); } void send_cw(char* text) { /* IC-7410 send CW */ static char output [BUFSIZE] = {0xfe, 0xfe, 0x80, 0x00, 0x17}; char *p; int count; count=0; p=output+5; while((*p++ = *text++)) { count++; if(count == 30) { /* IC-7410 max CW text length */ *p = 0xfd; /* IC-7410 postamble */ write(fd, output, 5+count+1); count=0; p=output+5; } } if(count) { *(--p) = 0xfd; /* replace zero with postamble */ write(fd, output, 5+count+1); } } void send_stored_text(int id) { /* use Function Keys */ send_cw(text_array[id-1]); /* id=1, 2, ... */ attron(COLOR_PAIR(2)); printw (text_array[id-1]); attroff(COLOR_PAIR(2)); } void serial_init(void) { struct termios tio; memset(&tio, 0, sizeof(tio)); tio.c_cflag = CS8 | CLOCAL | CREAD; tio.c_cc[VTIME] = 0; tio.c_cc[VEOL ] = 0xfd; /* IC-7410 postamble */ tio.c_lflag = ICANON; tio.c_iflag = IGNPAR | ICRNL; cfsetispeed(&tio, BAUDRATE); cfsetospeed(&tio, BAUDRATE); tcsetattr (fd, TCSANOW, &tio); } int main(void) { int c, count=0, nrow, ncol, row=0, col=0; char word[BUFSIZE]; struct termios oldtio; int selected_item; WINDOW *menubar,*messagebar, **menu_items; /* IC-7410 USB I/F initialize */ fd = open(MYRIG, O_RDWR | O_NOCTTY); if (fd < 0) { fprintf(stderr,"Error: can not open %s \n", MYRIG); return (-1); } tcgetattr (fd, &oldtio); serial_init(); /* ncurses initialize */ init_curses(); getmaxyx (stdscr,nrow,ncol); if(nrow<NROWMIN || ncol < NCOLMIN) { row=1; col=0; move(row, col); printw("Current Window size is %d rows, %d columns. \n\n" ,nrow, ncol); printw("Please make the Window size greater than %d rows, %d columns. \n" ,NROWMIN, NCOLMIN); printw("Hit anykey.. \n"); getch(); endwin(); return EXIT_FAILURE; } bkgd(COLOR_PAIR(4)); menubar =subwin(stdscr,1,40,0, 0); messagebar=subwin(stdscr,1,10,0,ncol-10); /* 10chars */ wattron(messagebar, COLOR_PAIR(2)); draw_menubar(menubar); row=5; col=0; move(row, col); refresh(); while ( (c=getch()) != 0x04) { /* ^d, EOT */ switch (c) { case KEY_F(1): menu_items=draw_menu1(0); selected_item=scroll_menu(menu_items,nspeed); delete_menu(menu_items,nspeed); if (selected_item<0) ; else { wclear(messagebar); wprintw(messagebar, "Now %2d WPM",speed[selected_item]); /* 10chars */ send_keyspeed(speed[selected_item]); } touchwin(stdscr); refresh(); break; case KEY_F(2): menu_items=draw_menu2(20); selected_item=scroll_menu(menu_items,ntext); delete_menu(menu_items,ntext); if (selected_item<0) ; else send_stored_text(selected_item+1); touchwin(stdscr); refresh(); break; case KEY_BACKSPACE: if(count) { /* only within a word */ getyx (stdscr, row, col); count--; col--; /* only within the same line */ mvaddch(row, col, ' '); move (row, col); /* cursor goes back */ } break; default: if(isprint(c)) { addch(c); word[count++] = c; } break; } getyx(stdscr, row, col); if(c == 0x0a || (c==' ' && (col >= ncol-10 || col == ncol))) printw("\n"); refresh(); if(c == 0x0a || c == ' ' || c == '.' || c == ',') { word[count] = 0; count=0; send_cw(word); } } tcsetattr(fd, TCSANOW, &oldtio); /* reset serial terminal */ endwin (); /* reset ncurses */ return EXIT_SUCCESS; }
Note: The menu part of the code is from
http://www.linuxfocus.org/English/March2002/article233.shtml