commit de4154976cdc9b37862f87246b1a30991302d4d8 from: marcus date: Mon Feb 11 21:51:12 2002 UTC More on vt52 emulation. Not vttest complete. Poked around in keyboard handling. Broke and fixed it at several places. It is still a mess. commit - 030eadbad26a370a331fb85fe1f9ab26f11e4af8 commit + de4154976cdc9b37862f87246b1a30991302d4d8 blob - a8b4ba92783013068d6440d4986f2d9f6e058994 blob + 6f9aabefe34294ca8db22e8c61c72edc92db1e32 --- de/mud/terminal/vt320.java +++ de/mud/terminal/vt320.java @@ -124,7 +124,13 @@ public abstract class vt320 extends VDU implements Key KeyHome[0] = KeyHome[1] = KeyHome[2] = KeyHome[3] = "\u001b[H"; KeyEnd[0] = KeyEnd[1] = KeyEnd[2] = KeyEnd[3] = "\u001b[F"; Escape[0] = Escape[1] = Escape[2] = Escape[3] = "\u001b"; - BackSpace[0] = BackSpace[1] = BackSpace[2] = BackSpace[3] = "\b"; + if (vms) { + BackSpace[1] = ""+(char)10; // VMS shift deletes word back + BackSpace[2] = "\u0018"; // VMS control deletes line back + BackSpace[0] = BackSpace[3] = "\u007f"; // VMS other is delete + } else { + BackSpace[0] = BackSpace[1] = BackSpace[2] = BackSpace[3] = "\b"; + } /* some more VT100 keys */ Find = "\u001b[1~"; @@ -192,7 +198,7 @@ public abstract class vt320 extends VDU implements Key Numpad[7] = "\u001bOw"; Numpad[8] = "\u001bOx"; Numpad[9] = "\u001bOy"; - KPMinus = "\u001bOm"; + KPMinus = PF4; KPComma = "\u001bOl"; KPPeriod = "\u001bOn"; KPEnter = "\u001bOM"; @@ -416,10 +422,6 @@ public abstract class vt320 extends VDU implements Key // the actual terminal emulation code comes here: // =================================================================== - // due to a bug with Windows we need a keypress cache - private int pressedKey = ' '; - // private long pressedWhen = ' '; - private String terminalID = "vt320"; private String answerBack = "Use Terminal.answerback to set ...\n"; @@ -433,7 +435,7 @@ public abstract class vt320 extends VDU implements Key int insertmode = 0; int statusmode = 0; - int vt52mode = 0; + boolean vt52mode = false; int normalcursor = 0; boolean moveoutsidemargins = true; boolean wraparound = true; @@ -472,6 +474,8 @@ public abstract class vt320 extends VDU implements Key private final static int TSTATE_CSI_DOLLAR = 11; /* ESC [ Pn $ */ private final static int TSTATE_CSI_EX = 12; /* ESC [ ! */ private final static int TSTATE_ESCSPACE = 13; /* ESC */ + private final static int TSTATE_VT52X = 14; + private final static int TSTATE_VT52Y = 15; /* The graphics charsets * B - default ASCII @@ -538,7 +542,7 @@ public abstract class vt320 extends VDU implements Key private String FunctionKeyAlt[]; private String TabKey[]; private String KeyUp[],KeyDown[],KeyLeft[],KeyRight[]; - private String KPMinus, KPComma, KPPeriod,KPEnter; + private String KPMinus, KPComma, KPPeriod, KPEnter; private String PF1, PF2, PF3, PF4; private String Help, Do, Find, Select; @@ -598,50 +602,25 @@ public abstract class vt320 extends VDU implements Key } /** + * A small conveniance method thar converts a 7bit string to the 8bit + * version if VT52 mode is not set. + * @param s the string to be sent + * @param doecho echo to terminal + */ + private boolean writeNumpad(String s) { + if (((s.length() == 3) && (s.charAt(0) == 27) && (s.charAt(1)=='O'))) { + if (vt52mode) { + s="\u001b?"+s.substring(2); /* ESC ? x */ + } else { + s="\u008f"+s.substring(2); /* SS3 ? x */ + } + } + return write(s,false); + } + + /** * main keytyping event handler... */ - public void keyTyped(KeyEvent evt) { - boolean control = evt.isControlDown(); - boolean shift = evt.isShiftDown(); - boolean alt = evt.isAltDown(); - - int keyCode = evt.getKeyCode(); - char keyChar = evt.getKeyChar(); - - if (keyChar == '\u001b' || keyChar == '\b') return; - - if (keyChar == '\t') { - if (shift) { - write(TabKey[1],false); - } else { if (control) { - write(TabKey[2],false); - } else { if (alt) { - write(TabKey[3],false); - } else { - write(TabKey[0],false); - }}} - return; - } - if (alt) { - write(""+((char)(keyChar|0x80))); - return; - } - if(!(keyChar == '\r' || keyChar == '\n') || control) - write(""+keyChar); - } - - /** - * Not used. - */ - public void keyReleased(KeyEvent evt) { - // nothing to to, however maybe we should use it? - } - - /** - * Handle events for the terminal. Only accept events for the scroll - * bar. Any other events have to be propagated to the parent. - * @param evt the event - */ public void keyPressed(KeyEvent evt) { boolean control = evt.isControlDown(); boolean shift = evt.isShiftDown(); @@ -649,92 +628,16 @@ public abstract class vt320 extends VDU implements Key int keyCode = evt.getKeyCode(); char keyChar = evt.getKeyChar(); + //System.out.println("keyPressed "+evt); - /* - if(pressedKey == KeyEvent.VK_ENTER && - (keyCode == KeyEvent.VK_ENTER || keyChar == 10) - && evt.getWhen() - pressedWhen < 50) - return; - - pressedWhen = evt.getWhen(); - */ - - if( ((keyCode == KeyEvent.VK_ENTER) || (keyChar == 10)) && !control) { - write("\n",false); - if (localecho) putString("\r\n"); // bad hack - } - - // FIXME: on german PC keyboards you have to use Alt-Ctrl-q to get an @, - // so we can't just use it here... will probably break some other VMS - // codes. -Marcus - // if(((!vms && keyChar == '2') || keyChar == '@' || keyChar == ' ') - // && control) - if (((!vms && keyChar == '2') || keyChar == ' ') && control) - write("" + (char)0); - - if(vms) { - if (keyChar == 8) { - if(shift && !control) - write("" + (char)10); // VMS shift deletes word back - else if(control && !shift) - write("" + (char)24); // VMS control deletes line back - else - write("" + (char)127); // VMS other is delete - } else if(keyChar == 127 && !control) { - if (shift) - write(Insert[0]); // VMS shift delete = insert - else - write(Remove[0]); // VMS delete = remove - } else if(control) - switch(keyChar) { - case '0': write(Numpad[0]); return; - case '1': write(Numpad[1]); return; - case '2': write(Numpad[2]); return; - case '3': write(Numpad[3]); return; - case '4': write(Numpad[4]); return; - case '5': write(Numpad[5]); return; - case '6': write(Numpad[6]); return; - case '7': write(Numpad[7]); return; - case '8': write(Numpad[8]); return; - case '9': write(Numpad[9]); return; - case '.': write(KPPeriod); return; - case '-': - case 31: write(KPMinus); return; - case '+': write(KPComma); return; - case 10: write(KPEnter); return; - case '/': write(PF2); return; - case '*': write(PF3); return; - } - if (shift && keyChar < 32) - write(PF1+(char)(keyChar + 64)); - return; - } - - if (debug>2) System.out.println("vt320: keyPressed "+evt+"\""+keyChar+"\""); - - String fmap[]; int xind; + String fmap[]; xind = 0; fmap = FunctionKey; if(shift) { fmap = FunctionKeyShift; xind=1; } if(control) { fmap = FunctionKeyCtrl; xind=2; } if(alt) { fmap = FunctionKeyAlt; xind=3; } - if(evt.isActionKey()) switch(keyCode) { - case KeyEvent.VK_NUMPAD0: write(Numpad[0],false); break; - case KeyEvent.VK_NUMPAD1: write(Numpad[1],false); break; - case KeyEvent.VK_NUMPAD2: write(Numpad[2],false); break; - case KeyEvent.VK_NUMPAD3: write(Numpad[3],false); break; - case KeyEvent.VK_NUMPAD4: write(Numpad[4],false); break; - case KeyEvent.VK_NUMPAD5: write(Numpad[5],false); break; - case KeyEvent.VK_NUMPAD6: write(Numpad[6],false); break; - case KeyEvent.VK_NUMPAD7: write(Numpad[7],false); break; - case KeyEvent.VK_NUMPAD8: write(Numpad[8],false); break; - case KeyEvent.VK_NUMPAD9: write(Numpad[9],false); break; - case KeyEvent.VK_DECIMAL: write(NUMDot[xind],false); break; - case KeyEvent.VK_ADD: write(NUMPlus[xind],false); break; - } - switch (keyCode) { case KeyEvent.VK_PAUSE: if (shift || control) @@ -761,42 +664,149 @@ public abstract class vt320 extends VDU implements Key case KeyEvent.VK_INSERT: write(Insert[xind],false); break; case KeyEvent.VK_DELETE: write(Remove[xind],false); break; case KeyEvent.VK_ESCAPE: write(Escape[xind],false); break; - case KeyEvent.VK_BACK_SPACE: - write(BackSpace[xind]); // do local echo in this case - break; - case KeyEvent.VK_HOME: - if(vms) - write("" + (char)8,false); - else - write(KeyHome[xind],false); - break; - case KeyEvent.VK_END: - if(vms) - write("" + (char)5,false); - else - write(KeyEnd[xind],false); - break; + case KeyEvent.VK_BACK_SPACE: write(BackSpace[xind]); break; + case KeyEvent.VK_HOME: write(KeyHome[xind],false); break; + case KeyEvent.VK_END: write(KeyEnd[xind],false); break; case KeyEvent.VK_NUM_LOCK: - if(vms && control) - if(pressedKey != keyCode) { - pressedKey = keyCode; - write(PF1,false); - } else - // Here, we eat a second numlock since that returns numlock state - pressedKey = ' '; + if(vms && control) { + writeNumpad(PF1); + } if(!control) numlock = !numlock; break; case KeyEvent.VK_CAPS_LOCK: capslock = !capslock; - break; + return; + case KeyEvent.VK_SHIFT: + case KeyEvent.VK_CONTROL: + case KeyEvent.VK_ALT: + return; default: - if(debug > 2) - System.out.println("vt320: unknown event: "+evt); break; } } + /** + * Not used. + */ + public void keyReleased(KeyEvent evt) { + // nothing to to, however maybe we should use it? + } + + /** + * Handle key Typed events for the terminal, this will get + * all normal key types, but no shift/alt/control/numlock. + * @param evt the event + */ + public void keyTyped(KeyEvent evt) { + boolean control = evt.isControlDown(); + boolean shift = evt.isShiftDown(); + boolean alt = evt.isAltDown(); + + int keyCode = evt.getKeyCode(); + char keyChar = evt.getKeyChar(); + + //System.out.println("keyTyped "+evt+",keyChar "+(int)keyChar); + + if (keyChar == '\t') { + if (shift) { + write(TabKey[1],false); + } else { if (control) { + write(TabKey[2],false); + } else { if (alt) { + write(TabKey[3],false); + } else { + write(TabKey[0],false); + }}} + return; + } + if (alt) { + write(""+((char)(keyChar|0x80))); + return; + } + + if( ((keyCode == KeyEvent.VK_ENTER) || (keyChar == 10)) && !control) { + write("\n",false); + if (localecho) putString("\r\n"); // bad hack + } + + // FIXME: on german PC keyboards you have to use Alt-Ctrl-q to get an @, + // so we can't just use it here... will probably break some other VMS + // codes. -Marcus + // if(((!vms && keyChar == '2') || keyChar == '@' || keyChar == ' ') + // && control) + if (((!vms && keyChar == '2') || keyChar == ' ') && control) + write("" + (char)0); + + if(vms) { + if(keyChar == 127 && !control) { + if (shift) + writeNumpad(Insert[0]); // VMS shift delete = insert + else + writeNumpad(Remove[0]); // VMS delete = remove + return; + } else if(control) + switch(keyChar) { + case '0': writeNumpad(Numpad[0]); return; + case '1': writeNumpad(Numpad[1]); return; + case '2': writeNumpad(Numpad[2]); return; + case '3': writeNumpad(Numpad[3]); return; + case '4': writeNumpad(Numpad[4]); return; + case '5': writeNumpad(Numpad[5]); return; + case '6': writeNumpad(Numpad[6]); return; + case '7': writeNumpad(Numpad[7]); return; + case '8': writeNumpad(Numpad[8]); return; + case '9': writeNumpad(Numpad[9]); return; + case '.': writeNumpad(KPPeriod); return; + case '-': + case 31: writeNumpad(KPMinus); return; + case '+': writeNumpad(KPComma); return; + case 10: writeNumpad(KPEnter); return; + case '/': writeNumpad(PF2); return; + case '*': writeNumpad(PF3); return; + /* NUMLOCK handled in keyPressed */ + default: + break; + } + /* Now what does this do and how did it get here. -Marcus + if (shift && keyChar < 32) { + write(PF1+(char)(keyChar + 64)); + return; + } + */ + } + + if (debug>2) System.out.println("vt320: keyPressed "+evt+"\""+keyChar+"\""); + + String fmap[]; + int xind; + xind = 0; + fmap = FunctionKey; + if(shift) { fmap = FunctionKeyShift; xind=1; } + if(control) { fmap = FunctionKeyCtrl; xind=2; } + if(alt) { fmap = FunctionKeyAlt; xind=3; } + + if(evt.isActionKey()) switch(keyCode) { + case KeyEvent.VK_NUMPAD0: write(Numpad[0],false); return; + case KeyEvent.VK_NUMPAD1: write(Numpad[1],false); return; + case KeyEvent.VK_NUMPAD2: write(Numpad[2],false); return; + case KeyEvent.VK_NUMPAD3: write(Numpad[3],false); return; + case KeyEvent.VK_NUMPAD4: write(Numpad[4],false); return; + case KeyEvent.VK_NUMPAD5: write(Numpad[5],false); return; + case KeyEvent.VK_NUMPAD6: write(Numpad[6],false); return; + case KeyEvent.VK_NUMPAD7: write(Numpad[7],false); return; + case KeyEvent.VK_NUMPAD8: write(Numpad[8],false); return; + case KeyEvent.VK_NUMPAD9: write(Numpad[9],false); return; + case KeyEvent.VK_DECIMAL: write(NUMDot[xind],false); return; + case KeyEvent.VK_ADD: write(NUMPlus[xind],false); return; + } + + if (!((keyChar == 8) || (keyChar == 127) || (keyChar =='\r') || (keyChar == '\n'))) { + write(""+keyChar); + return; + } + } + private void handle_dcs(String dcs) { System.out.println("DCS: "+dcs); } @@ -1403,6 +1413,21 @@ public abstract class vt320 extends VDU implements Key dcs=""; term_state = TSTATE_DCS; break; + case 'A': /* CUU */ + R--; + if (R<0) R=0; + break; + case 'B': /* CUD */ + R++; + if (R>rows-1) R=rows-1; + break; + case 'C': + C++; + if (C>=columns) C=columns-1; + break; + case 'I': // RI + insertLine(R,1,SCROLL_DOWN); + break; case 'E': /* NEL */ if (R == bm || R == rows - 1) insertLine(R,1,SCROLL_UP); @@ -1420,6 +1445,16 @@ public abstract class vt320 extends VDU implements Key if (debug>1) System.out.println("ESC D (at "+R+" )"); break; + case 'J': /* erase to end of screen */ + if (Rbm) // outside scrolling region break; @@ -1510,11 +1545,22 @@ public abstract class vt320 extends VDU implements Key gr = 3; usedcharsets = true; break; + case 'Y': /* vt52 cursor address mode , next chars are x,y */ + term_state = TSTATE_VT52Y; + break; default: System.out.println("ESC unknown letter: ("+((int)c)+")"); break; } break; + case TSTATE_VT52X: + C = c-37; + term_state = TSTATE_VT52Y; + break; + case TSTATE_VT52Y: + R = c-37; + term_state = TSTATE_DATA; + break; case TSTATE_SETG0: if(c!='0' && c!='A' && c!='B' && c!='<') System.out.println("ESC ( "+c+": G0 char set? ("+((int)c)+")"); @@ -1644,6 +1690,10 @@ public abstract class vt320 extends VDU implements Key KeyRight[0]= "\u001bOC"; KeyLeft[0] = "\u001bOD"; break; + case 2: /* DECANM */ + vt52mode = true; + System.out.println("vt52 mode enabled"); + break; case 3: /* 132 columns*/ size = getSize(); setScreenSize(132,rows); @@ -1710,6 +1760,10 @@ public abstract class vt320 extends VDU implements Key KeyRight[0]= "\u001b[C"; KeyLeft[0] = "\u001b[D"; break; + case 2: /* DECANM */ + vt52mode = false; + System.out.println("vt52 mode disabled"); + break; case 3: /* 80 columns*/ size = getSize(); setScreenSize(80,rows);