/* ** === WtKbd.C -- Keyboard handler for WT */ /*=====================*/ /*====== Includes =====*/ /*=====================*/ #include #include #include #include #include "wt.h" #include "wtbuf.h" #include "wtcfg.h" #include "wtcom.h" #include "wtkbd.h" #include "wtppn.h" #include "wtser.h" #include "wtsta.h" #include "wtwin.h" /*=====================*/ /*===== Constants =====*/ /*=====================*/ #define SHIFT_INS 0x80 #define SHIFT_CAPS 0x40 #define SHIFT_NUM 0x20 #define SHIFT_SCROLL 0x10 #define SHIFT_ALT 0x08 #define SHIFT_CTRL 0x04 #define SHIFT_LSHIFT 0x02 #define SHIFT_RSHIFT 0x01 /*==================*/ /*===== Macros =====*/ /*==================*/ #define KEY(scn,asc) ((scn<<8) | (asc)) /********************************/ /*===== External variables =====*/ /********************************/ extern int back_visible; extern int ppns_visible; extern int help_visible; /*===========================*/ /*===== Local variables =====*/ /*===========================*/ static int shift_state = 0; char inpt_buf[90]; /* Input buffer (80+a little extra */ char *inpt_ptr = inpt_buf; /* pointer into input buffer */ int inpt_cnt = 0; /* no. of chars in inpt */ int inpt_pos = 1; /* input position */ int editing = 0; /* 0 means line is virginal */ static int repeating = 0; static int looping = 0; /*===========================*/ /*===== Local functions =====*/ /*===========================*/ /************************************************************/ /* */ /* clear_buffer(): Clear the command line. */ /* */ /************************************************************/ static void clear_buffer(void) { win_select(WIN_INPT); win_clear(); inpt_cnt = 0; inpt_pos = 1; inpt_ptr = inpt_buf; *inpt_ptr = '\0'; editing = 0; } /* end clear_buffer() */ /************************************************************/ /* */ /* delete_char(): Delete character at current insert pos. */ /* */ /************************************************************/ static void delete_char(void) { if (inpt_pos <= inpt_cnt) { strcpy(inpt_ptr, inpt_ptr+1); inpt_cnt--; win_select(WIN_INPT); win_x(inpt_pos-1); win_puts(inpt_ptr); win_putch(' '); win_x(inpt_pos-1); editing = 1; } } /* end delete_char() */ /************************************************************/ /* */ /* insert_char(): Insert a character into the command line. */ /* */ /************************************************************/ static int insert_char(char ch) { char *q; if (inpt_cnt > 75) { beep(); return 0; } for (q=inpt_buf+inpt_cnt+1; q>=inpt_ptr; q--) { *(q+1) = *q; } inpt_cnt++; *inpt_ptr = ch; win_select(WIN_INPT); win_x(inpt_pos-1); win_puts(inpt_ptr++); inpt_pos++; win_x(inpt_pos-1); editing = 1; return 1; } /* end insert_char() */ /************************************************************/ /* */ /* left_char(): Move input position one char left, with chk */ /* */ /************************************************************/ static int left_char(void) { if (inpt_pos <= 1) { beep(); return 0; } else { inpt_pos--; inpt_ptr--; win_select(WIN_INPT); win_x(inpt_pos-1); } editing = 1; return inpt_pos; } /* end left_char() */ /************************************************************/ /* */ /* right_char(): Move input posn one char right, with check */ /* */ /************************************************************/ static int right_char(void) { if (inpt_pos > inpt_cnt) { beep(); return 0; } else { inpt_pos++; inpt_ptr++; win_select(WIN_INPT); win_x(inpt_pos-1); } editing = 1; return inpt_pos; } /* end right_char() */ /************************************************************/ /* */ /* shift_update(): updates screen depending on shift status */ /* */ /************************************************************/ static void shift_update(int new_shift) { /* ALT means we wanna see the macro definitions */ if (new_shift & SHIFT_ALT && !(shift_state & SHIFT_ALT)) { cfg_showmac(); } else if (shift_state & SHIFT_ALT && !(new_shift & SHIFT_ALT)) { cfg_hidemac(); } /* SCROLL means we wanna see the backscroll buffer */ if (new_shift & SHIFT_SCROLL && !(shift_state & SHIFT_SCROLL)) { if (buf_backswitch(-1)) { buf_position(POS_LAST); buf_display(); } } else if (shift_state & SHIFT_SCROLL && !(new_shift & SHIFT_SCROLL)) { buf_backswitch(-1); } shift_state = new_shift; } /* end shift_update() */ /****************************************************/ /* */ /* keybd_update(): updates based on keyboard input. */ /* */ /****************************************************/ static void keybd_update(int new_key) { int asc_key; char *inpt_trans; char inpt_key[3]; int cr_flag; char *p; char name_buf[20]; int fkey, mkey; sta_repeat(0); repeating = 0; sta_loop(0); looping = 0; inpt_trans = NULL; inpt_key[1] = '\0'; inpt_key[2] = '\0'; cr_flag = 0; asc_key = new_key & 0xff; /* --- check for buffer manipulation key --- */ if (back_visible) { switch (new_key) { case KEY(0x48,0xE0): /* Cur up [t-pad] */ buf_position(POS_PREV); /* up one line */ buf_display(); goto show_cursor; case KEY(0x47,0xE0): /* Home [6-pad] */ buf_position(POS_FIRST); /* beginning of buffer */ buf_display(); goto show_cursor; case KEY(0x49,0xE0): /* PgUp [6-pad] */ buf_position(POS_PGUP); /* up one page */ buf_display(); goto show_cursor; case KEY(0x50,0xE0): /* Cur dn [t-pad] */ buf_position(POS_NEXT); /* down one line */ buf_display(); goto show_cursor; case KEY(0x4F,0xE0): /* End [6-pad] */ buf_position(POS_LAST); /* end of buffer */ buf_display(); goto show_cursor; case KEY(0x51,0xE0): /* PgDn [6-pad] */ buf_position(POS_PGDN); /* down one page */ buf_display(); goto show_cursor; } /* end switch */ } /* --- check for PPN list manipulation key --- */ if (ppns_visible) { switch (new_key) { case KEY(0x48,0xE0): /* Cur up [t-pad] */ ppn_position(POS_PREV); /* up one line */ buf_display(); goto show_cursor; case KEY(0x47,0xE0): /* Home [6-pad] */ ppn_position(POS_FIRST); /* beginning of buffer */ buf_display(); goto show_cursor; case KEY(0x49,0xE0): /* PgUp [6-pad] */ ppn_position(POS_PGUP); /* up one page */ buf_display(); goto show_cursor; case KEY(0x50,0xE0): /* Cur dn [t-pad] */ ppn_position(POS_NEXT); /* down one line */ buf_display(); goto show_cursor; case KEY(0x4F,0xE0): /* End [6-pad] */ ppn_position(POS_LAST); /* end of buffer */ buf_display(); goto show_cursor; case KEY(0x51,0xE0): /* PgDn [6-pad] */ ppn_position(POS_PGDN); /* down one page */ buf_display(); goto show_cursor; } /* end switch */ if (asc_key == '\033') { /* ESC */ ppn_lookup(""); goto show_cursor; } } /* --- check for $HELP termination key --- */ if (help_visible) { if (asc_key == '\033') { /* ESC */ cfg_help(0); goto show_cursor; } } /* --- check for first key on empty buffer --- */ if (inpt_pos == 1) { switch (new_key) { case KEY(0x47,0x00): /* Home [n-pad] */ case KEY(0x47,0x37): /* Home [n-pad] */ inpt_trans = "NW\r"; break; case KEY(0x49,0x00): /* PgUp [n-pad] */ case KEY(0x49,0x39): /* PgUp [n-pad] */ inpt_trans = "NE\r"; break; case KEY(0x4F,0x00): /* End [n-pad] */ case KEY(0x4F,0x31): /* End [n-pad] */ inpt_trans = "SW\r"; break; case KEY(0x51,0x00): /* PgDn [n-pad] */ case KEY(0x51,0x33): /* PgDn [n-pad] */ inpt_trans = "SE\r"; break; case KEY(0x48,0x00): /* Cur Up [n-pad] */ case KEY(0x48,0x38): /* Cur Up [n-pad] */ inpt_trans = "N\r"; break; case KEY(0x4B,0x00): /* Cur Lf [n-pad] */ case KEY(0x4B,0x34): /* Cur Lf [n-pad] */ inpt_trans = "W\r"; break; case KEY(0x50,0x00): /* Cur Dn [n-pad] */ case KEY(0x50,0x32): /* Cur Dn [n-pad] */ inpt_trans = "S\r"; break; case KEY(0x4D,0x00): /* Cur Rt [n-pad] */ case KEY(0x4D,0x36): /* Cur Rt [n-pad] */ inpt_trans = "E\r"; break; case KEY(0x4C,0x00): /* -5- [n-pad] */ case KEY(0x4C,0x35): /* -5- [n-pad] */ inpt_trans = "IN\r"; break; case KEY(0x52,0x00): /* Ins [n-pad] */ case KEY(0x52,0x30): /* Ins [n-pad] */ inpt_trans = "OUT\r"; break; } /* end switch */ /* Any printable char at begin line will clear it. */ if (!editing && (asc_key >= 32 && asc_key != 0xE0 || inpt_trans != NULL)) { /* printable char */ clear_buffer(); } } /* end if first char */ /* --- check for macro key --- */ mkey = 0; switch (new_key) { case KEY(0x1E, 0x00): mkey = 'A'; break; case KEY(0x30, 0x00): mkey = 'B'; break; case KEY(0x2E, 0x00): mkey = 'C'; break; case KEY(0x20, 0x00): mkey = 'D'; break; case KEY(0x12, 0x00): mkey = 'E'; break; case KEY(0x21, 0x00): mkey = 'F'; break; case KEY(0x22, 0x00): mkey = 'G'; break; case KEY(0x23, 0x00): mkey = 'H'; break; case KEY(0x17, 0x00): mkey = 'I'; break; case KEY(0x24, 0x00): mkey = 'J'; break; case KEY(0x25, 0x00): mkey = 'K'; break; case KEY(0x26, 0x00): mkey = 'L'; break; case KEY(0x32, 0x00): mkey = 'M'; break; case KEY(0x31, 0x00): mkey = 'N'; break; case KEY(0x18, 0x00): mkey = 'O'; break; case KEY(0x19, 0x00): mkey = 'P'; break; case KEY(0x10, 0x00): mkey = 'Q'; break; case KEY(0x13, 0x00): mkey = 'R'; break; case KEY(0x1F, 0x00): mkey = 'S'; break; case KEY(0x14, 0x00): mkey = 'T'; break; case KEY(0x16, 0x00): mkey = 'U'; break; case KEY(0x2F, 0x00): mkey = 'V'; break; case KEY(0x11, 0x00): mkey = 'W'; break; case KEY(0x2D, 0x00): mkey = 'X'; break; case KEY(0x15, 0x00): mkey = 'Y'; break; case KEY(0x2C, 0x00): mkey = 'Z'; break; } if (mkey) { inpt_trans = cfg_mkey(mkey-'A'); /* virginal key state? see above! */ if (! editing) { clear_buffer(); } } /* --- check for F key or edit key --- */ if (inpt_trans == NULL) { switch (new_key) { case KEY(0x4B,0xE0): /* Cur lf [t-pad] */ left_char(); goto show_cursor; case KEY(0x4D,0xE0): /* Cur rt [t-pad] */ right_char(); goto show_cursor; case KEY(0x53,0xE0): /* Del [6-pad] */ delete_char(); goto show_cursor; case KEY(0x52,0xE0): /* Insert [6-pad] */ if (insert_char(' ')) { left_char(); } goto show_cursor; case KEY(0x3B,0x00): case KEY(0x3B,0xE0): fkey = 1; break; case KEY(0x3C,0x00): case KEY(0x3C,0xE0): fkey = 2; break; case KEY(0x3D,0x00): case KEY(0x3D,0xE0): fkey = 3; break; case KEY(0x3E,0x00): case KEY(0x3E,0xE0): fkey = 4; break; case KEY(0x3F,0x00): case KEY(0x3F,0xE0): fkey = 5; break; case KEY(0x40,0x00): case KEY(0x40,0xE0): fkey = 6; break; case KEY(0x41,0x00): case KEY(0x41,0xE0): fkey = 7; break; case KEY(0x42,0x00): case KEY(0x42,0xE0): fkey = 8; break; case KEY(0x43,0x00): case KEY(0x43,0xE0): fkey = 9; break; case KEY(0x44,0x00): case KEY(0x44,0xE0): fkey = 10; break; case KEY(0x54,0x00): case KEY(0x54,0xE0): fkey = 11; break; case KEY(0x55,0x00): case KEY(0x55,0xE0): fkey = 12; break; case KEY(0x56,0x00): case KEY(0x56,0xE0): fkey = 13; break; case KEY(0x57,0x00): case KEY(0x57,0xE0): fkey = 14; break; case KEY(0x58,0x00): case KEY(0x58,0xE0): fkey = 15; break; case KEY(0x59,0x00): case KEY(0x59,0xE0): fkey = 16; break; case KEY(0x5A,0x00): case KEY(0x5A,0xE0): fkey = 17; break; case KEY(0x5B,0x00): case KEY(0x5B,0xE0): fkey = 18; break; case KEY(0x5C,0x00): case KEY(0x5C,0xE0): fkey = 19; break; case KEY(0x5D,0x00): case KEY(0x5D,0xE0): fkey = 20; break; default: fkey = 0; break; } /* end switch */ if (fkey != 0) { if (inpt_pos == 1) { clear_buffer(); name_buf[0] = '\0'; } else { name_buf[0] = ' '; name_buf[1] = '\0'; } strcat(name_buf, sta_keytran(fkey)); strcat(name_buf, " "); inpt_trans = name_buf; } } /* --- check for Umlaut --- */ if (inpt_trans == NULL) { switch (asc_key) { case 132: /* a-Umlaut */ inpt_trans = "ae"; break; case 148: /* o-Umlaut */ inpt_trans = "oe"; break; case 129: /* u-Umlaut */ inpt_trans = "ue"; break; case 142: /* A-Umlaut */ inpt_trans = "Ae"; break; case 153: /* O-Umlaut */ inpt_trans = "Oe"; break; case 154: /* U-Umlaut */ inpt_trans = "Ue"; break; case 225: /* Double S */ inpt_trans = "ss"; break; } } /* --- check for translated char(s) --- */ if (inpt_trans != NULL) { for (p=inpt_trans; *p && inpt_pos < DPY_COLS-2; p++) { if (*p == '\r') { cr_flag = 1; break; } else if (p[0]=='^' && toupper(p[1])=='M' && p[2]=='\0') { cr_flag = 1; break; } else { insert_char(*p); } } /* end for */ /* --- Check for ASCII chars --- */ } else if (asc_key != 0 && asc_key != 0xE0) { if (asc_key < 32) { /* control char */ switch (asc_key) { case '\b': /* backspace */ if (left_char()) { delete_char(); } break; case '\r': /* CR */ if (new_key==KEY(0x32,0x0D)) { ser_int_putc(asc_key); } else if (inpt_cnt > 0) { cr_flag = 1; } break; case CTRL('C'): /* CTRL-C: clear buffer */ case CTRL('I'): /* TAB: for "something" */ case CTRL('O'): /* CTRL-O: stop scroll */ case CTRL('P'): /* CTRL-P: who knows? */ ser_int_putc(asc_key); break; case '\033': /* ESC = line clear */ case CTRL('U'): /* ^U = line clear */ clear_buffer(); break; } /* end switch */ } else if (asc_key < 128) { /* printable char */ if (inpt_pos > 75) { beep(); } else { insert_char((char) asc_key); } } } /* endif */ /* --- Process CR, if any --- */ if (cr_flag) { if (inpt_buf[0] == '!' && !repeating) { sta_repeat(1); repeating = 1; } else if (inpt_buf[0] == '*' && !looping) { sta_loop(1); looping = 1; } if (inpt_buf[0] == '$') { scr_exec(inpt_buf+1); } else { if (repeating || looping) { com_xputs(inpt_buf+1); } else { com_xputs(inpt_buf); } ser_int_putc('\r'); } inpt_pos = 1; inpt_ptr = inpt_buf; cr_flag = 0; editing = 0; } /* end if */ /* --- Update input cursor --- */ show_cursor:; win_select(WIN_INPT); win_x(inpt_pos-1); } /* end keybd_update() */ /*============================*/ /*===== Global functions =====*/ /*============================*/ /**********************************************/ /* */ /* kbd_init(): initialize keyboard variables. */ /* */ /**********************************************/ void kbd_init(void) { shift_state = 0; inpt_cnt = 0; /* no. of chars in inpt */ inpt_pos = 1; /* input position */ inpt_ptr = inpt_buf; repeating = 0; looping = 0; back_visible = 0; win_select(WIN_INPT); win_x(0); } /* end kbd_init() */ /**************************************************/ /* */ /* kbd_update(): get chars from kbd if available. */ /* */ /**************************************************/ void kbd_update() { unsigned temp_shift; temp_shift = _bios_keybrd(_NKEYBRD_SHIFTSTATUS); if (temp_shift == 0xFFFF) { temp_shift = 0; } else { temp_shift &= SHIFT_SCROLL | SHIFT_ALT | SHIFT_CTRL | SHIFT_LSHIFT | SHIFT_RSHIFT ; } if (temp_shift != shift_state) { shift_update(temp_shift); } else if (_bios_keybrd(_NKEYBRD_READY)) { keybd_update(_bios_keybrd(_NKEYBRD_READ)); } } /* end kbd_update() */ /*****************************************/ /* kbd_repeat(): repeat current kbd input*/ /*****************************************/ void kbd_repeat(void) { com_xputs(inpt_buf+1); ser_int_putc('\r'); } /* end kbd_repeat() */ /* EOF(WtKbd.C) */