diff --git a/macssh/MacSSH.mcp b/macssh/MacSSH.mcp index 30cb135..4a86bda 100755 Binary files a/macssh/MacSSH.mcp and b/macssh/MacSSH.mcp differ diff --git a/macssh/source/Headers/Vers.h b/macssh/source/Headers/Vers.h index 16e32aa..1563686 100755 --- a/macssh/source/Headers/Vers.h +++ b/macssh/source/Headers/Vers.h @@ -11,7 +11,7 @@ #define VMajor 2 #define VMinor (1 * 16) + 0 #define VStage beta -#define VRelease 5 -#define VShortString "2.1b5" +#define VRelease 6 +#define VShortString "2.1b6" #define CopyrightString "©2000-2001 J.-P. Stierlin" diff --git a/macssh/source/Linemode/linemode.c b/macssh/source/Linemode/linemode.c index b5020e1..63583f5 100755 --- a/macssh/source/Linemode/linemode.c +++ b/macssh/source/Linemode/linemode.c @@ -72,41 +72,29 @@ void initLinemode(struct WindRec *tw) void process_key(unsigned char ascii,struct WindRec *tw) { - if (tw->litNext) //do no processing on next key - { + if (tw->litNext) { + //do no processing on next key tw->litNext = FALSE; - if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ - tw->kbbuf[tw->kblen++] = ascii; - else - { - netpush(tw->port); - netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ - tw->kbbuf[0]=ascii; - tw->kblen=1; - } - if (tw->echo) - { - if (ascii>31 && ascii <127) /* add these chars to buffer */ - { + + kbwrite(tw, &ascii, 1); + + if (tw->echo) { + if (ascii>31 && ascii <127) { + /* add these chars to buffer */ parse(tw, &ascii, 1); - return; } - else - return; + return; } } - if (tw->lmodeBits & 2) // TRAPSIG mode active - { + if (tw->lmodeBits & 2) { + // TRAPSIG mode active unsigned char toSend[2] = {IAC,0}; short whichSignal = 0; - if (ascii == tw->slc[SLC_IP]) - { + if (ascii == tw->slc[SLC_IP]) { whichSignal = SLC_IP; - toSend[1] = TEL_IP; // RAB BetterTelnet 2.0b1 - } - else if (ascii == tw->slc[SLC_SUSP]) // RAB BetterTelnet 2.0b1 - { + toSend[1] = TEL_IP; + } else if (ascii == tw->slc[SLC_SUSP]) { whichSignal = SLC_SUSP; toSend[1] = TEL_SUSP; } @@ -151,19 +139,9 @@ void process_key(unsigned char ascii,struct WindRec *tw) if ((tw->lmodeBits & L_SOFT_TAB)&&(ascii == 0x09)) // SOFT_TAB mode active; expand tab into spaces { short numSpaces = VSIgetNextTabDistance(); - while (numSpaces > 0) - { - while ((numSpaces > 0)&&(tw->kblen < (MAXKB -1))) - { - tw->kbbuf[tw->kblen++] = 0x20; //space - numSpaces--; - } - if (tw->kblen == (MAXKB -1)) - { - netpush(tw->port); - netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ - tw->kblen=0; - } + unsigned char spacechar = ' '; + while (numSpaces > 0) { + kbwrite(tw, &spacechar, 1); } if (tw->echo) parse(tw, &ascii, 1); @@ -178,11 +156,9 @@ void process_key(unsigned char ascii,struct WindRec *tw) if (ascii == '\015') //CR { //since we are in edit, send the buffer and CR-LF - if (tw->kblen > 0) - netwrite(tw->port, tw->kbbuf, tw->kblen); + kbflush(tw); netpush(tw->port); netwrite(tw->port,"\015\012",2); - tw->kblen = 0; if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; @@ -218,8 +194,7 @@ void process_key(unsigned char ascii,struct WindRec *tw) else if ((ascii == tw->slc[SLC_EOF]) && (tw->lmodeBits & 2)) { //push the buffer, send IAC EOF (RAB BetterTelnet 2.0b1 - only under TRAPSIG) char eofString[2] = { IAC, TEL_EOF }; - if (tw->kblen > 0) - netwrite(tw->port, tw->kbbuf, tw->kblen); + kbflush(tw); // RAB BetterTelnet 2.0b1 - BAD! BAD! BAD! // Fix for *BSD (and probably others): // Putting ^D into Telnet's key buffer after sending an EOF could make it pop up later, so @@ -227,7 +202,6 @@ void process_key(unsigned char ascii,struct WindRec *tw) // after a cat command which terminated with ^D caused a logout. Yuck. // tw->kbbuf[0]=ascii; // tw->kblen=1; - tw->kblen = 0; netpush(tw->port); netwrite(tw->port,eofString, 2); return; @@ -282,26 +256,15 @@ void process_key(unsigned char ascii,struct WindRec *tw) } else if ((ascii == tw->slc[SLC_FORW1])||(ascii == tw->slc[SLC_FORW1])) { - if (tw->kblen > 0) - netwrite(tw->port, tw->kbbuf, tw->kblen); - netpush(tw->port); + kbflush(tw); netwrite(tw->port,&ascii,1); - tw->kblen = 0; return; } //ok, at this point, we are past all local editing functions. Now, add the character to the buffer. else { - if (tw->kblen < (MAXKB -1)) // Add to buffer if not full - tw->kbbuf[tw->kblen++] = ascii; - else - { - netpush(tw->port); - netwrite( tw->port, tw->kbbuf, tw->kblen); // if full send buffer - tw->kbbuf[0]=ascii; - tw->kblen=1; - } + kbwrite(tw, &ascii, 1); } } diff --git a/macssh/source/Preferences/prefs.c b/macssh/source/Preferences/prefs.c index 81896b7..9b96d24 100755 --- a/macssh/source/Preferences/prefs.c +++ b/macssh/source/Preferences/prefs.c @@ -16,6 +16,7 @@ #include "prefs.proto.h" #include "mainseg.proto.h" // For quit proto #include "errors.proto.h" +#include "DlogUtils.proto.h" FTPServerPrefs* gFTPServerPrefs=NULL; ApplicationPrefs* gApplicationPrefs=NULL; @@ -90,8 +91,8 @@ OSErr NewPreferences(void) { ApplicationPrefs **AppPrefsHdl; FTPServerPrefs **FTPPrefsHdl; - SessionPrefs **DefaultSessionPrefs; - TerminalPrefs **DefaultTerminalPrefs; + SessionPrefs **sessPrefs; + TerminalPrefs **termPrefs; // Get the master copies from the application's resource fork @@ -103,13 +104,34 @@ OSErr NewPreferences(void) if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); DetachResource((Handle)FTPPrefsHdl); - DefaultSessionPrefs = (SessionPrefs **)GetResource(SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID); - if ((ResError() != noErr) || (DefaultSessionPrefs == NULL)) return(ResError()); - DetachResource((Handle)DefaultSessionPrefs); + sessPrefs = (SessionPrefs **)GetResource(SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID); + if ((ResError() != noErr) || (sessPrefs == NULL)) return(ResError()); + DetachResource((Handle)sessPrefs); - DefaultTerminalPrefs = (TerminalPrefs **)GetResource(TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID); - if ((ResError() != noErr) || (DefaultTerminalPrefs == NULL)) return(ResError()); - DetachResource((Handle)DefaultTerminalPrefs); + termPrefs = (TerminalPrefs **)GetResource(TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID); + if ((ResError() != noErr) || (termPrefs == NULL)) return(ResError()); + DetachResource((Handle)termPrefs); + + // update a few settings + HLock((Handle)sessPrefs); + HLock((Handle)termPrefs); + if ( GetScriptManagerVariable(smRegionCode) == verJapan ) { + short familyID; + unsigned char *jpfont = "\posaka"; + GetFNum( jpfont, &familyID ); + if ( familyID ) { + (**termPrefs).fontsize = 12; + (**termPrefs).boldFontSize = 12; + pstrcpy( (**termPrefs).DisplayFont, jpfont ); + pstrcpy( (**termPrefs).BoldFont, jpfont ); + } +#if GENERATINGPOWERPC + // WARNING: this string must match the one in BuildTranslateMenu + pstrcpy( (**sessPrefs).TranslationTable, "\pJIS (ISO-2022-JP)" ); +#endif + } + HUnlock((Handle)sessPrefs); + HUnlock((Handle)termPrefs); // Add them to the Preferences file @@ -119,9 +141,9 @@ OSErr NewPreferences(void) if (ResError() != noErr) return(ResError()); AddResource((Handle)FTPPrefsHdl,FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID, "\p"); if (ResError() != noErr) return(ResError()); - AddResource((Handle)DefaultSessionPrefs,SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID, "\p"); + AddResource((Handle)sessPrefs,SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); - AddResource((Handle)DefaultTerminalPrefs,TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID, "\p"); + AddResource((Handle)termPrefs,TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); // Update the preferences file and release the resources @@ -129,8 +151,8 @@ OSErr NewPreferences(void) UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)AppPrefsHdl); ReleaseResource((Handle)FTPPrefsHdl); - ReleaseResource((Handle)DefaultSessionPrefs); - ReleaseResource((Handle)DefaultTerminalPrefs); + ReleaseResource((Handle)sessPrefs); + ReleaseResource((Handle)termPrefs); return(ResError()); } diff --git a/macssh/source/Screens/rsdefs.h b/macssh/source/Screens/rsdefs.h index 9a6bf44..10ce036 100755 --- a/macssh/source/Screens/rsdefs.h +++ b/macssh/source/Screens/rsdefs.h @@ -28,14 +28,15 @@ #define CVO 0 #define CHO (-2) -#define LOCKWIDTH 16 +#define LOCKWIDTH 16 // width of the ssh locker #define CURS_BLINK_PERIOD 30 +#define INFINITY 32000 // Will screens ever be this large? +#define WINDCOLORSIZE 4 +#define ANSICOLORSIZE 16 +#define PALETTESIZE (WINDCOLORSIZE + ANSICOLORSIZE) -#define INFINITY 20000 // Will screens ever be this large? -#define MAXATTR 16 -#define PALSIZE (MAXATTR*2+4*2) //this is ANSI colors plus our four. /*------------------------------------------------------------------------*/ /* Now we have some externs, packed away neatly from the rest of the code */ @@ -98,6 +99,8 @@ struct RSdata { active; /* true if window is currently active */ short cursType; + RGBColor + savedColors[16]; }; typedef struct RSdata RSdata; diff --git a/macssh/source/Screens/rsinterf.c b/macssh/source/Screens/rsinterf.c index 882d37e..842593c 100755 --- a/macssh/source/Screens/rsinterf.c +++ b/macssh/source/Screens/rsinterf.c @@ -14,6 +14,7 @@ #include "rsdefs.h" #include "vsdata.h" +#include "vskeys.h" #include "wind.h" #include "rsmac.proto.h" #include "vsinterf.proto.h" @@ -97,84 +98,103 @@ void RSselect( short w, Point pt, EventRecord theEvent) static long lastClick = 0; static Point lastClickLoc = {0,0}; GrafPtr tempwndo; - Point curr, temp; + Point curr, temp, lastm; long clickTime; short shift = (theEvent.modifiers & shiftKey); + VSAttrib attrib; + + RSsetConst(w); tempwndo = RSlocal[w].window; curr = normalize(pt, w, TRUE); clickTime = LMGetTicks(); - if ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) ) - && ((clickTime - lastClick) <= GetDblTime()) - && EqualPt(curr, lastClickLoc)) { + if ( (EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last)) + && clickTime - lastClick <= GetDblTime() + && EqualPt(curr, lastClickLoc) ) { /* NCSA: SB - check to see if this is a special click */ /* NCSA: SB - It has to be in the right time interval, and in the same spot */ - curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); + curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w, TRUE); HandleDoubleClick(w, theEvent.modifiers); RSlocal[w].selected = 1; lastClick = clickTime; lastClickLoc = curr; - } - else if (theEvent.modifiers & cmdKey) - { // a command click means we should look for a url - if ( RSTextSelected(w) && PointInSelection(curr, w) ) //we have a selection already + } else if ((theEvent.modifiers & cmdKey)) { + // a command click means we should look for a url + if ( RSTextSelected(w) && PointInSelection(curr, w) ) { + // we have a selection already HandleURL(w); - else - { // we need to find the url around this pnt + } else { + // we need to find the url around this pnt if (FindURLAroundPoint(curr, w)) HandleURL(w); else SysBeep(1); } - } - else { + } else { lastClick = clickTime; lastClickLoc = curr; if (RSlocal[w].selected) { if (!shift) { RSlocal[w].selected = 0; - /* unhighlight current selection */ - RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); - /* start new selection */ - curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w,TRUE); - } - else { + // unhighlight current selection + RSinvText(w, RSlocal[w].anchor, RSlocal[w].last, &noConst); + // start new selection + curr = normalize(pt, w, TRUE); + RSlocal[w].last = RSlocal[w].anchor = curr; + } else { RSsortAnchors(w); if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; + } + } + } else { + // start new selection + curr = normalize(pt, w, TRUE); + RSlocal[w].anchor = RSlocal[w].last = curr; + } + + if (EqualPt(RSlocal[w].anchor, RSlocal[w].last) && RSlocal[w].anchor.h > -1) { + if (VSgetattr(w, RSlocal[w].anchor.h - 1, curr.v, RSlocal[w].anchor.h, curr.v, &attrib, sizeof(VSAttrib))) { + if (VSisansi2b(attrib)) { + --RSlocal[w].anchor.h; + --RSlocal[w].last.h; + } + } + } + + while ( StillDown() ) { + // wait for mouse position to change + do { + temp = getlocalmouse(tempwndo); + curr = normalize(temp, w,TRUE); + if ( curr.h > -1 ) { + if (VSgetattr(w, curr.h - 1, curr.v, curr.h, curr.v, &attrib, sizeof(VSAttrib))) { + if (VSisansi2b(attrib)) { + ++curr.h; + } } } - } - else - { - /* start new selection */ - curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); + } while (StillDown() && (EqualPt(curr, RSlocal[w].last) || EqualPt(pt, temp))); + if ( !EqualPt(pt, temp) ) { + // toggle highlight state of text between current and last mouse positions + RSinvText(w, curr, RSlocal[w].last, &noConst); + RSlocal[w].last = curr; + pt = temp; } - - while (StillDown()) - { - /* wait for mouse position to change */ - do { - curr = normalize(getlocalmouse(tempwndo), w,TRUE); - } while (EqualPt(curr, RSlocal[w].last) && StillDown()); - - /* toggle highlight state of text between current and last mouse positions */ - RSinvText(w, curr, RSlocal[w].last, &noConst); - RSlocal[w].last = curr; - } /* while */ } + } RSlocal[w].selected = !EqualPt(RSlocal[w].anchor, RSlocal[w].last); SetMenusForSelection((short)RSlocal[w].selected); - } /* RSselect */ - - void FlashSelection(short w) - { +} // RSselect + +void FlashSelection(short w) +{ short i; DELAYLONG finalTick; for (i = 0; i < 2; i++) { @@ -183,7 +203,8 @@ void RSselect( short w, Point pt, EventRecord theEvent) Delay(5, &finalTick); RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); } - } +} + Boolean PointInSelection(Point curr, short w) { long beg_offset, end_offset, current_offset; @@ -231,19 +252,19 @@ void RSzoom ZoomWindow(window, code, shifted); EraseRect(&window->portRect); /* BYU 2.4.15 */ - /* get new window size */ + /* get new window size */ h = window->portRect.right - window->portRect.left; v = window->portRect.bottom - window->portRect.top; RSsetsize(w, v, h, -1); /* save new size settings and update scroll bars */ - /* update the visible region of the virtual screen */ + /* update the visible region of the virtual screen */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1), (y1 + (v - 16 + CVO) / FHeight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ - /* refresh the part which has been revealed, if any */ + /* refresh the part which has been revealed, if any */ VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); - /* window contents are now completely valid */ + /* window contents are now completely valid */ ValidRect(&window->portRect); } /* RSzoom */ @@ -260,8 +281,8 @@ void RSdrawlocker(short w, RgnHandle visRgn) { /* draw locker icon */ if ( RSlocal[w].left ) { - short screenIndex = findbyVS(w); - if ( screenIndex >= 0 && screens[screenIndex].protocol == 4 ) { + short sn = findbyVS(w); + if ( sn >= 0 && screens[sn].protocol == 4 ) { Rect iconRect = (**RSlocal[w].left).contrlRect; iconRect.top += 1; iconRect.right = iconRect.left; @@ -410,8 +431,8 @@ short RSsize (GrafPtr window, long *where, long modifiers) short w, width, lines; short tw, h, v, x1, x2, y1, y2, th; Boolean changeVSSize = false; - short screenIndex = 0; - Boolean screenIndexValid = false; + short sn = 0; + Boolean snValid = false; short err = noErr; short cwidth; short oldlines; @@ -422,7 +443,7 @@ short RSsize (GrafPtr window, long *where, long modifiers) if (modifiers & cmdKey) return (0); - screenIndexValid = (screenIndex = findbyVS(w)) != -1; + snValid = (sn = findbyVS(w)) >= 0; /* NONO */ /* inverted window-resize behaviour */ @@ -435,7 +456,7 @@ short RSsize (GrafPtr window, long *where, long modifiers) // should be used by default, and option toggles behaviour. // Maybe it should be user configurable? #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS - if(screenIndexValid && screens[screenIndex].naws) { + if(snValid && screens[sn].naws) { /* NONO */ /* inverted window-resize behaviour */ /*changeVSSize = (modifiers & optionKey) != optionKey;*/ @@ -486,7 +507,7 @@ short RSsize (GrafPtr window, long *where, long modifiers) SizeWindow(window, h, v, FALSE); /* change it */ } - RSsetsize(w, v, h, screenIndex); /* save new size settings and update scroll bars */ + RSsetsize(w, v, h, sn); /* save new size settings and update scroll bars */ /* update the visible region of the virtual screen */ @@ -523,13 +544,13 @@ short RSsize (GrafPtr window, long *where, long modifiers) cwidth = 255; } RScalcwsize(w,cwidth); - if (screenIndexValid + if (snValid && (oldlines != VSgetlines(w) || oldcols != VSgetcols(w)) ) { - if (screens[screenIndex].naws) { - SendNAWSinfo(&screens[screenIndex], cwidth, (y2-y1+1)); + if (screens[sn].naws) { + SendNAWSinfo(&screens[sn], cwidth, (y2-y1+1)); } - if (screens[screenIndex].protocol == 4) { - ssh_glue_wresize(&screens[screenIndex]); + if (screens[sn].protocol == 4) { + ssh_glue_wresize(&screens[sn]); } } return (0); @@ -554,16 +575,36 @@ void RSshow( short w) /* reveals a hidden terminal window. */ ShowWindow(RScurrent->window); } +/* + * RSresetcolors: back to default ANSI colors + */ + +void RSresetcolors( short w ) +{ + int i; + + if ( !TelInfo->haveColorQuickDraw || RSsetwind(w) < 0 ) + return; + + for ( i = 0; i < ANSICOLORSIZE; i++ ) { + SetEntryColor(RScurrent->pal, i + WINDCOLORSIZE, &RScurrent->savedColors[i]); + } +} + +/* + * RSsetcolors: change one of the window/ANSI colors + */ + Boolean RSsetcolors ( short w, /* window number */ short n, /* color entry number */ - RGBColor *color + RGBColor *color ) /* sets a new value for the specified color entry of a terminal window. */ { - if ( !(TelInfo->haveColorQuickDraw) || (RSsetwind(w) < 0) || (n > 15) || (n < 0)) - return(FALSE); + if ( !TelInfo->haveColorQuickDraw || RSsetwind(w) < 0 || n < 0 || n >= PALETTESIZE ) + return FALSE; SetEntryColor(RScurrent->pal, n, color); @@ -595,7 +636,7 @@ Boolean RSsetcolors return(TRUE); } /* RSsetcolors */ - void RSsendstring +void RSsendstring ( short w, /* which terminal window */ char *ptr, /* pointer to data */ @@ -603,15 +644,18 @@ Boolean RSsetcolors ) /* sends some data to the host along the connection associated with the specified window. */ - { - short temp; +{ + short sn; + WindRecPtr tw; - temp = findbyVS(w); - if (temp < 0) + sn = findbyVS(w); + if (sn) return; - netpush(screens[temp].port); /* BYU 2.4.18 - for Diab systems? */ - netwrite(screens[temp].port, ptr, len); - } /* RSsendstring */ + tw = &screens[sn]; + netpush(tw->port); /* BYU 2.4.18 - for Diab systems? */ + netwrite(tw->port, ptr, len); +} /* RSsendstring */ + short RSnewwindow @@ -621,26 +665,17 @@ short RSnewwindow short width, /* number of characters per text line (80 or 132) */ short lines, /* number of text lines */ StringPtr name, /* window name */ - short wrapon, /* autowrap on by default */ short fnum, /* ID of font to use initially */ short fsiz, /* size of font to use initially */ - short showit, /* window initially visible or not */ - short goaway, /* NCSA 2.5 */ - short forcesave, /* NCSA 2.5: force screen save */ short screenNumber, - short allowBold, - short colorBold, - short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, - short realbold, - short oldScrollback, - short jump, - short realBlink + short vtemulation, + unsigned long flags ) /* creates a virtual screen and a window to display it in. */ - { +{ GrafPort gp; /* temp port for getting text parameters */ short w; @@ -653,13 +688,14 @@ short RSnewwindow WindowPeek front; WindowPtr behind; - /* create the virtual screen */ - w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */ - lines, width, forcesave, ignoreBeeps, oldScrollback, jump, realBlink); /* NCSA 2.5 */ + /* create the virtual screen */ + w = VSnewscreen(vtemulation, scrollback, (scrollback != 0), /* NCSA 2.5 */ + lines, width, flags & RSWforcesave, flags & RSWignoreBeeps, + flags & RSWsavelines, flags & RSWjumpscroll, flags & RSWrealBlink); if (w < 0) { /* problems opening the virtual screen -- tell us about it */ return(-1); - } - + } + RScurrent = RSlocal + w; RScurrent->fnum = fnum; @@ -669,9 +705,9 @@ short RSnewwindow RScurrent->bfstyle = bfstyle; OpenPort(&gp); - RScurrent->allowBold = allowBold; - RScurrent->colorBold = colorBold; - RScurrent->realbold = realbold; + RScurrent->allowBold = flags & RSWallowBold; + RScurrent->colorBold = flags & RSWcolorBold; + RScurrent->realbold = flags & RSWrealbold; RSTextFont(fnum,fsiz,0); /* BYU */ TextSize(fsiz); RSfontmetrics(); @@ -700,26 +736,30 @@ short RSnewwindow /* create the window */ if (!TelInfo->haveColorQuickDraw) { - RScurrent->window = NewWindow(0L, wDims, name, showit, 8,behind, goaway, (long)w); + RScurrent->window = NewWindow(0L, wDims, name, flags & RSWshowit, 8,behind, flags & RSWgoaway, (long)w); RScurrent->pal = NULL; if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } } else { - RGBColor scratchRGB; - - RScurrent->window = NewCWindow(0L, wDims, name, showit, 8,behind, goaway, (long)w); + if ( TelInfo->AnsiColors == NULL ) { + VSdestroy(w); + return(-2); + } + + RScurrent->window = NewCWindow(0L, wDims, name, flags & RSWshowit, 8,behind, flags & RSWgoaway, (long)w); if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } + //note: the ANSI colors are in the top 8 of the palette. The four telnet colors (settable //in telnet) are in the lower 4 of the palette. These 4 are set later by a call from //CreateConnectionFromParams to RSsetColor (ick, but I am not going to add 4 more params to //this ungodly function call (CCP 2.7) ourColorTableHdl = (CTabHandle) myNewHandle((long) (sizeof(ColorTable) + - PALSIZE * sizeof(CSpecArray))); + (PALETTESIZE - 1) * sizeof(CSpecArray))); if (ourColorTableHdl == NULL) { DisposeWindow(RScurrent->window); @@ -728,25 +768,24 @@ short RSnewwindow } HLock((Handle) ourColorTableHdl); - (*ourColorTableHdl)->ctSize = PALSIZE-1; // Number of entries minus 1 + (*ourColorTableHdl)->ctSize = PALETTESIZE - 1; // Number of entries minus 1 (*ourColorTableHdl)->ctFlags = 0; - for (i=0; i <4; i++) //set the ctTable.value field to zero for our four + for (i = 0; i < WINDCOLORSIZE; i++) // set the ctTable.value field to zero for our four (*ourColorTableHdl)->ctTable[i].value = 0; - if (TelInfo->AnsiColors==NULL) - return(-2); //BUGG CHANGE THIS ONCE WE ARE WORKING - - for (i=0; i < MAXATTR*2; i++) //get the ANSI colors from the palette - { - GetEntryColor(TelInfo->AnsiColors, i, &(*ourColorTableHdl)->ctTable[i+4].rgb); - (*ourColorTableHdl)->ctTable[i+4].value = 0; + for (i = 0; i < ANSICOLORSIZE; i++) { + // get the ANSI colors from the palette + GetEntryColor(TelInfo->AnsiColors, i, &(*ourColorTableHdl)->ctTable[i + WINDCOLORSIZE].rgb); + (*ourColorTableHdl)->ctTable[i + WINDCOLORSIZE].value = 0; + RScurrent->savedColors[i] = (*ourColorTableHdl)->ctTable[i + WINDCOLORSIZE].rgb; } - - RScurrent->pal = NewPalette(PALSIZE, ourColorTableHdl, pmCourteous, 0); - DisposeHandle((Handle) ourColorTableHdl); - if (RScurrent->pal == NULL) - { + + RScurrent->pal = NewPalette(PALETTESIZE, ourColorTableHdl, pmCourteous, 0); + + DisposeHandle((Handle)ourColorTableHdl); + + if (RScurrent->pal == NULL) { DisposeWindow(RScurrent->window); VSdestroy(w); return(-2); @@ -772,8 +811,6 @@ short RSnewwindow pRect.bottom = pRect.top + RMAXWINDOWHEIGHT; -/* BlockMoveData(&wstate->stdState, &pRect, 8); uh ? */ - /* create scroll bars for window */ pRect.top = -1 + CVO; pRect.bottom = wheight - 14 + CVO; @@ -820,7 +857,7 @@ short RSnewwindow else TextMode(srcCopy); - if (wrapon) + if (flags & RSWwrapon) /* turn on autowrap */ VSwrite(w, "\033[?7h",5); @@ -844,10 +881,14 @@ void RSkillwindow ) /* closes a terminal window. */ { + short sn; WindRecPtr tw; RSdata *temp; - tw = &screens[findbyVS(w)]; + sn = findbyVS(w); + if ( sn < 0 ) + return; + tw = &screens[sn]; --((*topLeftCorners)[tw->positionIndex]); //one less window at this position @@ -917,14 +958,14 @@ char **RSGetTextSel if (realsiz < 0) realsiz = - realsiz; realsiz ++; /* lines 2,3 selected can be 2 lines */ - realsiz *= (maxwid + 2); + realsiz *= (maxwid * 2 + 2); charh = myNewHandle(realsiz); if (charh == 0L) return((char **) -1L); /* Boo Boo return */ HLock((Handle)charh); charp = *charh; realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v, - charp, realsiz, "\015", table); + charp, realsiz, "\015", table, 1); HUnlock((Handle)charh); mySetHandleSize((Handle)charh, realsiz); return(charh); @@ -1058,19 +1099,53 @@ short RSfindvwind return(i); } /* RSfindvwind */ -void RSdeactivate - ( - short w - ) - /* handles a deactivate event for the specified window. */ - { + +/* + * RSactivate + * + * handles an activate event for the specified window + */ + +void RSactivate( short w ) +{ + RSsetConst(w); + /* display the grow icon */ + DrawGrowIcon(RSlocal[w].window); + /* and activate the scroll bars */ + if (RSlocal[w].scroll != 0L) { + ShowControl(RSlocal[w].scroll); + } + if (RSlocal[w].left != 0L) { + ShowControl(RSlocal[w].left); + } + + RSlocal[w].active = 1; + + if ( gApplicationPrefs->BlinkCursor ) { + TelInfo->blinktime = LMGetTicks() - CURS_BLINK_PERIOD; + } +} /* RSactivate */ + + +/* + * RSdeactivate + * + * handles a deactivate event for the specified window + */ + +void RSdeactivate( short w ) +{ GrafPtr port; GetPort(&port); SetPort(RSlocal[w].window); RSsetConst(w); - RScursoff(w); + RSlocal[w].active = 0; + + if ( gApplicationPrefs->BlinkCursor ) { + RScursoff( w ); + } BackColor(whiteColor); @@ -1091,8 +1166,6 @@ void RSdeactivate BackColor(blackColor); } - RSlocal[w].active = 0; - SetPort(port); } /* RSdeactivate */ @@ -1120,7 +1193,12 @@ void RScursblink( short w ) { unsigned long now; - if (VSvalids(w) || !VSIcursorvisible()) + if (!gApplicationPrefs->BlinkCursor + || VSvalids(w) + || !VSIcursorvisible() + || ((!RSlocal[w].active + || TelInfo->suspended) + && !RSlocal[w].cursorstate)) return; if ( (now = LMGetTicks()) - TelInfo->blinktime >= CURS_BLINK_PERIOD ) { GrafPtr savePort; @@ -1140,10 +1218,14 @@ void RScursblink( short w ) void RScursblinkon( short w ) { - if (VSvalids(w) || !VSIcursorvisible()) + if (!gApplicationPrefs->BlinkCursor + || VSvalids(w) + || !VSIcursorvisible() + || !RSlocal[w].active + || TelInfo->suspended) return; TelInfo->blinktime = LMGetTicks(); - if (!RSlocal[w].cursorstate) { + if ( !RSlocal[w].cursorstate ) { GrafPtr savePort; GetPort(&savePort); RSlocal[w].cursorstate = 1; @@ -1160,9 +1242,10 @@ void RScursblinkon( short w ) void RScursblinkoff( short w ) { - if (VSvalids(w) || !VSIcursorvisible()) + + if (!gApplicationPrefs->BlinkCursor || VSvalids(w) || !VSIcursorvisible()) return; - if (RSlocal[w].cursorstate) { + if ( RSlocal[w].cursorstate ) { GrafPtr savePort; GetPort(&savePort); RSlocal[w].cursorstate = 0; @@ -1301,7 +1384,7 @@ void RScalcwsize(short w, short width) ValidRect(&RScurrent->window->portRect); /* no need to do it again */ DrawControls(RScurrent->window); - RScursoff(w); +// RScursoff(w); } /* handles a click in a terminal window. */ @@ -1385,25 +1468,6 @@ short RSclick( GrafPtr window, EventRecord theEvent) 0; } /* RSclick */ -void RSactivate - ( - short w - ) - /* handles an activate event for the specified window. */ - { - RSsetConst(w); - /* display the grow icon */ - DrawGrowIcon(RSlocal[w].window); - /* and activate the scroll bars */ - if (RSlocal[w].scroll != 0L) { - ShowControl(RSlocal[w].scroll); - } - if (RSlocal[w].left != 0L) { - ShowControl(RSlocal[w].left); - } - RSlocal[w].active = 1; - } /* RSactivate */ - /*--------------------------------------------------------------------------*/ /* HandleDoubleClick */ /* This is the routine that does the real dirty work. Since it is not a */ @@ -1417,111 +1481,126 @@ static void HandleDoubleClick(short w, short modifiers) Point leftLoc, rightLoc, curr, oldcurr; long mySize; char theChar[5]; - short mode = -1, newmode, foundEnd=0; - RSsetConst(w); /* get window dims */ - leftLoc = RSlocal[w].anchor; /* these two should be the same */ + short mode = -1, newmode, foundEnd=0; + Point pt; + Point temp; + VSAttrib attrib; + + + RSsetConst(w); // get window dims + leftLoc = RSlocal[w].anchor; // these two should be the same rightLoc = RSlocal[w].last; - while(!foundEnd) /* scan to the right first */ + while(!foundEnd) // scan to the right first { mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v, - theChar,(long)1,"\015",0); - if(mySize ==0 || isspace(*theChar)) /* stop if not a letter */ + theChar, (long)1, "\015", 0, 0); + if(mySize ==0 || isspace(*theChar)) // stop if not a letter foundEnd =1; else rightLoc.h++; } foundEnd =0; - while(!foundEnd) /* ...and then scan to the left */ + while(!foundEnd) // ...and then scan to the left { mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v, - theChar,(long)1,"\015",0); - if(mySize ==0 || isspace(*theChar)) /* STOP! */ + theChar, (long)1, "\015", 0, 0); + if(mySize ==0 || isspace(*theChar)) // STOP! foundEnd =1; else leftLoc.h--; } - if (leftLoc.h != rightLoc.h) { /* we selected something */ + if (leftLoc.h != rightLoc.h) { // we selected something HiliteThis(w, leftLoc, rightLoc); - if (modifiers & cmdKey) // Possible URL selection + if (modifiers & cmdKey) // Possible URL selection HandleURL(w); else { curr.h = 0; curr.v = 0; + pt = getlocalmouse(RSlocal[w].window); while (StillDown()) { - /* wait for mouse position to change */ + // wait for mouse position to change do { oldcurr = curr; - curr = normalize(getlocalmouse(RSlocal[w].window), w,TRUE); - } while (EqualPt(curr, oldcurr) && StillDown()); + temp = getlocalmouse(RSlocal[w].window); + curr = normalize(temp, w,TRUE); + if ( curr.h > -1 ) { + if (VSgetattr(w, curr.h - 1, curr.v, curr.h, curr.v, &attrib, sizeof(VSAttrib))) { + if (VSisansi2b(attrib)) { + ++curr.h; + } + } + } + } while (StillDown() && (EqualPt(curr, oldcurr) || EqualPt(pt, temp))); + + if ( !EqualPt(pt, temp) ) { + pt = temp; + + if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) { + newmode = 1; // up + } else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) { + newmode = 2; // down + } else + newmode = -1; // inside dbl-clicked word + + /* toggle highlight state of text between current and last mouse positions */ + if (mode == -1) { + if (newmode == 2) { + RSlocal[w].anchor = leftLoc; + RSinvText(w, curr, rightLoc, &noConst); + RSlocal[w].last = curr; + } + if (newmode == 1) { + RSlocal[w].anchor = rightLoc; + RSinvText(w, curr, leftLoc, &noConst); + RSlocal[w].last = curr; + } + } - - if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) { - newmode = 1; // up - } - else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) { - newmode = 2; // down - } - else - newmode = -1; // inside dbl-clicked word - - /* toggle highlight state of text between current and last mouse positions */ - if (mode == -1) { - if (newmode == 2) { - RSlocal[w].anchor = leftLoc; - RSinvText(w, curr, rightLoc, &noConst); - RSlocal[w].last = curr; + if (mode == 1) { + if (newmode == 2) { + RSlocal[w].anchor = leftLoc; + RSinvText(w, oldcurr, leftLoc, &noConst); + RSinvText(w, rightLoc, curr, &noConst); + RSlocal[w].last = curr; } - if (newmode == 1) { - RSlocal[w].anchor = rightLoc; - RSinvText(w, curr, leftLoc, &noConst); - RSlocal[w].last = curr; + if (newmode == -1) { + RSlocal[w].anchor = leftLoc; + RSinvText(w, oldcurr, leftLoc, &noConst); + RSlocal[w].last = rightLoc; } - } - - if (mode == 1) { - if (newmode == 2) { - RSlocal[w].anchor = leftLoc; - RSinvText(w, oldcurr, leftLoc, &noConst); - RSinvText(w, rightLoc, curr, &noConst); - RSlocal[w].last = curr; - } - if (newmode == -1) { - RSlocal[w].anchor = leftLoc; - RSinvText(w, oldcurr, leftLoc, &noConst); - RSlocal[w].last = rightLoc; - } - if (newmode == mode) { - RSinvText(w, oldcurr, curr, &noConst); - RSlocal[w].last = curr; - } - } - - if (mode == 2) { - if (newmode == 1) { - RSlocal[w].anchor = rightLoc; - RSinvText(w, oldcurr, rightLoc, &noConst); - RSinvText(w, leftLoc, curr, &noConst); - RSlocal[w].last = curr; - } - if (newmode == -1) { - RSlocal[w].anchor = leftLoc; - RSinvText(w, oldcurr, rightLoc, &noConst); - RSlocal[w].last = rightLoc; - } - if (newmode == mode) { - RSinvText(w, oldcurr, curr, &noConst); - RSlocal[w].last = curr; + if (newmode == mode) { + RSinvText(w, oldcurr, curr, &noConst); + RSlocal[w].last = curr; } } - mode = newmode; - } /* while */ + if (mode == 2) { + if (newmode == 1) { + RSlocal[w].anchor = rightLoc; + RSinvText(w, oldcurr, rightLoc, &noConst); + RSinvText(w, leftLoc, curr, &noConst); + RSlocal[w].last = curr; + } + if (newmode == -1) { + RSlocal[w].anchor = leftLoc; + RSinvText(w, oldcurr, rightLoc, &noConst); + RSlocal[w].last = rightLoc; + } + if (newmode == mode) { + RSinvText(w, oldcurr, curr, &noConst); + RSlocal[w].last = curr; + } + } + + mode = newmode; + } } - } + } + } } Point getlocalmouse(GrafPtr wind) @@ -1856,14 +1935,14 @@ void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, s void RSUpdatePalette(void) //called when ANSI colors have changed, and we need to update each { //windows palette GrafPtr oldPort; - int screenIndex; + int sn; WindRec *w; GetPort(&oldPort); - for (screenIndex = 0; screenIndex < TelInfo->numwindows; screenIndex++) + for (sn = 0; sn < TelInfo->numwindows; sn++) { - w = &screens[screenIndex]; + w = &screens[sn]; if ((w->active == CNXN_ACTIVE)|| (w->active == CNXN_OPENING)) { diff --git a/macssh/source/Screens/rsinterf.proto.h b/macssh/source/Screens/rsinterf.proto.h index b64b930..7f03899 100755 --- a/macssh/source/Screens/rsinterf.proto.h +++ b/macssh/source/Screens/rsinterf.proto.h @@ -1,6 +1,24 @@ /* rsinterf.proto.h */ -void RSunload(void); + +/* RSnewwindow Flags */ +enum { + RSWwrapon = 0x00000001, + RSWshowit = 0x00000002, + RSWgoaway = 0x00000004, + RSWforcesave = 0x00000008, + RSWallowBold = 0x00000010, + RSWcolorBold = 0x00000020, + RSWignoreBeeps = 0x00000040, + RSWrealbold = 0x00000080, + RSWsavelines = 0x00000100, + RSWjumpscroll = 0x00000200, + RSWrealBlink = 0x00000400 +}; + + + +void RSunload(void); void RSselect(short w, Point pt, EventRecord theEvent); void RSzoom(GrafPtr window, short code, short shifted); void RSdrawlocker(short w, RgnHandle visRgn); @@ -10,11 +28,12 @@ short RSTextSelected(short w); void RSskip(short w, Boolean on); short RSsize(GrafPtr window, long *where, long modifiers); void RSshow(short w); +void RSresetcolors(short w); Boolean RSsetcolors(short w, short n, RGBColor *color); void RSsendstring(short w, char *ptr, short len); -short RSnewwindow(RectPtr wDims,short scrollback, short width, short lines, StringPtr name, short wrapon, - short fnum, short fsiz, short showit, short goaway, short forcesave, short screenNumber, short allowBold, - short colorBold, short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, short realbold, short oldScrollback, short jump, short); +short RSnewwindow(RectPtr wDims, short scrollback, short width, short lines, StringPtr name, + short fnum, short fsiz, short screenNumber, short bfnum, short bfsiz, short bfstyle, + short vtemulation, unsigned long flags); short RSmouseintext(short w, Point myPoint); void RSkillwindow(short w); void RSgetcolors(short w, short n, RGBColor *color); diff --git a/macssh/source/Screens/rsmac.c b/macssh/source/Screens/rsmac.c index e8ed920..266c7fe 100755 --- a/macssh/source/Screens/rsmac.c +++ b/macssh/source/Screens/rsmac.c @@ -213,12 +213,14 @@ short RSsetwind return(0); } /* RSsetwind */ -void RSbell - ( - short w - ) - /* gives an audible signal associated with the specified window. */ - { +/* + * RScursoff + * + * gives an audible signal associated with the specified window. + */ + +void RSbell( short w ) +{ /* NONO : #@%! bell ! I'm not deaf, It's my autokey buffer... */ static unsigned long sLastBellTicks = 0; @@ -247,34 +249,51 @@ void RSbell SysBeep(8); NotifyUser(); - } /* RSbell */ +} /* RSbell */ -void RScursoff - ( - short w - ) - /* hides the text cursor for the specified window. Assumes it - is currently being shown. */ - { +/* + * RScursison + * + */ + +Boolean RScursison( short w ) +{ + return RSlocal[w].cursorstate; +} /* RScursison */ + + +/* + * RScursoff + * + * hides the text cursor for the specified window. Assumes it + * is currently being shown. + */ + +void RScursoff( short w ) +{ if (RSlocal[w].skip || !RSlocal[w].cursorstate) /* BYU 2.4.11 */ return; - RSsetwind(w); - RScurrent->cursorstate = 0; /* BYU 2.4.11 */ - InvertRect(&RScurrent->cursor); - } /* RScursoff */ -void RScurson - ( - short w, - short la, - short x, - short y - ) - /* displays the text cursor for the specified window, at the - specified position. Assumes it isn't currently being shown. */ - { - short xw; + RSsetwind(w); + + RScurrent->cursorstate = 0; /* BYU 2.4.11 */ + + InvertRect(&RScurrent->cursor); + +} /* RScursoff */ + +/* + * RScurson + * + * displays the text cursor for the specified window, at the + * specifified position. Assumes it isn't currently being off. + */ + +void RScurson( short w, short la, short x, short y ) +{ + short xw; + VSAttrib attrib; if ( RSlocal[w].skip || RSlocal[w].cursorstate ) return; @@ -282,23 +301,26 @@ void RScurson RSsetwind(w); xw = RScurrent->fwidth; - if ((la & 3)) { + if (VSisdecdwh(la)) { // double width xw <<= 1; - - - if (x > ((VSIw->maxwidth + 1) >> 1) - 1) { - x = ((VSIw->maxwidth + 1) >> 1) - 1; } - - - } - - RScurrent->cursor.left = x * xw; RScurrent->cursor.top = y * RScurrent->fheight; + if ( y <= VSIw->lines ) { + if (VSIw->oldScrollback) { + attrib = VSIw->attrst[y]->text[x]; + } else { + attrib = VSIw->linest[y]->attr[x]; + } + if ((attrib & kVSansi2b)) { + // double width + xw <<= 1; + } + } + switch (RScurrent->cursType) { case UNDERSCORECURSOR: RScurrent->cursor.top += RScurrent->fheight; @@ -337,18 +359,12 @@ void RScurson } if ( VSIcursorvisible() ) { if ( !gApplicationPrefs->BlinkCursor ) { - RScurrent->cursorstate = 1; InvertRect(&RScurrent->cursor); - } else { - if ( RScurrent->cursorstate ) { - // refresh right now - RScurrent->cursorstate = 1; - InvertRect(&RScurrent->cursor); - TelInfo->blinktime = LMGetTicks(); - } else { - // refresh as soon as possible - TelInfo->blinktime = LMGetTicks() - CURS_BLINK_PERIOD; - } + RScurrent->cursorstate = 1; + } else if ( w == screens[scrn].vs && RScurrent->active ) { + InvertRect(&RScurrent->cursor); + TelInfo->blinktime = LMGetTicks(); + RScurrent->cursorstate = 1; } } } /* RScurson */ @@ -369,21 +385,11 @@ void RSsetattr(short la, VSAttrib a) RSla = la; RSa = a; - size = ((la & 3)) ? RScurrent->fsiz * 2 : RScurrent->fsiz; + size = (VSisdecdwh(la)) ? RScurrent->fsiz * 2 : RScurrent->fsiz; if ( VSisgrph(a) ) { - //GetFNum("\p%NCSA VT", &tempFontID); // RAB BetterTelnet 1.0fc4 - //TextFont(tempFontID); /* use "NCSA VT" (74) font for special graphics */ TextFont( gNCSAFontID ); } else { RSTextFont( RScurrent->fnum, size, VSisbold(a) && RScurrent->allowBold ); -/* - if ((la & 3)) { - GetFNum( (la & 2) ? "\pANSI/PC Bottom" : "\pANSI/PC Top", &tempFontID); - RSTextFont(tempFontID,RScurrent->fsiz,VSisbold(a) && RScurrent->allowBold); - } else { - RSTextFont(RScurrent->fnum,RScurrent->fsiz,VSisbold(a) && RScurrent->allowBold); - } -*/ } TextSize(size); @@ -584,7 +590,7 @@ void RSinvText if (lb.v - ub.v > 1) { /* highlight extends across more than two lines */ - /* highlight complete in-between lines */ + /* highlight complete in-between lines */ MYSETRECT ( temp, @@ -597,11 +603,8 @@ void RSinvText DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); - } /* if */ - } /* if */ - - RSsetattr(VSIw->lattrib, VSIw->attrib); - + } + } } /* RSinvText */ @@ -633,7 +636,7 @@ void RSdraw RSsetwind(w); xw = RScurrent->fwidth; - if ((la & 3)) { + if (VSisdecdwh(la)) { // double width xw <<= 1; } @@ -667,7 +670,7 @@ void RSdraw if (rect.bottom >= RScurrent->height) rect.bottom = RScurrent->height; - if ((la & 1)) { + if (VSisdecdhlt(la)) { // Upper part ys += RScurrent->fheight; } @@ -726,20 +729,6 @@ static void ScrollRectInRgn( WindowPtr window, Rect *inRect, short dh, short dv) } -/* - * RSdefaultattr() - */ - -void RSdefaultattr(short w) -{ - short screenIndex; - - if ( screens[findbyVS(w)].vtemulation < 2 ) - RSsetattr(VSIw->lattrib, 0); - else - RSsetattr(VSIw->lattrib, VSIw->attrib); -} - /* * RSdelcols() */ @@ -762,7 +751,7 @@ void RSdelcols xw = RScurrent->fwidth; /* - if ((la & 3)) { + if (VSisdecdwh(la)) { // double width xw <<= 1; } @@ -809,11 +798,12 @@ void RSdelchars if (RSlocal[w].skip) return; RSsetwind(w); -// RSsetattr(VSIw->lattrib, 0); /* avoid funny pen modes */ - RSdefaultattr(w); + +// RSsetattr(VSIw->lattrib, VSIw->attrib & ~kVSblnk); + RSsetattr(0, 0); xw = RScurrent->fwidth; - if ((la & 3)) { + if (VSisdecdwh(la)) { // double width xw <<= 1; } @@ -881,8 +871,9 @@ void RSdellines RSsetwind(w); RSsetConst(w); -// RSsetattr(VSIw->lattrib, 0); /* avoid funny pen modes */ - RSdefaultattr(w); + +// RSsetattr(VSIw->lattrib, VSIw->attrib & ~kVSblnk); + RSsetattr(0, 0); if (scrolled) { @@ -910,7 +901,7 @@ void RSdellines ScrollRectInRgn(RScurrent->window, &rect, 0, -RScurrent->fheight * n); RSsetattr(VSIw->lattrib, VSIw->attrib); /* restore mode for text drawing */ - } /* RSdellines */ +} /* RSdellines */ void RSerase ( @@ -929,8 +920,8 @@ void RSerase return; RSsetwind(w); -// RSsetattr(VSIw->lattrib, 0); /* avoid funny pen modes */ - RSdefaultattr(w); + RSsetattr(VSIw->lattrib, VSIw->attrib & ~kVSblnk); +// RSsetattr(0, 0); MYSETRECT ( @@ -952,9 +943,9 @@ void RSerase /* highlight any part of the selection within the cleared area */ RSinvText(w, RScurrent->anchor, RScurrent->last, &rect); - RSsetattr(VSIw->lattrib, VSIw->attrib); /* restore mode for text drawing */ +// RSsetattr(VSIw->lattrib, VSIw->attrib); /* restore mode for text drawing */ - } /* RSerase */ +} /* RSerase */ void RSinslines ( @@ -973,8 +964,9 @@ void RSinslines return; RSsetwind(w); RSsetConst(w); -// RSsetattr(VSIw->lattrib, 0); /* avoid funny pen modes */ - RSdefaultattr(w); + +// RSsetattr(VSIw->lattrib, VSIw->attrib & ~kVSblnk); + RSsetattr(0, 0); if (RScurrent->selected && (scrolled < 0)) { @@ -994,7 +986,7 @@ void RSinslines ScrollRectInRgn(RScurrent->window, &rect, 0, RScurrent->fheight * n); RSsetattr(VSIw->lattrib, VSIw->attrib); /* restore mode for text drawing */ - } /* RSinslines */ +} /* RSinslines */ void RSinscols ( @@ -1012,13 +1004,6 @@ void RSinscols return; RSsetwind(w); -/* - if ((VSIw->lattrib & 3)) { - // double width - xw <<= 1; - } -*/ - MYSETRECT /* bounds of entire text area */ ( rect, @@ -1061,7 +1046,7 @@ void RSinsstring RSsetwind(w); xw = RScurrent->fwidth; - if ((la & 3)) { + if (VSisdecdwh(la)) { // double width xw <<= 1; } @@ -1093,7 +1078,7 @@ void RSinsstring if (rect.left <= 0) rect.left = 0; - if ((la & 1)) { + if (VSisdecdhlt(la)) { // Upper part ys += RScurrent->fheight; } @@ -1240,45 +1225,35 @@ Point normalize(Point in, short w, Boolean autoScroll) to the specified window. Constrains the position to lie within the currently-visible region of the screen, autoscrolling the screen if necessary (and if autoScroll = TRUE). */ - { - - if (in.v <0) - { +{ + if (in.v < 0) { in.v = 0; if (autoScroll) VSscrolback(w, 1); - } /* if */ - if (in.v > RSlocal[w].height) - { + } + if (in.v > RSlocal[w].height) { in.v = RSlocal[w].height; if (autoScroll) VSscrolforward(w, 1); - } /* if */ + } in.v = in.v / FHeight; - if (in.h < 0) - { - in.h = -1; + if (in.h < 0) { + in.h = 0; if (autoScroll) VSscrolleft(w, 1); - } /* if */ - if (in.h > RSlocal[w].width) - { + } else if (in.h > RSlocal[w].width) { in.h = RSlocal[w].width; if (autoScroll) VSscrolright(w, 1); - } /* if */ - /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */ - /* the MPW C 3.0 compiler has a bug in its register allocation */ - /* which keeps the above line from working. So, replace it with this: */ - in.h = in.h + Fwidthhalf; - in.h = in.h / FWidth - 1; - /* note the bug has been fixed in the 3.1 compiler. */ + } + in.h = ((in.h + Fwidthhalf) / FWidth) - 1; + /* convert to virtual screen coordinates */ in.v += RSlocal[w].topline; in.h += RSlocal[w].leftmarg; - return(in); - } /* normalize */ + return in; +} /* normalize */ @@ -1303,6 +1278,9 @@ void RSsetsize( short w, short v, short h, short screenIndex) /* saves the new size settings for a window, and repositions the scroll bars accordingly. */ { + if ( VSIcursorvisible() ) + RScursoff( w ); + RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight; RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth; RSlocal[w].rheight = v - 16; @@ -1328,7 +1306,7 @@ void RSsetsize( short w, short v, short h, short screenIndex) } if ( RSlocal[w].left != NULL ) { short i; - if (screenIndex == -1) + if (screenIndex < 0) screenIndex = findbyVS(w); if ( screenIndex >= 0 && screens[screenIndex].protocol == 4 ) { i = LOCKWIDTH + 1; diff --git a/macssh/source/Screens/rsmac.proto.h b/macssh/source/Screens/rsmac.proto.h index 701f3fe..f925b64 100755 --- a/macssh/source/Screens/rsmac.proto.h +++ b/macssh/source/Screens/rsmac.proto.h @@ -7,13 +7,13 @@ void RSinitall(short max); void RSsetConst(short w); short RSsetwind(short w); void RSbell(short w); +Boolean RScursison( short w ); void RScursoff(short w); void RScurson(short w, short la, short x, short y); void RSsetattr(short la, VSAttrib a); void DoHiliteMode(void); void RSinvText(short w, Point curr, Point last, RectPtr constrain); void RSdraw(short w, short x, short y, short la, VSAttrib a, short len, char *ptr); -void RSdefaultattr(short w); void RSdelcols(short w, short n); void RSdelchars(short w, short la, short x, short y, short n); void RSdellines(short w, short t, short b, short n, short scrolled); diff --git a/macssh/source/Screens/vsdata.h b/macssh/source/Screens/vsdata.h index 1ae65e9..064b60f 100755 --- a/macssh/source/Screens/vsdata.h +++ b/macssh/source/Screens/vsdata.h @@ -63,6 +63,10 @@ typedef struct VSattrline //CCP 2.7 ANSI needs shorts #define DEBUG_CAPTURE struct VSscrn { OSType id; // VSCR + short + vtemulation; /* 0:vt100, 1:vt220, 2:ansi, 3:linux */ + short + vteightbits; /* true if we accept vt200 8-bit codes */ VSlinePtr scrntop, /* topmost line of the current screen (= linest[0]) */ buftop, /* top (i e oldest line) of scrollback buffer */ @@ -117,7 +121,11 @@ struct VSscrn { char *tabs; /* pointer to array for tab settings */ /* contains 'x' at each tab position, blanks elsewhere */ unsigned long escflags; - }; + short trincount; /* number of chars pending in translation */ + short trinx; /* number of characters to draw at left of cursor */ + short trintag; /* true if waiting for a second multi-byte character */ + unsigned char trinbuf[4]; +}; typedef struct VSscrn VSscrn; @@ -129,7 +137,7 @@ struct VSscrndata { stat; /* status of this screen (0=Uninitialized, */ /* BYU 2.4.18 */ /* 1=In Use */ /* BYU 2.4.18 */ /* 2=Initialized, but not IU */ /* BYU 2.4.18 */ - }; +}; typedef struct VSscrndata VSscrndata; diff --git a/macssh/source/Screens/vsinterf.c b/macssh/source/Screens/vsinterf.c index 0e5077b..5da12bf 100755 --- a/macssh/source/Screens/vsinterf.c +++ b/macssh/source/Screens/vsinterf.c @@ -275,11 +275,10 @@ void VSIclrbuf register VSAttrib *ta; for (i = 0; i <= VSIw->lines; i++) { + VSIw->linest[i]->lattr = 0; if (VSIw->oldScrollback) { - VSIw->attrst[i]->lattr = 0; ta = &VSIw->attrst[i]->text[0]; } else { - VSIw->linest[i]->lattr = 0; ta = &VSIw->linest[i]->attr[0]; } tx = &VSIw->linest[i]->text[0]; @@ -293,6 +292,7 @@ void VSIclrbuf short VSnewscreen ( + short vtemulation, short maxlines, /* max lines to save in scrollback buffer */ short screensave, /* whether to have a scrollback buffer */ short numLines, //numLines initially on screen (CCP 2.7) @@ -305,7 +305,6 @@ short VSnewscreen ) /* creates a new virtual screen, and returns its number. */ { - if (maxlines < VSDEFLINES) maxlines = VSDEFLINES; @@ -348,10 +347,13 @@ short VSnewscreen if ((VSscreens[VSIwn].loc = VSIw = (VSscrn *) myNewPtr(sizeof(VSscrn))) == 0L) return(-2); + VSIw->vtemulation = vtemulation; + VSIw->oldScrollback = oldScrollback; VSIw->lines = numLines; //VSIw->lines = 23; CCP 2.7 set this from the start + VSIw->linest = VSInewlinearray(VSIw->lines + 1); if (VSIw->linest == NULL) { @@ -454,10 +456,13 @@ short VSnewscreen VSIw->savelines = screensave; VSIw->forcesave = forcesave; /* NCSA 2.5 */ VSIw->attrib = 0; - VSIw->Pattrib = -1; /* initially no saved attribute */ + VSIw->Pattrib = 0xffffffff; /* initially no saved attribute */ VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; + VSIw->trincount = 0; + VSIw->trinx = 0; + VSIw->trintag = 0; VSIw->G0 = 0; VSIw->G1 = 1; VSIw->DECAWM = 0; @@ -532,11 +537,10 @@ void VSrealloc(short w) } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { + savedTextPtr->lattr = VSIw->linest[i]->lattr; if (VSIw->oldScrollback) { - savedTextPtr->lattr = VSIw->attrst[i]->lattr; BlockMoveData(VSIw->attrst[i]->text, savedTextPtr->attr, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } else { - savedTextPtr->lattr = VSIw->linest[i]->lattr; BlockMoveData(VSIw->linest[i]->attr, savedTextPtr->attr, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; @@ -591,7 +595,6 @@ void VSredrawLine(short w) //redraws current line VSIcuroff(w); } - short VSredraw ( short w, // window to redraw */ @@ -605,6 +608,10 @@ short VSredraw VSlinePtr ypt; short y; short tx1, tx2, ty1, ty2, tn, offset; + short sx1; + short sx2; + Boolean cursOff; + if (VSvalids(w) != 0) return(-3); @@ -633,9 +640,12 @@ short VSredraw tn = -1; // so we include more than 1 line // if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region - - if (VSIcursorenabled()) + + cursOff = 0; + if ( VSIcursorenabled() && RScursison(w) ) { + cursOff = 1; VSIcuroff(w); // temporarily hide cursor + } // draw visible part of scrollback buffer if (y1 < 0) { @@ -648,6 +658,9 @@ short VSredraw if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need @@ -657,34 +670,39 @@ short VSredraw VSAttrib *pa; VSAttrib lasta; short x, lastx; + short chw; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; - + // if double size, we must shift width - if (ypt->lattr & 3) { + if (VSisdecdwh(ypt->lattr)) { tx1 >>= 1; tx2 >>= 1; - } + chw = 2; + } else + chw = 1; + + // multi-byte + if ( tx1 > 0 && (pa[tx1-1] & kVSansi2b) ) + --tx1; + if ( tx2 < VSIw->maxwidth && (pa[tx2] & kVSansi2b) ) + ++tx2; lastx = tx1; - lasta = pa[tx1]; - for(x=tx1+1; x<=tx2; x++) { - if (pa[x]!=lasta) { + lasta = pa[tx1] & ~kVSansi2b; + for(x = tx1+1; x <= tx2; x++) { + if ( (pa[x] & ~kVSansi2b) != lasta ) { RSdraw(w, lastx, y, ypt->lattr, lasta, x-lastx, pt + lastx); lastx = x; - lasta = pa[x]; + lasta = pa[x] & ~kVSansi2b; } } if (lastx<=tx2) RSdraw(w, lastx, y, ypt->lattr, lasta, tx2-lastx+1, pt + lastx); - - // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; - } + tx1 = sx1; + tx2 = sx2; ypt = ypt->next; } } @@ -702,6 +720,9 @@ short VSredraw if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->linest[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { @@ -709,43 +730,49 @@ short VSredraw VSAttrib *pa; VSAttrib lasta; short x, lastx; + short chw; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; // if double size, we must shift width - if (ypt->lattr & 3) { + if (VSisdecdwh(ypt->lattr)) { tx1 >>= 1; tx2 >>= 1; - } + chw = 2; + } else + chw = 1; + + // multi-byte + if ( tx1 > 0 && (pa[tx1-1] & kVSansi2b) ) + --tx1; + if ( tx2 < VSIw->maxwidth && (pa[tx2] & kVSansi2b) ) + ++tx2; lastx = tx1; - lasta = pa[tx1]; - for(x=tx1+1; x<=tx2; x++) { - if (pa[x]!=lasta) { + lasta = pa[tx1] & ~kVSansi2b; + for(x = tx1+1; x <= tx2; x++) { + if ( (pa[x] & ~kVSansi2b) != lasta ) { RSdraw(w, lastx, y, ypt->lattr, lasta, x-lastx, pt + lastx); lastx = x; - lasta = pa[x]; + lasta = pa[x] & ~kVSansi2b; } } if (lastx<=tx2) RSdraw(w, lastx, y, ypt->lattr, lasta, tx2-lastx+1, pt + lastx); - - // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; - } + tx1 = sx1; + tx2 = sx2; ypt = ypt->next; } } } - if (VSIcursorenabled()) + if (VSIcursorenabled() && cursOff) VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ return(0); - } /* VSredraw */ +} /* VSredraw */ + short VSOredraw ( @@ -761,6 +788,11 @@ short VSOredraw VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; + short sx1; + short sx2; + Boolean cursOff; + + // this fails for multi-bytes character set... if (VSvalids(w) != 0) return(-3); @@ -786,11 +818,14 @@ short VSOredraw tn = -1; // so we include more than 1 line // if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region - - if (VSIcursorenabled()) - VSIcuroff(w); // temporarily hide cursor - RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area + cursOff = 0; + if ( VSIcursorenabled() && RScursison(w) ) { + cursOff = 1; + VSIcuroff(w); // temporarily hide cursor + } + +// RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // draw visible part of scrollback buffer if (y1 < 0) { @@ -802,6 +837,9 @@ short VSOredraw tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need @@ -809,17 +847,18 @@ short VSOredraw for (y=ty1; y<=ty2; y++) { // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 >>= 1; - tx2 >>= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = (tx1 & 1) ? (tx1 >> 1) - 1 : (tx1 >> 1); + tx2 = (tx2 & 1) ? (tx2 >> 1) + 1 : (tx2 >> 1); } + /* no attributes... */ RSdraw(w, tx1, y, ypt->lattr, 0, tn, ypt->text + VSIw->Rleft +tx1); // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = sx1; + tx2 = sx2; } ypt = ypt->next; @@ -839,6 +878,9 @@ short VSOredraw if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->linest[VSIw->Rtop+ty1]; ypa = VSIw->attrst[VSIw->Rtop+ty1]; @@ -852,28 +894,34 @@ short VSOredraw pa = ypa->text + VSIw->Rleft; // if double size, we must shift width - if (ypa->lattr & 3) { - tx1 >>= 1; - tx2 >>= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = (tx1 & 1) ? (tx1 >> 1) - 1 : (tx1 >> 1); + tx2 = (tx2 & 1) ? (tx2 >> 1) + 1 : (tx2 >> 1); } lastx = tx1; - lasta = pa[tx1]; - + lasta = pa[tx1] & ~kVSansi2b; for(x=tx1+1; x<=tx2; x++) { - if (pa[x]!=lasta) { - RSdraw(w, lastx, y, ypa->lattr, lasta, x-lastx, pt + lastx); + if ( (pa[x] & ~kVSansi2b) != lasta ) { + if (lastx == tx1 && tx1 > 0 && (pa[tx1-1] & kVSansi2b)) + RSdraw(w, lastx-1, y, ypt->lattr, lasta, x-lastx+1, pt + lastx-1); + else + RSdraw(w, lastx, y, ypt->lattr, lasta, x-lastx, pt + lastx); lastx = x; - lasta = pa[x]; + lasta = pa[x] & ~kVSansi2b; } } - if (lastx<=tx2) - RSdraw(w, lastx, y, ypa->lattr, lasta, tx2-lastx+1, pt + lastx); + if (lastx<=tx2) { + if (lastx == tx1 && tx1 > 0 && (pa[tx1-1] & kVSansi2b)) + RSdraw(w, lastx-1, y, ypt->lattr, lasta, tx2-lastx+2, pt + lastx-1); + else + RSdraw(w, lastx, y, ypt->lattr, lasta, tx2-lastx+1, pt + lastx); + } // if double size, we must shift width - if (ypa->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = sx1; + tx2 = sx2; } ypt = ypt->next; @@ -882,7 +930,7 @@ short VSOredraw } } - if (VSIcursorenabled()) + if (VSIcursorenabled() && cursOff) VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ return(0); @@ -896,27 +944,34 @@ short VSwrite short len /* length of text string */ ) /* sends a stream of characters to the specified window. */ - { +{ + int cursOff; + // _profile = 1; if (len == 0) return 0; if (VSvalids(w) != 0) return(-3); - if (VSIcursorenabled()) - VSIcuroff(w); /* hide cursor momentarily */ + cursOff = 0; + if ( VSIcursorenabled() ) { + cursOff = 1; + VSIcuroff(w); // hide cursor momentarily + } VSIcursdisable(); // RAB BetterTelnet 2.0b4 VSem((unsigned char *) ptr, len); /* BYU LSC - interpret the character stream */ VSIflush(); // RAB BetterTelnet 2.0b3 VSIcursenable(); - if (VSIcursorenabled()) + if ( VSIcursorenabled() && cursOff ) VSIcurson(w, VSIw->x, VSIw->y, 1); /* restore cursor, force it to be visible. */ // _profile = 0; return(0); - } /* VSwrite */ +} /* VSwrite */ + // RAB BetterTelnet 2.0b3 // The same VSwrite you know and love, except it doesn't flush. // This is for parse() to use so it doesn't flush every time it hits an escape. + short VSwritefast ( short w, /* screen to draw into */ @@ -926,12 +981,13 @@ short VSwritefast /* sends a stream of characters to the specified window. */ { // _profile = 1; - if (len == 0) + if ( len == 0 ) return 0; - if (VSvalids(w) != 0) + if ( VSvalids(w) != 0 ) return(-3); - if (VSIcursorenabled()) + if ( VSIcursorenabled() ) { VSIcuroff(w); /* hide cursor momentarily */ + } VSIcursdisable(); VSem((unsigned char *) ptr, len); /* BYU LSC - interpret the character stream */ @@ -951,10 +1007,11 @@ void VSflushwrite(short w) { VSIflush(); VSIcursenable(); - if (VSIcursorenabled()) + if ( VSIcursorenabled() ) { VSIcurson(w, VSIw->x, VSIw->y, 1); - + } } + // Utility routine: BetterTelnet 1.0fc3 (RAB) void VSsetprintmode(short w, short printMode) { @@ -1066,6 +1123,7 @@ void VSpossend /* sends a stream of VT100 cursor-movement sequences to move the cursor on the specified screen to the specified position. */ { + short sn; static char VSkbax[] = "\033O ", /* prefix for auxiliary code */ VSkban[] = "\033[ "; /* prefix for arrows normal */ @@ -1076,8 +1134,9 @@ void VSpossend /* NCSA: SB - This would bomb before. You need to get the screens # from the - translation routine before you access the record! */ - if (screens[findbyVS(w)].arrowmap) { /* NCSA: SB - get the CORRECT screens # */ + translation routine before you access the record! */ + sn = findbyVS(w); + if (sn >= 0 && screens[sn].arrowmap) { /* NCSA: SB - get the CORRECT screens # */ VSpossendEM(w,x,y,echo); // MAT-- call our cursor movement routine return; // MAT-- then exit } @@ -1147,6 +1206,7 @@ char VSkbsend // VSkban[] = "\033[ ", /* prefix for arrows normal */ // VSkbfn[] = "\033O ", /* prefix for function keys */ /* BYU 2.4.12 */ // VSk220[] = "\033[ ~"; /* prefix for vt220 keys */ /* BYU 2.4.12 */ + short sn; char *vskptr; short vskplen; short macronum; @@ -1154,7 +1214,10 @@ char VSkbsend if (VSvalids(w) != 0) return(-3); - if ( screens[findbyVS(w)].arrowmap && (k <= VSLT) && (k >= VSUP) ) // MAT-- + sn = findbyVS(w); + if (sn < 0) + return; + if ( screens[sn].arrowmap && (k <= VSLT) && (k >= VSUP) ) // MAT-- // MAT-- important...we need to check this first before { // MAT-- the next if(É) statement gets its hands on the string. switch (k) { // MAT-- do the mapping from arrowkeys -> EMACS ctrl keys. @@ -1239,7 +1302,7 @@ char VSkbsend else if ((k == VSKE) && !VSIw->DECPAM) // Enter (!AM) macronum++; - sendmacro(&screens[findbyVS(VSIwn)], macronum); // and actually send it, the NEW way! + sendmacro(&screens[sn], macronum); // and actually send it, the NEW way! return 0; } /* VSkbsend */ @@ -1636,7 +1699,7 @@ char *VSIstrcopy(char *src, short len, char *dest, short table, short noClip) p = src + len - 1; /* skip trailing blanks, but only if !noClip */ - if ((!noClip) || table || gApplicationPrefs->clipTrailingSpaces) + if (!noClip && (table || gApplicationPrefs->clipTrailingSpaces)) // RAB BetterTelnet 1.0fc7, 1.1 while ((*p == ' ') && (p >= src)) p--; @@ -1671,7 +1734,8 @@ char *VSIstrcopy(char *src, short len, char *dest, short table, short noClip) return(dest); } /* VSIstrcopy */ -long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table) + +long VSOgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table) /* copies a portion of text from the specified virtual screen into the *charp buffer. table, if nonzero, is the minimum length of runs of spaces to be replaced with single tabs. Returns the @@ -1679,11 +1743,11 @@ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, lon length to copy, but this is currently ignored! EOLS is the end-of-line sequence to insert at line boundaries. This is currently assumed to be exactly one character long. */ - { +{ UNUSED_ARG(max) /* !! */ short EOLlen; short lx,ly, /* Upper bounds of selection */ - ux,uy; /* Lower bounds of selection */ + ux,uy; /* Lower bounds of selection */ short maxwid; char *origcp; VSlinePtr t; @@ -1694,29 +1758,37 @@ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, lon maxwid = VSIw->maxwidth; origcp = charp; - if (y1 < -VSIw->numlines) - { - y1 = -VSIw->numlines; - x1 = -1; - } /* if */ - if (y1 == y2) + // this fails for multi-bytes character set... + + /* Order the lower and upper bounds */ + if (x1 < x2) { + ux = x1; + lx = x2; + } else { + ux = x2; + lx = x1; + } + + if (y1 < y2) { + uy = y1; + ly = y2; + } else { + uy = y2; + ly = y1; + } + + if (uy < -VSIw->numlines) { + uy = -VSIw->numlines; + ux = -1; + } + if (ly < -VSIw->numlines) { + ly = -VSIw->numlines; + } + + if (uy == ly) { /* copying no more than a single line */ - t = VSIGetLineStart(w, y1); - if (x1 < x2) /* Order the lower and upper bounds */ - { - ux = x1; - uy = y1; - lx = x2; - ly = y2; - } - else - { - ux = x2; - uy = y2; - lx = x1; - ly = y1; - } /* if */ + t = VSIGetLineStart(w, uy); if ((long)(lx-ux) < max) charp=VSIstrcopy(&t->text[ux+1], lx-ux, charp, table, 1); @@ -1728,20 +1800,6 @@ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, lon else { /* copying more than one line */ - if (y1 < y2) /* Order the lower and upper bounds */ - { - ux = x1; - uy = y1; - lx = x2; - ly = y2; - } - else - { - ux = x2; - uy = y2; - lx = x1; - ly = y1; - } /* if */ t = VSIGetLineStart(w, uy); if (((long) (maxwid-ux) < max)) charp=VSIstrcopy(&t->text[ux+1],maxwid-ux,charp,table, 0); @@ -1772,7 +1830,243 @@ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, lon *charp++ = *EOLS; /* assumes it's only one character! */ } /* if */ return(charp - origcp); - } /* VSgettext */ +} /* VSgettext */ + + +long VSgettext(short w, short x1, short y1, short x2, short y2, + char *charp, long max, char *EOLS, short table, short clipspaces) + /* copies a portion of text from the specified virtual screen into + the *charp buffer. table, if nonzero, is the minimum length of + runs of spaces to be replaced with single tabs. Returns the + length of the copied text. max is supposed to be the maximum + length to copy, but this is currently ignored! + EOLS is the end-of-line sequence to insert at line boundaries. + This is currently assumed to be exactly one character long. */ +{ + short mw; + short lx,ly, /* Upper bounds of selection */ + ux,uy; /* Lower bounds of selection */ + char *origcp; + short elen; + short outlen; + short i; + VSlinePtr ypt; + VSattrlinePtr ypa; + char *pt; + VSAttrib *pa; + + if (VSvalids(w) != 0) + return(-3); + + if (VSIw->oldScrollback) + return VSOgettext(w, x1, y1, x2, y2, charp, max, EOLS, table); + + mw = VSIw->maxwidth; + + /* limit the lower and upper bounds */ + if (x1 < -1) + x1 = -1; + else if (x1 > mw) + x1 = mw; + if (x2 < -1) + x2 = -1; + else if (x2 > mw) + x2 = mw; + if (y1 < -VSIw->numlines) { + y1 = -VSIw->numlines; + x1 = -1; + } else if (y1 > VSIw->lines) { + y1 = VSIw->lines; + x1 = mw; + } + if (y2 < -VSIw->numlines) { + y2 = -VSIw->numlines; + x2 = -1; + } else if (y2 > VSIw->lines) { + y2 = VSIw->lines; + x2 = mw; + } + + origcp = charp; + elen = strlen(EOLS); + + /* Order the lower and upper bounds */ + ux = x1; + lx = x2; + uy = y1; + ly = y2; + if ( y1 == y2 ) { + if ( x1 > x2 ) { + ux = x2; + lx = x1; + } + } else if (y1 > y2) { + uy = y2; + ly = y1; + ux = x2; + lx = x1; + } + + x1 = ux + 1; + + // get text from scrollback buffer + if (uy < 0) { + x2 = mw; + y2 = (ly >= 0) ? -1 : ly; + ypt = VSIGetLineStart(w, uy); + for ( y1 = uy; y1 <= y2 && max >= elen; y1++, x1 = 0, x2 = mw, ypt = ypt->next ) { + pt = ypt->text; +// pa = ypt->attr; + if (y1 == ly) + x2 = lx; // end last line + outlen = x2 - x1 + 1; + if (outlen > max) { + outlen = max; + } + charp = VSIstrcopy(pt + x1, outlen, pt = charp, table, !clipspaces); + max -= charp - pt; + if (max >= elen && !VSiswrap(ypt->lattr) && y1 != ly) { + strcpy(charp, EOLS); + charp += elen; + max -= elen; + } + } + uy = 0; // continue with on-screen buffer, if any + } + + // get text from on-screen buffer + if (ly >= 0) { + x2 = mw; + ypt = VSIw->linest[uy]; + for ( y1 = uy; y1 <= ly && max >= elen; y1++, x1 = 0, x2 = mw, ypt = ypt->next ) { + pt = ypt->text; +// pa = ypt->attr; + if (y1 == ly) + x2 = lx; + outlen = x2 - x1 + 1; + if (outlen > max) { + outlen = max; + } + charp = VSIstrcopy(pt + x1, outlen, pt = charp, table, !clipspaces); + max -= charp - pt; + if (max >= elen && !VSiswrap(ypt->lattr) && y1 != ly) { + strcpy(charp, EOLS); + charp += elen; + max -= elen; + } + } + } + + return charp - origcp; +} + + +long VSgetattr(short w, short x1, short y1, short x2, short y2, + VSAttrib *attrp, long max) +{ + short mw; + short lx,ly; // Lower bounds of selection + short ux,uy; // Upper bounds of selection + VSAttrib *origap; + short outlen; + short i; + VSlinePtr ypt; + VSAttrib *pa; + + if (VSvalids(w) != 0) + return(-3); + + if (VSIw->oldScrollback) + return 0; // not coded... + + mw = VSIw->maxwidth; + + /* limit the lower and upper bounds */ + if (x1 < -1) + x1 = -1; + else if (x1 > mw) + x1 = mw; + if (x2 < -1) + x2 = -1; + else if (x2 > mw) + x2 = mw; + if (y1 < -VSIw->numlines) { + y1 = -VSIw->numlines; + x1 = -1; + } else if (y1 > VSIw->lines) { + y1 = VSIw->lines; + x1 = mw; + } + if (y2 < -VSIw->numlines) { + y2 = -VSIw->numlines; + x2 = -1; + } else if (y2 > VSIw->lines) { + y2 = VSIw->lines; + x2 = mw; + } + + origap = attrp; + + /* Order the lower and upper bounds */ + ux = x1; + lx = x2; + uy = y1; + ly = y2; + if ( y1 == y2 ) { + if ( x1 > x2 ) { + ux = x2; + lx = x1; + } + } else if (y1 > y2) { + uy = y2; + ly = y1; + ux = x2; + lx = x1; + } + + x1 = ux + 1; + + // get attributes from scrollback buffer + if (uy < 0) { + x2 = mw; + y2 = (ly >= 0) ? -1 : ly; + ypt = VSIGetLineStart(w, uy); + for ( y1 = uy; y1 <= y2 && max >= sizeof(VSAttrib); y1++, x1 = 0, x2 = mw, ypt = ypt->next ) { + pa = ypt->attr; + if (y1 == ly) + x2 = lx; // end last line + outlen = (x2 - x1 + 1) * sizeof(VSAttrib); + if (outlen > max / sizeof(VSAttrib)) { + outlen = max / sizeof(VSAttrib); + } + memcpy(attrp, pa + x1, outlen * sizeof(VSAttrib)); + attrp += outlen; + max -= outlen * sizeof(VSAttrib); + } + uy = 0; // continue with on-screen buffer, if any + } + + // get attributes from on-screen buffer + if (ly >= 0) { + x2 = mw; + ypt = VSIw->linest[uy]; + for ( y1 = uy; y1 <= ly && max >= sizeof(VSAttrib); y1++, x1 = 0, x2 = mw, ypt = ypt->next ) { + pa = ypt->attr; + if (y1 == ly) + x2 = lx; + outlen = (x2 - x1 + 1) * sizeof(VSAttrib); + if (outlen > max / sizeof(VSAttrib)) { + outlen = max / sizeof(VSAttrib); + } + memcpy(attrp, pa + x1, outlen * sizeof(VSAttrib)); + attrp += outlen; + max -= outlen * sizeof(VSAttrib); + } + } + + return attrp - origap; +} + short VSgetnumlines ( @@ -2073,7 +2367,6 @@ short VSOsetlines /* initialize the new screen lines to blank text and no attributes */ for (i = 0; i <= lines; i++) { - VSIw->attrst[i]->lattr = 0; VSIw->linest[i]->lattr = 0; tempa = VSIw->attrst[i]->text; temp = VSIw->linest[i]->text; @@ -2154,6 +2447,8 @@ short VSPulseOne VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; + short sx1; + short sx2; short cursOff; if (VSvalids(w) != 0) @@ -2188,8 +2483,11 @@ short VSPulseOne cursOff = 0; - // draw visible part of scrollback buffer + // we need to access only the visible part + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need @@ -2204,9 +2502,9 @@ short VSPulseOne pa = ypt->attr + VSIw->Rleft; // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 >>= 1; - tx2 >>= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = (tx1 & 1) ? (tx1 >> 1) - 1 : (tx1 >> 1); + tx2 = (tx2 & 1) ? (tx2 >> 1) + 1 : (tx2 >> 1); } lastx = tx1; @@ -2245,15 +2543,16 @@ short VSPulseOne } // if double size, we must shift width - if (ypt->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = sx1; + tx2 = sx2; } ypt = ypt->next; } /* back to default window colors */ + RSsetwind(w); RSsetattr( 0, 0 ); return 0; @@ -2274,6 +2573,8 @@ short VSOPulseOne short y; short tx1, tx2, ty1, ty2, tn, offset; short cursOff; + short sx1; + short sx2; if (VSvalids(w) != 0) return(-3); @@ -2304,7 +2605,9 @@ short VSOPulseOne cursOff = 0; - if(y1<0) y1=0; + if (y1 < 0) + y1 = 0; + // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { @@ -2316,6 +2619,9 @@ short VSOPulseOne if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { + sx1 = tx1; + sx2 = tx2; + ypt = VSIw->linest[VSIw->Rtop+ty1]; ypa = VSIw->attrst[VSIw->Rtop+ty1]; @@ -2329,9 +2635,9 @@ short VSOPulseOne pa = ypa->text + VSIw->Rleft; // if double size, we must shift width - if (ypa->lattr & 3) { - tx1 >>= 1; - tx2 >>= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = (tx1 & 1) ? (tx1 >> 1) - 1 : (tx1 >> 1); + tx2 = (tx2 & 1) ? (tx2 >> 1) + 1 : (tx2 >> 1); } lastx = tx1; @@ -2344,7 +2650,7 @@ short VSOPulseOne cursOff = 1; VSIcuroff(w); } - RSdraw(w, lastx, y, ypa->lattr, lasta, x-lastx, pt + lastx); + RSdraw(w, lastx, y, ypt->lattr, lasta, x-lastx, pt + lastx); if ( cursOff ) { // restore cursor at original position cursOff = 0; @@ -2361,7 +2667,7 @@ short VSOPulseOne cursOff = 1; VSIcuroff(w); } - RSdraw(w, lastx, y, ypa->lattr, lasta, tx2-lastx+1, pt + lastx); + RSdraw(w, lastx, y, ypt->lattr, lasta, tx2-lastx+1, pt + lastx); if ( cursOff ) { // restore cursor at original position cursOff = 0; @@ -2370,9 +2676,9 @@ short VSOPulseOne } // if double size, we must shift width - if (ypa->lattr & 3) { - tx1 <<= 1; - tx2 <<= 1; + if (VSisdecdwh(ypt->lattr)) { + tx1 = sx1; + tx2 = sx2; } ypt = ypt->next; @@ -2382,7 +2688,10 @@ short VSOPulseOne } /* back to default window colors */ + RSsetwind(w); RSsetattr( 0, 0 ); return 0; } + + diff --git a/macssh/source/Screens/vsinterf.proto.h b/macssh/source/Screens/vsinterf.proto.h index 9d06b33..5141b08 100755 --- a/macssh/source/Screens/vsinterf.proto.h +++ b/macssh/source/Screens/vsinterf.proto.h @@ -10,20 +10,21 @@ void VScapture(unsigned char *ptr, short len); short VSvalids(short w); VSscrn *VSwhereis(short i); void VSIclrbuf(void); -short VSnewscreen(short maxlines, short screensave, short numLines, short maxwid, short forcesave, short ignoreBeeps, short oldScrollback, short jump, short blink); +short VSnewscreen(short vtemulation, short maxlines, short screensave, short numLines, + short maxwid, short forcesave, short ignoreBeeps, short oldScrollback, short jump, short blink); short VSdestroy(short w); short VSredraw(short w, short x1, short y1, short x2, short y2); short VSOredraw(short, short, short, short, short); short VSwrite(short w, char *ptr, short len); short VSwritefast(short w, char *ptr, short len); void VSsetprintmode(short, short); -short VSclear(short w); +//short VSclear(short w); void VSpossendEM(short w, short x, short y, short echo); void VSpossend(short w, short x, short y, short echo); char VSkbsend(short w, unsigned char k, short echo, short blah); -short VSclearall(short w); +//short VSclearall(short w); short VSreset(short w); -char *VSgetline(short w, short y); +//char *VSgetline(short w, short y); void VSscrolright(short w, short n); void VSredrawLine(short w); void VSscrolleft(short w, short n); @@ -35,11 +36,14 @@ short VSscrolcontrol(short w, short scrolon, short offtop); void VSbeepcontrol(short, short); void VSenableblink(short w, Boolean enableBlink); short VSgetrgn(short w, short *x1, short *y1, short *x2, short *y2); -short VSsnapshot(short w); +//short VSsnapshot(short w); short VSmaxwidth(short w); VSlinePtr VSIGetLineStart(short w, short y1); char *VSIstrcopy(char*, short, char*, short, short); -long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table); +long VSgettext(short w, short x1, short y1, short x2, short y2, + char *charp, long max, char *EOLS, short table, short clipspaces); +long VSgetattr(short w, short x1, short y1, short x2, short y2, + VSAttrib *attrp, long max); short VSgetlines(short w); short VSgetnumlines(short w); short VSsetlines(short w, short lines); diff --git a/macssh/source/Screens/vsintern.c b/macssh/source/Screens/vsintern.c index 10cb2f9..04160ad 100755 --- a/macssh/source/Screens/vsintern.c +++ b/macssh/source/Screens/vsintern.c @@ -35,6 +35,7 @@ #include "rsmac.proto.h" #include "rsinterf.proto.h" #include "maclook.proto.h" +#include "translate.proto.h" #include "wind.h" #include "rsdefs.h" #include "Vers.h" @@ -42,7 +43,7 @@ #define ScrollbackQuantum 100 //#define VSIclrattrib 0 -#define VSIclrattrib VSIw->attrib +#define VSIclrattrib (VSIw->attrib & 0x0003ffff) #include "vsintern.proto.h" @@ -172,11 +173,7 @@ void VSIcurson if (!VSIw->DECCM) return; // Bri 970610 if (VSIw->disableCursor) return; // RAB BetterTelnet 2.0b4 - if (VSIw->oldScrollback) { - lattr = VSIw->attrst[y]->lattr; - } else { - lattr = VSIw->linest[y]->lattr; - } + lattr = VSIw->linest[y]->lattr; if (!VSIclip(&x, &y, &x2, &y2, &n, &offset)) { /* cursor already lies within visible region */ @@ -240,8 +237,6 @@ short VSIcursorenabled( void ) return 0; // Bri 970610 if (VSIw->disableCursor) return 0; // RAB BetterTelnet 2.0b4 - if (!RSisInFront(VSIwn)) - return 0; return 1; } @@ -262,6 +257,85 @@ short VSIcursorvisible( void ) return 1; } +/* + * VScursblink + */ + +void VScursblink( short w ) +{ + unsigned long now; + short + x = VSIw->x, + y = VSIw->y, + x2, + y2, + n = 1, + offset; + + if (!gApplicationPrefs->BlinkCursor + || VSvalids(w) + || !VSIcursorvisible() + || ((!RSlocal[w].active || TelInfo->suspended) && !RSlocal[w].cursorstate)) + return; + if ( (now = LMGetTicks()) - TelInfo->blinktime >= CURS_BLINK_PERIOD ) { + GrafPtr savePort; + GetPort(&savePort); + TelInfo->blinktime = now; + RSlocal[w].cursorstate ^= 1; + SetPort(RSlocal[w].window); + InvertRect(&RSlocal[w].cursor); + SetPort(savePort); + } +} /* VScursblink */ + + +/* + * VScursblinkon + */ + +void VScursblinkon( short w ) +{ + if (!gApplicationPrefs->BlinkCursor + || VSvalids(w) + || !VSIcursorvisible() + || !RSlocal[w].active + || TelInfo->suspended) + return; + TelInfo->blinktime = LMGetTicks(); + if ( !RSlocal[w].cursorstate ) { + GrafPtr savePort; + GetPort(&savePort); + RSlocal[w].cursorstate = 1; + SetPort(RSlocal[w].window); + InvertRect(&RSlocal[w].cursor); + SetPort(savePort); + } +} /* VScursblinkon */ + + +/* + * VScursblinkoff + */ + +void VScursblinkoff( short w ) +{ + + if (!gApplicationPrefs->BlinkCursor || VSvalids(w) || !VSIcursorvisible()) + return; + if ( RSlocal[w].cursorstate ) { + GrafPtr savePort; + GetPort(&savePort); + RSlocal[w].cursorstate = 0; + TelInfo->blinktime = LMGetTicks() - CURS_BLINK_PERIOD; + SetPort(RSlocal[w].window); + InvertRect(&RSlocal[w].cursor); + SetPort(savePort); + } +} /* VScursblinkoff */ + + + + VSlineArray VSInewlinearray ( short nrlines @@ -629,11 +703,10 @@ void VSIelo if (s < 0) s = VSIw->y; + VSIw->linest[s]->lattr = 0; if (VSIw->oldScrollback) { - VSIw->attrst[s]->lattr = 0; ta = &VSIw->attrst[s]->text[0]; } else { - VSIw->linest[s]->lattr = 0; ta = &VSIw->linest[s]->attr[0]; } tt = &VSIw->linest[s]->text[0]; @@ -730,12 +803,15 @@ void VSIreset VSIw->DECPAM = 0; VSIw->DECORG = 0; /* NCSA: SB -- is this needed? */ VSIw->DECCM = 1; // Bri 970610 - VSIw->Pattrib = 0xffff; /* NCSA: SB -- is this needed? */ + VSIw->Pattrib = 0xffffffff; /* NCSA: SB -- is this needed? */ VSIw->IRM = 0; VSIw->attrib = 0; VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; + VSIw->trincount = 0; + VSIw->trinx = 0; + VSIw->trintag = 0; VSIw->prbuf=0; /* LU */ if (VSIw->prredirect) { /* LU - kill redirection */ VSIw->prredirect=0; /* LU */ @@ -851,7 +927,9 @@ void VSOdellines short i, j; char *tt; VSAttrib *ta; - VSlinePtr as, ts, TD, BD, TI, BI, itt, ita; + VSlinePtr as, ts, TD, BD, TI, BI, itt; + VSattrlinePtr ita; + if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) @@ -897,13 +975,12 @@ void VSOdellines VSIlistmove(TD, BD, TI, BI); /* blank out the newly-created replacement lines */ - ita = TD; /* start of attribute lines to be blanked out */ + ita = (VSattrlinePtr)TD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { - ta = ((VSattrlinePtr)ita)->text; - ita->lattr = 0; itt->lattr = 0; tt = itt->text; + ta = ita->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; @@ -1059,10 +1136,9 @@ void VSOinslines ita = aTD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { + itt->lattr = 0; tt = itt->text; ta = ita->text; - itt->lattr = 0; - ita->lattr = 0; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; @@ -1312,7 +1388,6 @@ void VSOscroll else VSIw->vistop = VSIw->vistop->next; /* consistent with changed display */ /* blank out newly-revealed bottom line */ - VSIw->attrst[VSIw->lines]->lattr = 0; VSIw->linest[VSIw->lines]->lattr = 0; tempa = VSIw->attrst[VSIw->lines]->text; temp = VSIw->linest[VSIw->lines]->text; @@ -1373,7 +1448,9 @@ void VSIindex /* moves cursor down one line, unless it's at the bottom of the scrolling region, in which case scrolls up one. */ // RAB BetterTelnet 2.0b3 - added jump scrolling so it runs faster - { +{ + short sn = findbyVS(VSIwn); + if (VSIw->y == VSIw->bottom) { /* BYU - changed "==" to ">=" and back again */ if (VSIw->jumpScroll) if (VSIw->linesjumped || !RSlocal[VSIwn].skip) @@ -1389,6 +1466,12 @@ void VSIindex VSIw->lattrib = 0; + // back to default input translation ? + if ( sn >= 0 ) { + WindRec *tw = &screens[sn]; + switchintranslation(tw, tw->outnational, tw->outcharset); + } + } /* VSIindex */ void VSIwrapnow(short *xp, short *yp) @@ -1399,7 +1482,7 @@ void VSIwrapnow(short *xp, short *yp) { short mw = VSIw->maxwidth; - if ((VSIw->lattrib & 3)) { + if (VSisdecdwh(VSIw->lattrib)) { mw >>= 1; if ( !(VSIw->maxwidth & 1) ) mw -= 1; @@ -1448,11 +1531,10 @@ void VSIeeol } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { + savedTextPtr->lattr = VSIw->linest[i]->lattr; if (VSIw->oldScrollback) { - savedTextPtr->lattr = VSIw->attrst[i]->lattr; BlockMoveData(VSIw->attrst[i]->text, savedTextPtr->attr, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } else { - savedTextPtr->lattr = VSIw->linest[i]->lattr; BlockMoveData(VSIw->linest[i]->attr, savedTextPtr->attr, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; @@ -1467,11 +1549,10 @@ void VSIeeol } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { + VSIw->linest[i]->lattr = savedTextPtr->lattr; if (VSIw->oldScrollback) { - VSIw->attrst[i]->lattr = savedTextPtr->lattr; BlockMoveData(savedTextPtr->attr, VSIw->attrst[i]->text, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } else { - VSIw->linest[i]->lattr = savedTextPtr->lattr; BlockMoveData(savedTextPtr->attr, VSIw->linest[i]->attr, (VSIw->allwidth + 1) * sizeof(VSAttrib)); } if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; @@ -1482,11 +1563,10 @@ void VSIeeol VSIwrapnow(&x1, &y1); y2 = y1; /* clear out screen line */ + //VSIw->linest[y1]->lattr = 0; if (VSIw->oldScrollback) { - VSIw->attrst[y1]->lattr = 0; ta = &VSIw->attrst[y1]->text[x1]; } else { - VSIw->linest[y1]->lattr = 0; ta = &VSIw->linest[y1]->attr[x1]; } tt = &VSIw->linest[y1]->text[x1]; @@ -1496,8 +1576,10 @@ void VSIeeol *tt++ = ' '; } /* update display */ - if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) - RSerase(VSIwn, x1, y1, x2, y2); + if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) { + //RSerase(VSIwn, x1, y1, x2, y2); + VSredraw(VSIwn, x1, y1, x2, y2); + } } /* VSIeeol */ void VSIdelchars @@ -1528,12 +1610,11 @@ void VSIdelchars if (x > VSIw->maxwidth) x = VSIw->maxwidth; + lattr = VSIw->linest[y1]->lattr; if (VSIw->oldScrollback) { tempa = VSIw->attrst[y1]->text; - lattr = VSIw->attrst[y1]->lattr; } else { tempa = VSIw->linest[y1]->attr; - lattr = VSIw->linest[y1]->lattr; } temp = VSIw->linest[y1]->text; for (i = x1; i <= VSIw->maxwidth - x; i++) @@ -1635,11 +1716,10 @@ void VSIebol VSIwrapnow(&x2, &y1); y2 = y1; /* clear from beginning of line to cursor */ + //VSIw->linest[y1]->lattr = 0; if (VSIw->oldScrollback) { - //VSIw->attrst[y1]->lattr = 0; ta = &VSIw->attrst[y1]->text[0]; } else { - //VSIw->attrst[y1]->lattr = 0; ta = &VSIw->linest[y1]->attr[0]; } tt = &VSIw->linest[y1]->text[0]; @@ -1671,11 +1751,10 @@ void VSIel x1 = 0; } /* clear out line */ + //VSIw->linest[s]->lattr = 0; if (VSIw->oldScrollback) { - //VSIw->attrst[s]->lattr = 0; ta = &VSIw->attrst[s]->text[0]; } else { - //VSIw->linest[s]->lattr = 0; ta = &VSIw->linest[s]->attr[0]; } tt = &VSIw->linest[s]->text[0]; @@ -1773,7 +1852,7 @@ void VSIrange short wrap = (VSIw->DECAWM) ? 1 : 0; short mw = VSIw->maxwidth; - if ((VSIw->lattrib & 3)) { + if (VSisdecdwh(VSIw->lattrib)) { mw >>= 1; if ( !(VSIw->maxwidth & 1) ) mw -= 1; @@ -1803,7 +1882,7 @@ void VTsendpos( void ) y = VSIw->y; short mw = VSIw->maxwidth; - if ((VSIw->lattrib & 3)) { + if (VSisdecdwh(VSIw->lattrib)) { mw >>= 1; if ( !(VSIw->maxwidth & 1) ) mw -= 1; @@ -1872,7 +1951,12 @@ void VTsendstat( void ) void VTsendident( void ) { - if (screens[findbyVS(VSIwn)].vtemulation) + short sn = findbyVS(VSIwn); + + if ( sn < 0 ) + return; + + if (screens[sn].vtemulation) //RSsendstring(VSIwn, "\033[?62;1;6c", 10); // VT200-series RSsendstring(VSIwn, "\033[?62;1;2;6;7;8c", 16); // VT200-series else @@ -2014,7 +2098,8 @@ void VSItab //BUGG void VSIinschar ( - short x /* number of blanks to insert */ + short x, /* number of blanks to insert */ + short clear ) /* inserts the specified number of blank characters at the current cursor position, moving the rest of the line along, @@ -2031,19 +2116,19 @@ void VSIinschar else tempa = VSIw->linest[VSIw->y]->attr; temp = VSIw->linest[VSIw->y]->text; - for (i = VSIw->maxwidth - x; i >= VSIw->x; i--) - { - /* move along remaining characters on line */ + for (i = VSIw->maxwidth - x; i >= VSIw->x; i--) { + /* move along remaining characters on line */ temp[x + i] =temp[i]; tempa[x + i] = tempa[i]; - } /* for */ - for (i = VSIw->x; i < VSIw->x + x; i++) - { - /* insert appropriate number of blanks */ - temp[i] = ' '; - tempa[i] = VSIclrattrib; - } /* for */ - } /* VSIinschar */ + } + if ( clear ) { + for (i = VSIw->x; i < VSIw->x + x; i++) { + /* insert appropriate number of blanks */ + temp[i] = ' '; + tempa[i] = VSIclrattrib; + } + } +} /* VSIinschar */ void VSIinsstring ( @@ -2077,7 +2162,7 @@ void VSIrestore ) /* restores the last-saved cursor position and attribute settings. */ { - if (VSIw->Pattrib == 0xffff) + if (VSIw->Pattrib == 0xffffffff) /* no previous save */ return; @@ -2086,7 +2171,9 @@ void VSIrestore VSIw->x = VSIw->Px; VSIw->y = VSIw->Py; VSIrange(); - VSIw->attrib = VSinattr(VSIw->Pattrib); /* hmm, this will clear the graphics character set selection */ + // keep the graphics character set selection + VSIw->attrib &= kVSgrph; + VSIw->attrib |= VSIw->Pattrib; } /* VSIrestore */ void VSIdraw diff --git a/macssh/source/Screens/vsintern.proto.h b/macssh/source/Screens/vsintern.proto.h index 64f0f9b..344c22e 100755 --- a/macssh/source/Screens/vsintern.proto.h +++ b/macssh/source/Screens/vsintern.proto.h @@ -9,6 +9,10 @@ void VSIcurson(short w, short x, short y, short ForceMove); void VSIcuroff(short w); short VSIcursorenabled( void ); short VSIcursorvisible(void); +void VScursblink(short w); +void VScursblinkon(short w); +void VScursblinkoff(short w); + VSlineArray VSInewlinearray(short nrlines); VSlinePtr VSInewlines(short nlines); VSlinePtr VSOnewlines(short, short); @@ -50,7 +54,7 @@ void VTalign(void); void VSIapclear(void); void VSIsetoption(short toggle); void VSItab(void); -void VSIinschar(short x); +void VSIinschar(short x, short clear); void VSIinsstring(short len, char *start); void VSIsave(void); void VSIrestore(void); diff --git a/macssh/source/Screens/vskeys.h b/macssh/source/Screens/vskeys.h index a72040d..b994bcf 100755 --- a/macssh/source/Screens/vskeys.h +++ b/macssh/source/Screens/vskeys.h @@ -93,48 +93,82 @@ extern unsigned char *VSIkplen; /* BYU 2.4.12 */ /* * Definition of attribute bits in the Virtual Screen * - * 0 - Bold - * 1 - faint - * 2 - italic - * 3 - Underline - * 4 - slowly Blinking - * 5 - rapidly Blinking - * 6 - Reverse - * 7 - Graphics character set - * 8 - bit 0 of ansi foreground color index - * 9 - bit 1 of ansi foreground color index - * 10 - bit 2 of ansi foreground color index - * 11 - use ansi foreground color - * 12 - bit 0 of ansi background color index - * 13 - bit 1 of ansi background color index - * 14 - bit 2 of ansi background color index - * 15 - use ansi background color + * 0 - 0x000001 - Bold + * 1 - 0x000002 - faint + * 2 - 0x000004 - italic + * 3 - 0x000008 - Underline + * 4 - 0x000010 - slowly Blinking + * 5 - 0x000020 - rapidly Blinking + * 6 - 0x000040 - Reverse + * 7 - 0x000080 - Graphics character set + * 8 - bit 0 of ansi foreground color index + * 9 - bit 1 of ansi foreground color index + * 10 - bit 2 of ansi foreground color index + * 11 - 0x000800 - use ansi foreground color + * 12 - bit 0 of ansi background color index + * 13 - bit 1 of ansi background color index + * 14 - bit 2 of ansi background color index + * 15 - 0x008000 - use ansi background color + * 16 - 0x010000 - use 2nd ansi foreground color + * 17 - 0x020000 - use 2nd ansi background color + * 18 - 0x040000 - has first character in high byte * + * 8 higher bits: second character in multibyte mode */ + +/* character attributes */ + #define VSa(x) (1 << ((x) - 1)) -#define VSisbold(x) ((x) & 0x01) -#define VSisfaint(x) ((x) & 0x02) -#define VSisitalic(x) ((x) & 0x04) -#define VSisundl(x) ((x) & 0x08) -#define VSisblnk(x) ((x) & 0x10) -#define VSisfastblnk(x) ((x) & 0x20) -#define VSisrev(x) ((x) & 0x40) -#define VSisgrph(x) ((x) & 0x80) -#define VSisansifg(x) ((x) & 0x0800) -#define VSisansibg(x) ((x) & 0x08000) -#define VSisansi(x) ((x) & 0x08800) -#define VSisansifg2(x) ((x) & 0x10000) -#define VSisansibg2(x) ((x) & 0x20000) -//#define VSinattr(x) ((x) & 0xd9) -#define VSinattr(x) ((x) & 0xff) +#define kVSbold 0x000001 +#define kVSfaint 0x000002 +#define kVSitalic 0x000004 +#define kVSundl 0x000008 +#define kVSblnk 0x000010 +#define kVSfastblnk 0x000020 +#define kVSrev 0x000040 +#define kVSgrph 0x000080 +#define kVSansifg 0x000800 +#define kVSansibg 0x008000 +#define kVSansifg2 0x010000 +#define kVSansibg2 0x020000 +#define kVSansi2b 0x040000 +// 4 bits unused, higher bit (i.e. 0x00800000) MUST be left to 0 -#define VSgraph(x) ((x) | 0x80) -#define VSnotgraph(x) ((x) & 0x7F) +#define VSisbold(x) ((x) & kVSbold) +#define VSisfaint(x) ((x) & kVSfaint) +#define VSisitalic(x) ((x) & kVSitalic) +#define VSisundl(x) ((x) & kVSundl) +#define VSisblnk(x) ((x) & kVSblnk) +#define VSisfastblnk(x) ((x) & kVSfastblnk) +#define VSisrev(x) ((x) & kVSrev) +#define VSisgrph(x) ((x) & kVSgrph) +#define VSisansifg(x) ((x) & kVSansifg) +#define VSisansibg(x) ((x) & kVSansibg) +#define VSisansi(x) ((x) & (kVSansifg | kVSansibg)) +#define VSisansifg2(x) ((x) & kVSansifg2) +#define VSisansibg2(x) ((x) & kVSansibg2) +#define VSisansi2b(x) ((x) & kVSansi2b) -#define VSansifg(x) ((x) | 0x00800) -#define VSansibg(x) ((x) | 0x08000) -#define VSansifg2(x) ((x) | 0x10800) -#define VSansibg2(x) ((x) | 0x28000) +#define VSgraph(x) ((x) | kVSgrph) +#define VSnotgraph(x) ((x) & ~kVSgrph) +#define VSansifg(x) ((x) | kVSansifg) +#define VSansibg(x) ((x) | kVSansibg) +#define VSansifg2(x) ((x) | (kVSansifg2 | kVSansifg)) +#define VSansibg2(x) ((x) | (kVSansibg2 | kVSansibg)) +#define VSansi2b(x) ((x) | kVSansi2b) + +/* line attributes */ + +#define kVSdecdhlt 0x0001 +#define kVSdecdhlb 0x0002 +#define kVSwrap 0x0004 + +#define VSisdecdhlt(x) (((x) & kVSdecdhlt) && !((x) & kVSdecdhlb)) +#define VSisdecdhlb(x) (((x) & kVSdecdhlb) && !((x) & kVSdecdhlt)) +#define VSisdecdwl(x) (((x) & (kVSdecdhlt|kVSdecdhlb)) == (kVSdecdhlt|kVSdecdhlb)) +#define VSisdecdwh(x) (((x) & (kVSdecdhlt|kVSdecdhlb)) && !VSisdecdwl(x)) +//#define VSisdecdw(x) (((x) & (kVSdecdhlt|kVSdecdhlb))) +#define VSiswrap(x) ((x) & kVSwrap) #endif diff --git a/macssh/source/Screens/wind.h b/macssh/source/Screens/wind.h index 95331f7..95e08a5 100755 --- a/macssh/source/Screens/wind.h +++ b/macssh/source/Screens/wind.h @@ -6,6 +6,7 @@ #define __WIND__ #include +#include #define MAXKB 256 // BYU mod @@ -48,7 +49,8 @@ short vtemulation, // 0 = VT100, 1 = VT 220 bsdel, // backspace or delete is default eightbit, // eight bit font displayed (false is seven bit display - national, // LU/MP: translation table to use for this connection + innational, // translation table to use for this connection for input + outnational, // translation table to use for this connection for output arrowmap, // MAT: should we allow the arrow keys to be mapped?? showErrors, // show ALL errors if this is set pgupdwn, // JMB/MAT: should we have page up/down do local window movement? @@ -249,6 +251,18 @@ short remoteport; char remotehost[180]; + +short + incharset, // current translation state for multi-byte translation + outcharset, // current translation state for multi-byte translation + troutcount; + +unsigned char + troutbuf[16]; // chars pending in translation + +TECObjectRef + fromconverter, + toconverter; /* NONO */ diff --git a/macssh/source/Sets/Sets.c b/macssh/source/Sets/Sets.c index dcbb47f..1a91abc 100755 --- a/macssh/source/Sets/Sets.c +++ b/macssh/source/Sets/Sets.c @@ -209,7 +209,7 @@ short confile( char *s) break; case 2: /* HOST */ - strncpy(tempCstring, s, 63); /* Move name in */ + strncpy(tempCstring, s, sizeof(SetSessionPtr->hostname) - 1); /* Move name in */ CtoPstr(tempCstring); // Process the hosname string. @@ -375,9 +375,11 @@ short confile( char *s) TelInfo->CONFstate = 0; break; case 26: /* Font Name */ - strncpy(tempCstring, s, 63); /* Move name in */ - CtoPstr(tempCstring); - BlockMoveData(tempCstring, &(SetTerminalPtr->DisplayFont[0]), tempCstring[0]+1); +// strncpy(tempCstring, s, 63); /* Move name in */ +// CtoPstr(tempCstring); +// BlockMoveData(tempCstring, &(SetTerminalPtr->DisplayFont[0]), tempCstring[0]+1); + strncpy((char *) SetTerminalPtr->DisplayFont, s, sizeof(SetTerminalPtr->DisplayFont) - 1); + CtoPstr((char *) SetTerminalPtr->DisplayFont); TelInfo->CONFstate = 0; break; case 27: /* Font Size */ @@ -439,7 +441,7 @@ short confile( char *s) TelInfo->CONFstate = 0; /* NCSA */ break; /* NCSA */ case 38: // translation - strncpy((char *) SetSessionPtr->TranslationTable, s, 32); + strncpy((char *) SetSessionPtr->TranslationTable, s, sizeof(SetSessionPtr->TranslationTable) - 1); CtoPstr((char *) SetSessionPtr->TranslationTable); TelInfo->CONFstate=0; break; @@ -449,7 +451,7 @@ short confile( char *s) TelInfo->CONFstate=0; break; case 40: // answerback - strncpy((char *) SetTerminalPtr->AnswerBackMessage, s, 32); + strncpy((char *) SetTerminalPtr->AnswerBackMessage, s, sizeof(SetTerminalPtr->AnswerBackMessage) - 1); CtoPstr((char *) SetTerminalPtr->AnswerBackMessage); TelInfo->CONFstate=0; break; @@ -573,9 +575,11 @@ short confile( char *s) TelInfo->CONFstate=0; break; case 63: // boldfont - strncpy(tempCstring, s, 63); /* Move name in */ - CtoPstr(tempCstring); - BlockMoveData(tempCstring, &(SetTerminalPtr->BoldFont[0]), tempCstring[0]+1); + //strncpy(tempCstring, s, 63); /* Move name in */ + //CtoPstr(tempCstring); + //BlockMoveData(tempCstring, &(SetTerminalPtr->BoldFont[0]), tempCstring[0]+1); + strncpy((char *) SetTerminalPtr->BoldFont, s, sizeof(SetTerminalPtr->BoldFont) - 1); + CtoPstr((char *) SetTerminalPtr->BoldFont); TelInfo->CONFstate = 0; break; case 64: // inversebold @@ -604,9 +608,11 @@ short confile( char *s) TelInfo->CONFstate = 0; break; case 69: // otppassword - strncpy(tempCstring, s, 63); /* Move name in */ - CtoPstr(tempCstring); - BlockMoveData(tempCstring, &(SetSessionPtr->otppassword[0]), tempCstring[0]+1); + //strncpy(tempCstring, s, 63); /* Move name in */ + //CtoPstr(tempCstring); + //BlockMoveData(tempCstring, &(SetSessionPtr->otppassword[0]), tempCstring[0]+1); + strncpy((char *) SetSessionPtr->otppassword, s, sizeof(SetSessionPtr->otppassword) - 1); + CtoPstr((char *) SetSessionPtr->otppassword); TelInfo->CONFstate = 0; break; case 70: // realbold @@ -904,7 +910,7 @@ void SaveSet(short doSaveMacros, short dontSaveTitle) Rect rect; Point where; long junk; - char temp[256], temp2[256]; /* BYU LSC */ + char temp[256], temp2[300]; /* BYU LSC */ short fnum,fsiz; short i; FSSpec set; @@ -1115,9 +1121,9 @@ void SaveSet(short doSaveMacros, short dontSaveTitle) CStringToFile(fn, (unsigned char *)temp2); } -// if (screens[i].national) { // Don't do this if using default translation table +// if (screens[i].outnational) { // Don't do this if using default translation table // TranslationTable - GetMenuItemText(myMenus[National], screens[i].national+1, scratchPstring); + GetMenuItemText(myMenus[National], screens[i].outnational+1, scratchPstring); //pstrcpy(scratchPstring, (unsigned char *)TranslationTable); PtoCstr(scratchPstring); sprintf(temp2, "translation= \"%s\"\015", scratchPstring); @@ -1229,7 +1235,7 @@ void SaveSetFromSession(SessionPrefs* setSession, TerminalPrefs* setTerminal, sh Rect rect; Point where; long junk; - char temp[256], temp2[256]; /* BYU LSC */ + char temp[256], temp2[300]; /* BYU LSC */ short fnum,fsiz, i; FSSpec set; OSErr err; diff --git a/macssh/source/Url/url.c b/macssh/source/Url/url.c index 0459ee5..9b5b385 100755 --- a/macssh/source/Url/url.c +++ b/macssh/source/Url/url.c @@ -553,6 +553,100 @@ OSErr OpenHelperWithURL (OSType sig, char *url) } #define isurlschemechar(c) (isalnum((c)) || c == '+' || c == '.' || c == '-') + +/* + * FindURLAroundPoint + * + * called by RSSelect when Command Click has occured outside any selection. + * This routine looks for urls around the current point, makes that the selected area if + * it finds one, and returns TRUE. Otherwise leaves the current selection area untouched + * and returns FALSE. + */ + +Boolean FindURLAroundPoint(Point curr, short w) +{ + Boolean found; + short columns; + short blockSize; + Handle lblock; + Handle rblock; + Point topleft; + Point botright; + short lblockSize; + short rblockSize; + char *p, *q, cp, cq; + + found = FALSE; + columns = VSgetcols(w) + 1; // VSgetcols returns one less than the number of columns + + if ( curr.h < 0 ) + curr.h = 0; + if ( curr.h >= columns ) + curr.h = columns - 1; + + topleft.h = curr.h - 255; + topleft.v = curr.v; + while ( topleft.h < 0 ) { + topleft.h += columns; + --topleft.v; + } + blockSize = 255 + (curr.v - topleft.v) + 1; + lblock = myNewHandle(blockSize); + HLock(lblock); + lblockSize = VSgettext(w, topleft.h, topleft.v, curr.h, curr.v, *lblock, blockSize, "\015", 0, 0); + + botright.h = curr.h + 255; + botright.v = curr.v; + while ( botright.h >= columns ) { + botright.h -= columns; + ++botright.v; + } + blockSize = 255 + (botright.v - curr.v) + 1; + rblock = myNewHandle(blockSize); + HLock(rblock); + rblockSize = VSgettext(w, curr.h, curr.v, botright.h, botright.v, *rblock, blockSize, "\015", 0, 0); + + blockSize = lblockSize + rblockSize; + HUnlock(lblock); + SetHandleSize(lblock, blockSize); + HLock(lblock); + BlockMoveData( *rblock, *lblock + lblockSize, rblockSize ); + DisposeHandle(rblock); + p = *lblock + lblockSize; + if ( !isLWSPorCR(*p) ) { + topleft.h = curr.h; + topleft.v = curr.v; + while ( p > *lblock && *p != '<' && !isLWSPorCR(p[-1]) && p[-1] != '"') { + --p; + if ( --topleft.h < 0 ) { + topleft.h += columns; + --topleft.v; + } + } + q = *lblock + lblockSize; // check first char of second block + botright.h = curr.h + 1; + botright.v = curr.v; + while ( q < *lblock + blockSize && *q != '>' && !isLWSPorCR(q[1]) && q[1] != '"' ) { + ++q; + if ( ++botright.h >= columns ) { + botright.h -= columns; + ++botright.v; + } + } + if ( q < *lblock + blockSize ) { + if (p < q && q - p < 256 && ((*p == '<' && *q == '>') || (*p != '<' && *q != '>'))) { + // found something + HiliteThis(w, topleft, botright); + found = TRUE; + } + } + } + DisposeHandle(lblock); + return found; +} + +#if 0 + Boolean FindURLAroundPoint(Point curr, short w) { /* called by RSSelect when Command Click has occured outside any selection. @@ -564,7 +658,6 @@ Boolean FindURLAroundPoint(Point curr, short w) Handle block; char *original, *start, *end, *textEnd, *p, *q; short i, numLines = 1; - char EOLS = CR; short neededLines, endLine = 0, startLine = 0; short blockSize; Point startPoint, endPoint; @@ -606,7 +699,7 @@ Boolean FindURLAroundPoint(Point curr, short w) textEnd = *block + blockSize; /* get the lines we need */ - VSgettext(w, 0, firstLine, columns-1, lastLine, *block, blockSize, &EOLS, 0); + VSgettext(w, 0, firstLine, columns-1, lastLine, *block, blockSize, "\015", 0, 0); original = *block; // RJZ 12/12/97. Fixed so that after @@ -750,3 +843,5 @@ Boolean FindURLAroundPoint(Point curr, short w) DisposeHandle(block); return TRUE; } + +#endif \ No newline at end of file diff --git a/macssh/source/config/configure.c b/macssh/source/config/configure.c index 8f1fa36..4cee7b8 100755 --- a/macssh/source/config/configure.c +++ b/macssh/source/config/configure.c @@ -34,6 +34,7 @@ #include "sshglue.proto.h" #include "errors.proto.h" #include "macros.proto.h" +#include "translate.proto.h" /* ssh2.c */ extern void clearcachedpassphrase(); @@ -1838,13 +1839,7 @@ Boolean EditSession(StringPtr PrefRecordNamePtr) UseResFile(TelInfo->ApplicationFile); SPopup[1].h = NewMenu(667, "\p"); - numberOfTerms = CountResources(USER_TRSL); - currentHead = createSortedList2(USER_TRSL,numberOfTerms,NULL); - GetIndString(scratchPstring,MISC_STRINGS,NONE_STRING); //"None" string - AppendMenu(SPopup[1].h,scratchPstring); - addListToMenu/*3*/(SPopup[1].h, currentHead, 2); - EnableItem(SPopup[1].h, 0); // Make sure the entire menu is enabled - deleteList(¤tHead); + BuildTranslateMenu(SPopup[1].h); UseResFile(TelInfo->SettingsFile); currentHead = savedList; @@ -1857,9 +1852,8 @@ Boolean EditSession(StringPtr PrefRecordNamePtr) if (IsDefaultLabel(PrefRecordNamePtr)) { HideDialogItem(dptr, SessAlias); HideDialogItem(dptr, SessAliasStatText); - } } - else { + } else { SessPrefsHdl = GetDefaultSession(); IsNewPrefRecord = TRUE; GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION); diff --git a/macssh/source/debug-errors/DlogUtils.c b/macssh/source/debug-errors/DlogUtils.c index a196821..0dbb5bd 100755 --- a/macssh/source/debug-errors/DlogUtils.c +++ b/macssh/source/debug-errors/DlogUtils.c @@ -459,6 +459,8 @@ WindowPtr GetNewMyDialog(short template,Ptr wStorage,WindowPtr behind, win = GetNewDialog(template, wStorage, behind); if (win==nil) return(nil); SetPort(win); + TextFont(systemFont); + TextSize(12); /* win->contR = ((GrafPtr)win)->portRect; */ /* win->qWindow.refCon = CREATOR; */ return(win); diff --git a/macssh/source/debug-errors/telnetdebug.c b/macssh/source/debug-errors/telnetdebug.c index 11c1285..1cbf38d 100755 --- a/macssh/source/debug-errors/telnetdebug.c +++ b/macssh/source/debug-errors/telnetdebug.c @@ -29,17 +29,20 @@ void InitDebug(void) Rect pRect; TerminalPrefs **termHdl; Boolean scratchBoolean; + unsigned long flags; + console = (WindRec *) myNewPtr(sizeof(WindRec)); + console->vs = -1; // SetRect(&pRect, 50, 150, 700, 350); // Need to make this a resource! SetRect(&pRect, 50, 150, 0, 0); -/* - console->vs=RSnewwindow( &pRect, 350, 80, 24, - "\p", 1, DefFONT, DefSIZE, TelInfo->debug,0,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1, 0, 0); -*/ - console->vs=RSnewwindow( &pRect, 2000, 80, 24, - "\p", 1, DefFONT, DefSIZE, TelInfo->debug,0,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1, 0, 0); /* NCSA 2.5 */ + flags = RSWwrapon | RSWgoaway | RSWignoreBeeps | RSWsavelines; + if (TelInfo->debug) + flags |= RSWshowit; + + console->vs=RSnewwindow( &pRect, 2000, 80, 24, "\p", DefFONT, DefSIZE, 0, + DefFONT, DefSIZE, 0, 0, flags); console->wind = RSgetwindow( console->vs); ((WindowPeek)console->wind)->windowKind = WIN_CONSOLE; @@ -48,7 +51,10 @@ void InitDebug(void) console->active=0; console->port=-1; console->termstate=VTEKTYPE; - console->national = 0; /* LU: no translation */ + console->innational = 0; /* LU: no translation */ + console->incharset = -1; + console->outnational = 0; + console->outcharset = -1; UseResFile(TelInfo->SettingsFile); termHdl = (TerminalPrefs **)Get1NamedSizedResource (TERMINALPREFS_RESTYPE, "\p", sizeof(TerminalPrefs)); @@ -87,8 +93,8 @@ void putlln( char *cp, short len ) char buf[256]; short temp; - size = VSgetcols(console->vs) + 1; - while (len > 0) { + size = VSgetcols(console->vs) + 1; + while ( size > 0 && len > 0 ) { short inlen = 0; short outlen = 0; temp = len; diff --git a/macssh/source/init/init.c b/macssh/source/init/init.c index 508f084..f1df356 100755 --- a/macssh/source/init/init.c +++ b/macssh/source/init/init.c @@ -61,6 +61,8 @@ extern char *getprefsd(char *name, char * buf, size_t size, short *vRefNum, long //extern char *tempspot; /* for temp storage only */ +Boolean gInitialized = 0; + extern Cursor *theCursors[]; extern WindRec @@ -111,15 +113,20 @@ void initftplog( void) TerminalPrefs **termHdl; Boolean scratchBoolean; Str255 tempString; + unsigned long flags; SetRect(&prect, 300,256,512,384); ftplog = (WindRec *) myNewPtr(sizeof(WindRec)); GetIndString(tempString,MISC_STRINGS,FTP_LOG_STRING); - ftplog->vs=RSnewwindow( &prect, 50, 80, 24, - tempString, 1, DefFONT, DefSIZE, gFTPServerPrefs->ShowFTPlog, - 1,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1, 0, 0); /* NCSA 2.5 */ + + flags = RSWwrapon | RSWgoaway | RSWignoreBeeps | RSWsavelines; + if (gFTPServerPrefs->ShowFTPlog) + flags |= RSWshowit; + + ftplog->vs=RSnewwindow( &prect, 50, 80, 24, tempString, DefFONT, DefSIZE, 0, + DefFONT, DefSIZE, 0, 0, flags); ftplog->wind = RSgetwindow( ftplog->vs); ((WindowPeek)ftplog->wind)->windowKind = WIN_LOG; @@ -521,4 +528,5 @@ void init (void) } loadWDEF(); //this just loads the WDEF code in so that it doesnt fragment the heap later loadErrors(); //ditto for the error code + gInitialized = true; } diff --git a/macssh/source/macros/macros.c b/macssh/source/macros/macros.c index 42e19cf..8a4aaf7 100755 --- a/macssh/source/macros/macros.c +++ b/macssh/source/macros/macros.c @@ -29,9 +29,13 @@ #include "vsinterf.proto.h" #include "macros.proto.h" +#include "netevent.proto.h" #include "Sets.proto.h" //for CStringToFile #include "movableModal.h" +#include "PasswordDialog.h" + +extern void ssh2_sched(); /* Macro Defines */ #define MACRO_IP 0xff /* Send IP number here */ @@ -379,6 +383,9 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ unsigned char myipnum[4]; Handle mh, ph; short i, num, pos, escape, length; + char *plabel; + Str255 password; + unsigned long startTicks; // Invalid number if (n < 0 || n >= NUM_MACROS) { @@ -402,7 +409,7 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ s = (unsigned char *)*mh; - ph = myNewHandle(GetHandleSize(mh)); + ph = myNewHandle(GetHandleSize(mh) + 256); if (!ph) return 0; // ouch HLock(ph); first = p = (unsigned char *)*ph; @@ -417,8 +424,7 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ escape = 0; while ( *s) { - if (((!(*s >= '0' && *s <= '9')) && pos && escape) || - (escape && (pos >= 3))) { + if (escape == 1 && (((*s < '0' || *s > '9') && pos) || pos >= 3)) { // do this ONCE - // it's a kludge to do this in each case *p++=num; @@ -426,20 +432,20 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ escape = 0; // now the rest of the code will take care of whatever char this was } - if (escape) { + if (escape == 1) { escape = 0; switch (*s) { case 'i': SendStringAsIfTyped(tw, (char *)first, p-first); sprintf(temp,"%d.%d.%d.%d", myipnum[0], myipnum[1], myipnum[2], myipnum[3]); SendStringAsIfTyped(tw, temp, strlen(temp)); - first = p; + first = p = (unsigned char *)*ph; break; case '#': SendStringAsIfTyped(tw, (char *)first, p-first); sprintf(temp,"%d", VSgetlines(tw->vs)); SendStringAsIfTyped(tw, temp, strlen(temp)); - first = p; + first = p = (unsigned char *)*ph; break; case 'n': *p++='\012'; @@ -456,6 +462,9 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ case '\\': *p++='\\'; break; + case 'k': + escape = 2; + break; default: if (*s <='9' && *s >='0' && pos <3) { num= num*8+( *s -'0'); @@ -475,8 +484,37 @@ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ } break; } + } else if (escape == 2) { + if (*s == '{') { + escape = 3; + plabel = NULL; + } else { + escape = 0; } - else { + } else if (escape == 3) { + if (*s != '}') { + if ( plabel == NULL ) + plabel = s; + } else { + *s = 0; + if (plabel && SSH2PasswordDialog(plabel, password)) { + SendStringAsIfTyped(tw, (char *)first, p-first); + // better wait for echo off... + startTicks = TickCount(); + while (TickCount() - startTicks < 30) { + ssh2_sched(); + DoNetEvents(); + } + first = p = (unsigned char *)*ph; + SendStringAsIfTyped(tw, (char *)password + 1, password[0]); + } else { + // malformed macro, or pasword cancel + first = p = (unsigned char *)*ph; + break; + } + escape = 0; + } + } else { if (*s=='\\') { num=0; pos=0; diff --git a/macssh/source/main/Connections.c b/macssh/source/main/Connections.c index 8f55c4e..ab44089 100755 --- a/macssh/source/main/Connections.c +++ b/macssh/source/main/Connections.c @@ -37,6 +37,7 @@ #include "prefs.proto.h" #include "popup.h" #include "popup.proto.h" +#include "translate.proto.h" #include "Connections.proto.h" #include "tnae.h" @@ -56,6 +57,7 @@ extern Cursor *theCursors[NUMCURS]; /* all the cursors in a nice bundle */ extern WindRec *screens; extern short scrn; extern short nNational; // Number of user-installed translation tables +extern short gTableCount; extern MenuHandle myMenus[]; extern Boolean authOK; extern Boolean encryptOK; @@ -100,6 +102,10 @@ void OpenPortSpecial(MenuHandle menuh, short item) success = CreateConnectionFromParams(theParams); } +static Boolean startautocomplete = false; +static Boolean doneautocomplete = false; +static unsigned long autoTicks; + SIMPLE_UPP(POCdlogfilter, ModalFilter); pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item) { @@ -143,28 +149,42 @@ pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item) // return(PopupMousedown(dptr, evt, item)); /* NONO */ +/* if ( gApplicationPrefs->parseAliases ) { editField = ((DialogPeek)dptr)->editField + 1; if ( editField == NChostname ) { - GetTEText(dptr, NChostname, scratch1Pstring); + GetTEText(dptr, editField, scratch1Pstring); } } +*/ /* NONO */ // RAB BetterTelnet 1.2 - we let StdFilterProc handle this now // return(DLOGwOK_Cancel(dptr, evt, item)); result = CallStdFilterProc(dptr, evt, item); - + /* NONO */ +/* if ( gApplicationPrefs->parseAliases ) { if ( editField == NChostname && (evt->what == keyDown || evt->what == autoKey) ) { - GetTEText(dptr, NChostname, scratch2Pstring); + GetTEText(dptr, editField, scratch2Pstring); if (memcmp(scratch1Pstring, scratch2Pstring, scratch1Pstring[0] + 1)) { - *item = NChostname; - result = true; + // host name changed + //*item = editField; + //result = true; + autoTicks = LMGetTicks(); + startautocomplete = true; } } } +*/ + if ( startautocomplete && LMGetTicks() - autoTicks >= 30 ) { + startautocomplete = false; + doneautocomplete = true; + *item = NChostname; + result = -1; + } + /* NONO */ return result; @@ -232,6 +252,7 @@ Boolean PresentOpenConnectionDialog(void) short ditem, scratchshort, mystrpos; Boolean success; long scratchlong; + Str255 hostString; Str255 scratchPstring, terminalPopupString, scritchPstring; Handle ItemHandle; SessionPrefs **tempSessHdl; @@ -316,6 +337,8 @@ Boolean PresentOpenConnectionDialog(void) BlockMoveData("\p", scratchPstring, 15); SetCurrentSession(dptr, scratchPstring); + GetTEText(dptr, NChostname, hostString); + // TerminalIndex = findPopupMenuItem(TermPopupHdl,(**defaultSessHdl).TerminalEmulation); // TPopup[0].choice = TerminalIndex; // PopupInit(dptr, TPopup); @@ -326,7 +349,10 @@ Boolean PresentOpenConnectionDialog(void) ShowWindow(dptr); - while (ditem > NCcancel) { + startautocomplete = false; + doneautocomplete = false; + + while (ditem != NCconnect && ditem != NCcancel) { movableModalDialog(POCdlogfilterUPP, &ditem); switch(ditem) { @@ -347,16 +373,25 @@ Boolean PresentOpenConnectionDialog(void) case NChostname: if ( gApplicationPrefs->parseAliases ) { - // check if the string matches a favorite name typedHost = true; GetTEText(dptr, NChostname, scratchPstring); - scratchshort = FindMenuItemText(SessPopupHdl, scratchPstring); - if ( scratchshort && sessMark != scratchshort ) { - SetItemMark(SessPopupHdl, sessMark, 0); - sessMark = scratchshort; - SetItemMark(SessPopupHdl, sessMark, 18); - GetMenuItemText(SessPopupHdl, scratchshort, scratchPstring); - SetCurrentSession(dptr, scratchPstring); + if (memcmp(scratchPstring, hostString, scratchPstring[0] + 1)) { + // host name changed + autoTicks = LMGetTicks(); + startautocomplete = true; + pstrcpy(hostString, scratchPstring); + } + if ( !startautocomplete && doneautocomplete ) { + doneautocomplete = false; + // check if the string matches a favorite name + scratchshort = FindMenuItemText(SessPopupHdl, scratchPstring); + if ( scratchshort /*&& sessMark != scratchshort*/ ) { + SetItemMark(SessPopupHdl, sessMark, 0); + sessMark = scratchshort; + SetItemMark(SessPopupHdl, sessMark, 18); + GetMenuItemText(SessPopupHdl, scratchshort, scratchPstring); + SetCurrentSession(dptr, scratchPstring); + } } } break; @@ -599,6 +634,7 @@ Boolean CreateConnectionFromParams( ConnInitParams **Params) Boolean scratchBoolean; WindRec *theScreen; unsigned char *hostname; + unsigned long flags; setLastCursor(theCursors[watchcurs]); /* We may be here a bit */ @@ -806,17 +842,35 @@ Boolean CreateConnectionFromParams( ConnInitParams **Params) return(FALSE); } - GetFNum(TermPtr->DisplayFont, &fontnumber); GetFNum(TermPtr->BoldFont, &otherfnum); - - theScreen->vs = RSnewwindow(&((**Params).WindowLocation),TermPtr->numbkscroll, TermPtr->vtwidth, - TermPtr->vtheight, (**Params).WindowName, TermPtr->vtwrap, - fontnumber, TermPtr->fontsize, 0, - 1, SessPtr->forcesave,cur, TermPtr->allowBold, TermPtr->colorBold, - SessPtr->ignoreBeeps, otherfnum, TermPtr->boldFontSize, TermPtr->boldFontStyle, - TermPtr->realbold, TermPtr->oldScrollback, TermPtr->jumpScroll, - TermPtr->realBlink); + + flags = 0; + if (TermPtr->vtwrap) + flags |= RSWwrapon; + /*flags |= RSWshowit;*/ + flags |= RSWgoaway; + if (SessPtr->forcesave) + flags |= RSWforcesave; + if (TermPtr->allowBold) + flags |= RSWallowBold; + if (TermPtr->colorBold) + flags |= RSWcolorBold; + if (SessPtr->ignoreBeeps) + flags |= RSWignoreBeeps; + if (TermPtr->realbold) + flags |= RSWrealbold; + if (TermPtr->oldScrollback) + flags |= RSWsavelines; + if (TermPtr->jumpScroll) + flags |= RSWjumpscroll; + if (TermPtr->realBlink) + flags |= RSWrealBlink; + + theScreen->vs = RSnewwindow(&((**Params).WindowLocation), TermPtr->numbkscroll, TermPtr->vtwidth, + TermPtr->vtheight, (**Params).WindowName, fontnumber, + TermPtr->fontsize, cur, otherfnum, TermPtr->boldFontSize, + TermPtr->boldFontStyle, TermPtr->vtemulation, flags); if (theScreen->vs <0 ) { /* we have a problem opening up the virtual screen */ OutOfMemory(1011); @@ -876,16 +930,23 @@ Boolean CreateConnectionFromParams( ConnInitParams **Params) theScreen->termstate=VTEKTYPE; /* BYU */ theScreen->echo = 1; theScreen->halfdup = SessPtr->halfdup; /* BYU */ - - theScreen->national = 0; // Default to no translation. + + theScreen->innational = 0; // Default to no translation. + theScreen->outnational = 0; // Default to no translation. + theScreen->incharset = 0; + theScreen->outcharset = 0; + theScreen->toconverter = NULL; + theScreen->fromconverter = NULL; // Now see if the desired translation is available, if not use default translation. - for(scratchshort = 1; scratchshort <= nNational+1; scratchshort++) { + for (scratchshort = 1; scratchshort <= nNational+1; scratchshort++) { GetMenuItemText(myMenus[National], scratchshort, scratchPstring); - if (EqualString(SessPtr->TranslationTable, scratchPstring, TRUE, FALSE)) - theScreen->national = scratchshort-1; + if (EqualString(SessPtr->TranslationTable, scratchPstring, TRUE, FALSE)) { + theScreen->innational = theScreen->outnational = scratchshort - 1; + break; } - - + } + inittranslation(theScreen); + // Set up paste related variables theScreen->incount = 0; theScreen->outcount = 0; @@ -1263,7 +1324,9 @@ void destroyport(short wind) auth_encrypt_end((tnParams **)&tw->aedata); DisposePtr((Ptr)tw->aedata); } - + + disposetranslation(tw); + /* * Get handle to the WDEF patch block, kill the window, and then * release the handle. @@ -1325,9 +1388,9 @@ void removeport(WindRecPtr tw) DestroyTickets(); if (!gApplicationPrefs->WindowsDontGoAway) { - short vs = findbyVS(tw->vs); - if ( vs > -1 ) { - destroyport(vs); + short sn = findbyVS(tw->vs); + if ( sn >= 0 ) { + destroyport(sn); } } else { Str255 temp; diff --git a/macssh/source/main/event.c b/macssh/source/main/event.c index d110dad..00803f0 100755 --- a/macssh/source/main/event.c +++ b/macssh/source/main/event.c @@ -27,6 +27,7 @@ #include "VSkeys.h" #include "wind.h" +#include "translate.h" #include "event.h" //kxplate moved to its own file (CCP 2.7) #include "errors.proto.h" #include "network.proto.h" @@ -36,6 +37,7 @@ #include "InternalEvents.h" #include "vsdata.h" #include "vsinterf.proto.h" +#include "vsintern.proto.h" #include "menuseg.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" @@ -69,6 +71,9 @@ extern int gMovableModal; #include "event.proto.h" +extern void syslog( int priority, const char *format, ...); +extern long dumpln( long base, char *dest, void *src, long len ); + // BetterTelnet 2.0fc1 - integrated DJ's changes for real blink (if you want it :-) /* DJ: Blink global */ short gBlink = 0; @@ -330,33 +335,33 @@ Boolean CheckPageKeys(short code) /* NCSA: SB */ switch (code) /* NCSA: SB */ { /* NCSA: SB */ case VSPGUP: /* NCSA: SB */ - RScursblinkoff(ourW); + VScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- - RScursblinkon(ourW); + VScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ /* NCSA: SB */ case VSPGDN: // MAT--121 is a PAGE DOWN. - RScursblinkoff(ourW); // MAT--in rsmac.c + VScursblinkoff(ourW); // MAT--in rsmac.c VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- - RScursblinkon(ourW); + VScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ // MAT-- case VSHOME: /* NCSA: SB */ - RScursblinkoff(ourW); + VScursblinkoff(ourW); VSscroltop(ourW); /* JMB 2.6 -- Created VSscroltop just for this purpose */ - RScursblinkon(ourW); + VScursblinkon(ourW); return TRUE; /* NCSA: SB */ break; // MAT-- // MAT-- case VSEND: /* NCSA: SB */ - RScursblinkoff(ourW); + VScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */ // MAT-- kludge time again. anyone suggest - RScursblinkon(ourW); + VScursblinkon(ourW); return TRUE; /* NCSA: SB */ break; // MAT-- a better way to hack this part? } // MAT-- @@ -365,10 +370,13 @@ Boolean CheckPageKeys(short code) /* NCSA: SB */ } /* NCSA: SB */ -/* translatekey -- - returns ascii code for input code, using the input modifiers. */ +/* + * translatekeycode + * + * returns ascii code for input code, using the input modifiers. + */ -static unsigned char translatekey(unsigned char code, long modifiers) +static unsigned char translatekeycode(unsigned char code, long modifiers) { Ptr KCHRPtr; unsigned long state = 0; @@ -387,12 +395,17 @@ static unsigned char translatekey(unsigned char code, long modifiers) void HandleKeyDown(EventRecord theEvent,struct WindRec *tw) { - unsigned char ascii, code; - unsigned char sendch; - long menuEquiv; - short enterkey = 0; - Boolean commanddown, optiondown, controldown,shifted; - ObscureCursor(); + unsigned char ascii, code; + unsigned char sendch; + long menuEquiv; + short enterkey = 0; + Boolean commanddown, optiondown, controldown,shifted; + unsigned char trbuf[32]; + unsigned char *pbuf; + long inlen; + long trlen; + int res; + int i; ascii = theEvent.message & charCodeMask; code = ((theEvent.message & keyCodeMask) >> 8); @@ -404,59 +417,26 @@ void HandleKeyDown(EventRecord theEvent,struct WindRec *tw) if (DebugKeys(commanddown, ascii, tw->vs)) return; -/* NONO : looks like this attempt is more a bug than a fix, and - a goto is maybe not very clean, but in such a code anyway... + ObscureCursor(); -// RAB BetterTelnet 2.0b4 - ha ha, no hack hack -// fixed emacs metakey so it works for special keys -// (and got rid of the goto kludge while I was at it) - - if ((tw->emacsmeta == 2)&&(optiondown)) { - char temp = ESC; - - if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) - return; - - optiondown = 0; // pretend we didn't see option -// NONO : was wrong ! - //theEvent.modifiers &= (!optionKey);//since we have a valid ASCII anyway from the KCHR - theEvent.modifiers &= ~optionKey;//since we have a valid ASCII anyway from the KCHR -// NONO - // now we fix a couple of broken items in the emacs KCHR - if (code == 0x31) ascii = 32; // space fix - if ((code == 0x32) && !shifted) ascii = 0x60; // backquote fix - if ((code == 0x1B) && shifted) ascii = 0x5F; // underline fix - - if (tw->kblen > 0) - { - netwrite( tw->port,tw->kbbuf,tw->kblen); - tw->kblen=0; - } - - netpush(tw->port); - netwrite(tw->port, &temp, 1); // send an escape, and deal with the char itself below - } -// goto emacsHack; //ha ha hack hack -*/ if ( tw->emacsmeta == 2 && optiondown ) { - /* option key as emacs meta key: keep shift and control translation */ - ascii = translatekey( code, (theEvent.modifiers & (shiftKey|controlKey)) ); - goto emacsHack; //ha ha hack hack + // option key as emacs meta key: keep shift and control translation + ascii = translatekeycode( code, (theEvent.modifiers & (shiftKey|controlKey)) ); + goto emacsHack; } -/* NONO */ - if ((code == 0x34)&&(ascii == 3)) //fix for PowerBook 540 bad KCHR - ascii = 13; //(map control-c to return) - else if ((controldown)&&(shifted)&&(ascii == '2')) - ascii = 0;//fix bad KCHR control-@ - else if ((controldown)&&(shifted)&&(ascii == '6')) - ascii = 0x1e;//fix bad KCHR control-^ + if ( code == 0x34 && ascii == 3 ) // fix for PowerBook 540 bad KCHR + ascii = 13; // (map control-c to return) + else if ( controldown && shifted && ascii == '2' ) + ascii = 0; // fix bad KCHR control-@ + else if ( controldown && shifted && ascii == '6' ) + ascii = 0x1e; // fix bad KCHR control-^ - if (commanddown) { + if ( commanddown ) { if (gApplicationPrefs->CommandKeys) { //if optioned, retranslate so we can do menu commands if ( optiondown ) { - ascii = translatekey( code, (theEvent.modifiers & shiftKey) ); + ascii = translatekeycode( code, (theEvent.modifiers & shiftKey) ); } menuEquiv = MenuKey(ascii); //handle menu keys first if ( (menuEquiv & 0xFFFF0000) != 0 ) { @@ -467,36 +447,33 @@ void HandleKeyDown(EventRecord theEvent,struct WindRec *tw) return; // Check for EMACS meta key. if ( tw->emacsmeta && controldown ) { - unsigned char temp[2]; - if (ascii <= 32) //control changed the ascii value - ascii |= 0x40; //move back to a non-control + if ( ascii <= 32 ) { + // control changed the ascii value + ascii |= 0x40; // move back to a non-control + } if ( shifted || ascii == 0x5f ) { //so we can get meta - - ascii = translatekey( code, (theEvent.modifiers & shiftKey) ); + ascii = translatekeycode( code, (theEvent.modifiers & shiftKey) ); } emacsHack: + trbuf[0] = ESC; + trbuf[1] = ascii; if ( (tw->clientflags & PASTE_IN_PROGRESS) && tw->pastemethod ) { // queue this - tw->kbbuf[tw->kblen++] = ESC; - tw->kbbuf[tw->kblen++] = ascii; - return; + kbwrite( tw, trbuf, 2); } - if (tw->kblen > 0) { - netwrite( tw->port,tw->kbbuf,tw->kblen); - tw->kblen=0; - } - temp[0] = ESC; - temp[1] = ascii; - if (tw->echo && tw->halfdup) - parse(tw,temp,2); - netpush(tw->port); + kbflush( tw ); + if ( tw->echo && tw->halfdup ) + parse( tw, trbuf, 2 ); + netpush( tw->port ); // netwrite(tw->port,temp,2); - netwrite(tw->port,temp,1); // RAB BetterTelnet 2.0b4 + // ascii is sent below + netwrite( tw->port, trbuf, 1 ); // RAB BetterTelnet 2.0b4 controldown = 0; // return; RAB BetterTelnet 2.0b4 - deal with key below - } else if ( ascii >= '0' && ascii <='9' ) { + } else if ( ascii >= '0' && ascii <= '9' ) { // now look for macros - sendmacro(tw, ascii - '0' + (shifted) ? 10 : 0); + sendmacro(tw, ascii - '0' + ((shifted) ? 10 : 0)); return; } else if (!((ascii == '`' && gApplicationPrefs->RemapTilde) || code == BScode )) { // remap cmd-pgup/down @@ -531,7 +508,7 @@ emacsHack: ascii = NULL; //a @, takes care of Apple not posting NULL key values // map '`' to ESC if needed - if (ascii == '`' && gApplicationPrefs->RemapTilde && !(commanddown)) + if (ascii == '`' && gApplicationPrefs->RemapTilde && !commanddown) ascii = ESC; // map Del to ^D if the user wants it @@ -540,38 +517,38 @@ emacsHack: ascii = 4; } - if (code == BScode) //handle mapping BS to DEL, flipping on option - { - if (tw->bsdel) - if ((optiondown && tw->emacsmeta != 2)||(commanddown)) + if ( code == BScode ) { + // handle mapping BS to DEL, flipping on option + if ( tw->bsdel ) { + if ( (optiondown && tw->emacsmeta != 2) || commanddown ) ascii = BS; else ascii = DEL; - else - if ((optiondown && tw->emacsmeta != 2)||(commanddown)) + } else { + if ( (optiondown && tw->emacsmeta != 2) || commanddown ) ascii = DEL; else ascii = BS; + } } - if (!tw->enabled) //if we are suspended, and we have negotiated restart_any - { //with the host, then enable the screen on anything but an XOFF. We will - //eat the XON later if that is what this is. (RFC 1372 --CCP 2.7) - if ((tw->restart_any_flow)&&(ascii != tw->TELstop)) { - tw->enabled = 1; - changeport(scrn, scrn); - } + if ( !tw->enabled && tw->restart_any_flow && ascii != tw->TELstop ) { + // if we are suspended, and we have negotiated restart_any + // with the host, then enable the screen on anything but an XOFF. We will + // eat the XON later if that is what this is. (RFC 1372 --CCP 2.7) + tw->enabled = 1; + changeport(scrn, scrn); } /* Remap PgUp,PgDown,Home,End if the user wants it that way */ // RAB BetterTelnet 2.0b3 - we don't check to see if we're using vt220 - if (tw->pgupdwn && (code >= KPlowest)) //do page up/down on vt100 - if (CheckPageKeys(code)) return; + if (tw->pgupdwn && code >= KPlowest) // do page up/down on vt100 + if ( CheckPageKeys(code) ) + return; - if (code >= KPlowest) /* BYU - Handle Keypad */ - { + if ( code >= KPlowest ) { /* - if (theWorld.keyBoardType == envStandADBKbd) //standard MacII keyboard has keypad +,- + if (theWorld.keyBoardType == envStandADBKbd) // standard MacII keyboard has keypad +,- { // codes switched if (code == 0x45) code = 0x4e; @@ -579,162 +556,174 @@ emacsHack: code = 0x45; } */ - // RAB BetterTelnet 2.0b3 - who cares if we're using VT220? - // RAB BetterTelnet 2.0b4 - fix for the fix -// if ((code >= 0x7B)||(code <= 0x60)) //fkeys dont work in vt100 - if (1) - { - if ((!tw->keypadmap)||(code == 0x4c)||(code > 0x51)||(code < 0x43)) //dont remap operators - { - if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this - { - tw->kbbuf[tw->kblen++] = 0; - tw->kbbuf[tw->kblen++] = kpxlate[shifted][code - KPlowest]; - return; - } - - if (tw->kblen > 0) - { - netwrite( tw->port,tw->kbbuf,tw->kblen); - tw->kblen=0; - } - - ascii = kpxlate[shifted][code - KPlowest]; - // Should we check here for ascii being zero? - VSkbsend(tw->vs, (unsigned char) ascii, tw->echo, shifted); + if ( !tw->keypadmap || code == 0x4c || code > 0x51 || code < 0x43 ) { + // dont remap operators + if ( (tw->clientflags & PASTE_IN_PROGRESS) && tw->pastemethod ) { + // queue this + trbuf[0] = 0; + trbuf[1] = kpxlate[shifted][code - KPlowest]; + kbwrite( tw, trbuf, 2); return; } - } - else // we dont handle function keys in vt100 + + kbflush( tw ); + ascii = kpxlate[shifted][code - KPlowest]; + // Should we check here for ascii being zero? + VSkbsend(tw->vs, (unsigned char) ascii, tw->echo, shifted); return; + } } // Handle whatever mapping is needed. - mac_nat(&ascii, tw->national); /* LU/PM: Convert char from mac to nat */ - - if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this - { - tw->kbbuf[tw->kblen++] = ascii; +// mac_nat(tw, &ascii); // LU/PM: Convert char from mac to nat + if ( GetTranslationIndex(tw->outnational) != kTRJIS ) { + if (tw->troutcount >= sizeof(tw->troutbuf)) { + // !!!! shouldn't occur... + Debugger(); + tw->troutcount = 0; + } + pbuf = tw->troutbuf; + pbuf[tw->troutcount++] = ascii; + + if ( tw->troutcount < sizeof(tw->troutbuf) - 1 ) { + EventRecord nextEvent; + if ( EventAvail(keyDownMask|autoKeyMask, &nextEvent) ) { + /* wait for next char */ + return; + } + } + + inlen = tw->troutcount; + trlen = sizeof(trbuf); + res = trbuf_mac_nat( tw, pbuf, &inlen, trbuf, &trlen ); + if ( res && res != kTECPartialCharErr ) { + // translation failed, leave data as-is + trlen = tw->troutcount; + } else { + // translation ok, or no data yet + if ( inlen ) { + // keep a few chars + for (i = inlen; i <= tw->troutcount; i++) { + pbuf[i - inlen] = pbuf[i]; + } + tw->troutcount -= inlen; + } + if ( !trlen ) { + // nothing yet + if ( tw->troutcount < sizeof(tw->troutbuf) ) { + return; + } + // temp translation buffer full, unable to translate... + // flush data ? + trlen = tw->troutcount; + res = trflush_mac_nat( tw ); + } else { + // translation complete + pbuf = trbuf; + } + } + tw->troutcount = 0; + } else { + // send as-is ? + if ( !tw->troutcount && !(ascii & 0x80) ) { + pbuf = &ascii; + trlen = 1; + } else { + pbuf = tw->troutbuf; + pbuf[tw->troutcount++] = ascii; + if ( tw->troutcount == 1 ) + // wait for second byte + return; + trlen = tw->troutcount; + tw->troutcount = 0; + } + } + + if ( (tw->clientflags & PASTE_IN_PROGRESS) && tw->pastemethod ) { + // queue this + kbwrite( tw, pbuf, trlen); + return; + } else if ( tw->lmode ) { + for (res = 0; res < trlen; ++res) { + // Some form of linemode is active; we dont touch it after them + process_key( pbuf[res], tw ); + } return; } - if (tw->lmode) // Some form of linemode is active; we dont touch it after them - { - process_key(ascii,tw); - return; - } - // BSD-like mapping.... if we don't want this, set chars to zero and it wont work //CCP 2.7: this is now AFTER the linemode stuff, so that linemode can handle it differently - if (ascii == tw->TELstop) - { - if (tw->allow_flow) //remote flow control can turn this off - { + if ( ascii == tw->TELstop ) { + if ( tw->allow_flow ) { + // remote flow control can turn this off tw->enabled = 0; - changeport(scrn,scrn); + changeport( scrn, scrn ); return; } - } - - if (ascii == tw->TELgo) - { - if (tw->allow_flow) //remote flow control can turn this off - { + } else if ( ascii == tw->TELgo ) { + if ( tw->allow_flow ) { + // remote flow control can turn this off tw->enabled = 1; - changeport(scrn, scrn); + changeport( scrn, scrn ); return; } - } - if (ascii == tw->TELip) - { + } else if ( ascii == tw->TELip ) { char *tellUser = "\n\r[Interrupt Process]\n\r"; - parse(tw,(unsigned char *)tellUser,23); - netpush(tw->port); - netwrite(tw->port, "\377\364",2); //IAC IP - netpush(tw->port); - netwrite(tw->port, "\377\375\006",3); // send Do TM - tw->timing = 1; // set emulate to TMwait + parse( tw, (unsigned char *)tellUser, 23 ); + netpush( tw->port ); + netwrite( tw->port, "\377\364", 2 ); //IAC IP + netpush( tw->port ); + netwrite( tw->port, "\377\375\006" ,3 ); // send Do TM + tw->timing = 1; // set emulate to TMwait return; } - - if (tw->echo && !tw->halfdup) // Handle klude-linemode - { - if (ascii>31 && ascii <127 && code < KPlowest) - { - if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ - tw->kbbuf[tw->kblen++] = ascii; - else - { /* if full send buffer */ - netwrite( tw->port, tw->kbbuf,tw->kblen); - tw->kbbuf[0] = ascii; - tw->kblen=1; + if ( tw->echo && !tw->halfdup ) { + // Handle klude-linemode + if ( ascii > 31 && ascii < 127 && code < KPlowest ) { + // printable key + kbwrite( tw, pbuf, trlen); + parse(tw, pbuf, trlen); + return; // OK, were set... + } else if ( code == BScode ) { + if ( tw->kblen > 0 ) { + --tw->kblen; + parse( tw, (unsigned char *)"\010 \010", 3 ); } + return; + } else if ( ascii == KILLCHAR ) { + while ( tw->kblen > 0 ) { + parse( tw, (unsigned char *)"\010 \010", 3 ); + --tw->kblen; + } + return; + } else if ( code < KPlowest ) { + // if full send buffer + kbflush( tw ); + if ( ascii != CR ) { + sendch = '@' + ascii; + parse( tw, (unsigned char *)"^", 1 ); + parse( tw, &sendch, 1 ); + } + } + } //end if klude-linemode - sendch=ascii; - parse(tw, &sendch, 1); - return; /* OK, were set...*/ - - } //end if printable key - else - { - if ( code == BScode ) - { - if (tw->kblen>0) - { - tw->kblen--; - parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ - } - return; - } - else if (ascii == KILLCHAR) - { - while (tw->kblen >0) - { - parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ - tw->kblen--; - } - return; - } - else if (code port, tw->kbbuf,tw->kblen); /* if full send buffer */ - tw->kblen=0; - if (ascii !=CR) - { - sendch='@'+ascii; - parse(tw,(unsigned char *) "^",1); /* BYU LSC */ - parse(tw, &sendch, 1); - } - } - }//end else non-printable key - }//end if klude-linemode - - - if (ascii == '\015') //CR - { - // If crmap is on, send CR-NULL instead of CR-LF. + if (ascii == '\015') { + // CR. If crmap is on, send CR-NULL instead of CR-LF. SendCRAsIfTyped(tw); return; -/* netpush(tw->port); - if (tw->crmap) - netwrite(tw->port,"\015\0",2); - else - netwrite(tw->port,"\015\012",2); //UNIVAC fix - if (tw->echo) - parse(tw,(unsigned char *) "\012\015",2); // BYU LSC - return; */ } if (tw->echo && tw->halfdup) - parse(tw, &ascii, 1); - - if (ascii != 255) - netwrite(tw->port,&ascii,1); - else - netwrite(tw->port, "\377\377", 2); - + parse( tw, pbuf, trlen ); + + if ( ascii != 255 ) { + netwrite( tw->port, pbuf, trlen ); + } else { + netwrite( tw->port, "\377\377", 2 ); + } + } void HandleMouseDown(EventRecord myEvent) @@ -744,11 +733,14 @@ void HandleMouseDown(EventRecord myEvent) short growErr, i; short theItem; DialogPtr dlogp; + short vs; code = FindWindow(myEvent.where, &whichWindow); switch (code) { case inMenuBar: + if ( gApplicationPrefs->BlinkCursor && (vs = RSfindvwind(FrontWindow())) >= 0 ) + VScursblinkoff(vs); if (myEvent.modifiers & optionKey) { switchToOptionMenus(TRUE); @@ -763,6 +755,8 @@ void HandleMouseDown(EventRecord myEvent) } else HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); + if ( gApplicationPrefs->BlinkCursor && (vs = RSfindvwind(FrontWindow())) >= 0 ) + VScursblinkon(vs); break; case inSysWindow: SystemClick(&myEvent, whichWindow); @@ -866,24 +860,20 @@ void DoEvents( EventRecord* theEvent) if (gotOne) { /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */ - if (gApplicationPrefs->BlinkCursor) - { - if ( (vs=RSfindvwind(FrontWindow())) >= 0) - if (vs == screens[scrn].vs) - if (!(myEvent.modifiers & cmdKey) && - ((myEvent.what == keyDown) || (myEvent.what == autoKey))) - RScursblinkon(vs); - else - RScursblinkoff(vs); + if ( gApplicationPrefs->BlinkCursor ) { + if ( (vs = RSfindvwind(FrontWindow())) >= 0 && vs == screens[scrn].vs ) { + if (!(myEvent.modifiers & cmdKey) && + (myEvent.what == keyDown || myEvent.what == autoKey)) + VScursblinkon(vs); + else + VScursblinkoff(vs); + } } HandleEvent(theEvent); + } else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) { + if ( (vs = RSfindvwind(FrontWindow())) >= 0 && vs == screens[scrn].vs ) + VScursblink(vs); } - else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) - { /* BYU 2.4.11 */ - if ( (vs=RSfindvwind(FrontWindow())) >= 0) /* BYU 2.4.11 */ - if (vs == screens[scrn].vs) /* BYU 2.4.11 */ - RScursblink(vs); /* BYU 2.4.11 */ - } /* BYU 2.4.11 */ if (FrontWindow() != TelInfo->macrosModeless) // RAB BetterTelnet 1.2 updateCursor(0); @@ -1149,9 +1139,6 @@ void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can DisposePtr(nRecPtr); gHaveInstalledNotification = FALSE; } -// DisableItem( myMenus[Edit],EDcut); -// DisableItem( myMenus[Edit],EDundo); -// DisableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ( (vs=RSfindvwind(window)) >= 0) @@ -1185,9 +1172,6 @@ void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can KeyScript(smRoman); } TelInfo->suspended=TRUE; /* We be in waitin' */ -// EnableItem( myMenus[Edit],EDcut); -// EnableItem( myMenus[Edit],EDundo); -// EnableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ((window = FrontWindow()) != nil) { diff --git a/macssh/source/main/mainseg.c b/macssh/source/main/mainseg.c index a843fb1..0e218d0 100755 --- a/macssh/source/main/mainseg.c +++ b/macssh/source/main/mainseg.c @@ -120,7 +120,7 @@ void main(void) if (!TelInfo->done) { DoNetEvents(); } - ssh2_sched(); + //ssh2_sched(); memOK = RecoverReserveMemory(); if (memOK) diff --git a/macssh/source/main/menuseg.c b/macssh/source/main/menuseg.c index dbef08a..006f5c0 100755 --- a/macssh/source/main/menuseg.c +++ b/macssh/source/main/menuseg.c @@ -21,6 +21,7 @@ #include "wind.h" +#include "translate.h" #include "menuseg.proto.h" #include "mainseg.proto.h" #include "Sets.proto.h" /* JMB: For Saved Sets functions */ @@ -77,6 +78,7 @@ extern WindRec *screens, /* The screen array from Maclook */ *ftplog; /* The FTP log screen from Maclook */ extern short nNational; +extern short gTableCount; void CloseCaptureFile(short w) { @@ -866,38 +868,30 @@ void paste( void) long off, /* offset */ length; /* the lenght of what is on the Scrap */ + WindRec *tw = &screens[scrn]; - if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please + if (tw->clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; - } - - /* Flush the buffer if necessary */ //CCP fix for linemode - if (screens[scrn].kblen>0) - { - netpush(screens[scrn].port); - netwrite( screens[scrn].port, screens[scrn].kbbuf, - screens[scrn].kblen); - screens[scrn].kblen=0; } if (GetScrap(0L, 'TEXT', &off)<=0L) /* If there are no TEXT res's */ - return; /* then we can't paste it */ + return; /* then we can't paste it */ - screens[scrn].outhand=myNewHandle(0L); /* create a handle to put chars in */ + /* Flush the buffer if necessary */ //CCP fix for linemode + kbflush(tw); - length= GetScrap( screens[scrn].outhand, 'TEXT',&off); - /* Store the scrap into the handle */ - screens[scrn].outlen = length; /* Set the length */ - HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ - screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ - - screens[scrn].clientflags |= PASTE_IN_PROGRESS; - screens[scrn].isUploading = 0; - screens[scrn].incount = 0; - screens[scrn].outcount = 0; - - trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ + tw->outhand = myNewHandle(0L); /* create a handle to put chars in */ + length = GetScrap(tw->outhand, 'TEXT', &off); + if ( GetTranslationIndex(tw->outnational) != kTRJIS ) + tw->outhand = htrbuf_mac_nat(tw, tw->outhand); + HLock(tw->outhand); + tw->outptr = *tw->outhand; + tw->outlen = GetHandleSize(tw->outhand); + tw->clientflags |= PASTE_IN_PROGRESS; + tw->isUploading = 0; + tw->incount = 0; + tw->outcount = 0; pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } @@ -908,8 +902,9 @@ void uploadFile(void) // RAB: routine added in BetterTelnet 1.0fc9 StandardFileReply sfr; OSErr err; short refNum; + WindRec *tw = &screens[scrn]; - if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please + if (tw->clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } @@ -921,86 +916,64 @@ void uploadFile(void) // RAB: routine added in BetterTelnet 1.0fc9 if (err) return; /* Flush the buffer if necessary */ //CCP fix for linemode - if (screens[scrn].kblen>0) - { - netpush(screens[scrn].port); - netwrite( screens[scrn].port, screens[scrn].kbbuf, - screens[scrn].kblen); - screens[scrn].kblen=0; - } - - screens[scrn].outhand=myNewHandle(16384); // for now, upload block is 16K - screens[scrn].outptr = *screens[scrn].outhand; - HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ - - length = 16384; - FSRead(refNum, &length, screens[scrn].outptr); + kbflush(tw); + length = 16384; // for now, upload block is 16K + tw->outhand = myNewHandle(length); + HLock( tw->outhand ); + FSRead(refNum, &length, *tw->outhand); if (length == 0) { FSClose(refNum); - HUnlock(screens[scrn].outhand); - DisposeHandle(screens[scrn].outhand); + HUnlock(tw->outhand); + DisposeHandle(tw->outhand); return; } - - screens[scrn].outlen = length; /* Set the length */ - HUnlock(screens[scrn].outhand); - SetHandleSize(screens[scrn].outhand, length); // now REALLY set the length - HLock(screens[scrn].outhand); - - screens[scrn].clientflags |= PASTE_IN_PROGRESS; + SetHandleSize(tw->outhand, length); // now REALLY set the length + if ( GetTranslationIndex(tw->outnational) != kTRJIS ) + tw->outhand = htrbuf_mac_nat(tw, tw->outhand); + HLock(tw->outhand); + tw->outptr = *tw->outhand; + tw->outlen = GetHandleSize(tw->outhand); + tw->clientflags |= PASTE_IN_PROGRESS; if (length == 16384) { - screens[scrn].isUploading = 1; - screens[scrn].uploadRefNum = refNum; + tw->isUploading = 1; + tw->uploadRefNum = refNum; } else { FSClose(refNum); - screens[scrn].isUploading = 0; } - screens[scrn].incount = 0; - screens[scrn].outcount = 0; - - trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ - + tw->incount = 0; + tw->outcount = 0; pasteText(scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ - } + void autoPaste(short vs) // RAB: routine added in BetterTelnet 1.0fc6 { char **charh; + WindRec *tw = &screens[scrn]; - if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please + if (tw->clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } /* Flush the buffer if necessary */ //CCP fix for linemode - if (screens[scrn].kblen>0) - { - netpush(screens[scrn].port); - netwrite( screens[scrn].port, screens[scrn].kbbuf, - screens[scrn].kblen); - screens[scrn].kblen=0; - } + kbflush(tw); - charh=RSGetTextSel(vs,0); /* Get the text selection */ + charh = RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ - HLock(charh); - screens[scrn].outhand=charh; - - screens[scrn].outlen = GetHandleSize(charh); /* Set the length */ - screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ - - screens[scrn].clientflags |= PASTE_IN_PROGRESS; - screens[scrn].isUploading = 0; - screens[scrn].incount = 0; - screens[scrn].outcount = 0; - - trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ - + if ( GetTranslationIndex(tw->outnational) != kTRJIS ) + tw->outhand = htrbuf_mac_nat(tw, charh); + HLock(tw->outhand); + tw->outptr = *tw->outhand; + tw->outlen = GetHandleSize(tw->outhand); + tw->clientflags |= PASTE_IN_PROGRESS; + tw->isUploading = 0; + tw->incount = 0; + tw->outcount = 0; pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } } @@ -1087,7 +1060,10 @@ void changeport(short oldprt, short newprt) CheckFonts(); - CheckNational(screens[newprt].national); + if ( screens[newprt].outnational < 0 ) + CheckNational( gTableCount - screens[newprt].outnational ); + else + CheckNational( screens[newprt].outnational ); } // Returns TRUE if the user cancelled the quit @@ -1423,12 +1399,10 @@ void HandleMenuCommand( long mResult, short modifiers) case EMecho: /* Toggle Local Echo (if poss.) */ if (TelInfo->numwindows < 1) break; - if ( screens[scrn].echo && screens[scrn].kblen > 0 ) { - netwrite( screens[scrn].port, screens[scrn].kbbuf, - screens[scrn].kblen); /* if not empty send buffer */ - screens[scrn].kblen = 0; + if ( screens[scrn].echo ) { + kbflush(&screens[scrn]); } - screens[scrn].echo= !screens[scrn].echo; /* toggle */ + screens[scrn].echo = !screens[scrn].echo; /* toggle */ if (screens[scrn].echo) { /* LOCAL ECHO */ if (!(modifiers & optionKey) && (screens[scrn].protocol == 0)) send_dont(screens[scrn].port,1); @@ -1584,11 +1558,9 @@ void HandleMenuCommand( long mResult, short modifiers) { char tmpout[30]; /* Basically the same except for */ unsigned char tmp[4]; /* The ftp -n phrase in NEftp */ - if (screens[scrn].echo && (screens[scrn].kblen>0)) { - netwrite( screens[scrn].port, screens[scrn].kbbuf, - screens[scrn].kblen);/* if not empty send buffer */ - screens[scrn].kblen=0; - } + if ( screens[scrn].echo ) { + kbflush(&screens[scrn]); + } netgetip(tmp); if (theItem == NEftp) { if ((gFTPServerPrefs->ServerState == 1) && !(modifiers & shiftKey)) @@ -1848,10 +1820,12 @@ void HandleMenuCommand( long mResult, short modifiers) case transMenu: if (TelInfo->numwindows>0) { CheckNational(theItem-1); // Set up the menu - transBuffer(screens[scrn].national, theItem-1); // Translate the scrollback buffer + //transBuffer(screens[scrn].outnational, theItem-1); // Translate the scrollback buffer + switchintranslation(&screens[scrn], theItem-1, 0); + switchouttranslation(&screens[scrn], theItem-1, 0); // and redraw the screen VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); /* LU */ - screens[scrn].national = theItem-1; + screens[scrn].outnational = theItem-1; } break; case keyMenu: diff --git a/macssh/source/network/netevent.c b/macssh/source/network/netevent.c index 6b329cc..8a6cee2 100755 --- a/macssh/source/network/netevent.c +++ b/macssh/source/network/netevent.c @@ -34,6 +34,7 @@ #include "rsinterf.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" +#include "translate.h" #include "vsdata.h" #include "vskeys.h" #include "translate.proto.h" @@ -227,85 +228,81 @@ void pasteText(short scrn) { short amount; long uploadLength; + WindRec *tw = &screens[scrn]; - if (!screens[scrn].outlen) + if (!tw->outlen) return; - if (netpush(screens[scrn].port) != 0) { /* BYU 2.4.16 - wait until not busy */ + if (netpush(tw->port) != 0) { /* BYU 2.4.16 - wait until not busy */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ - if (screens[scrn].incount) { /* BYU 2.4.16 */ - screens[scrn].incount = 0; /* BYU 2.4.16 */ - screens[scrn].outcount = 0; /* BYU 2.4.16 */ + if (tw->incount) { /* BYU 2.4.16 */ + tw->incount = 0; /* BYU 2.4.16 */ + tw->outcount = 0; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ - if (screens[scrn].outcount < 2) { /* BYU 2.4.16 */ - screens[scrn].outcount++; /* BYU 2.4.16 */ + if (tw->outcount < 2) { /* BYU 2.4.16 */ + tw->outcount++; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } - if (netqlen(screens[scrn].port) > 0) { /* BYU 2.4.16 - wait until not full */ + if (netqlen(tw->port) > 0) { /* BYU 2.4.16 - wait until not full */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ - if (!screens[scrn].pastemethod) { // Do this all at once? - amount = netwrite(screens[scrn].port, screens[scrn].outptr, - screens[scrn].outlen); + if (!tw->pastemethod) { // Do this all at once? + amount = netwrite(tw->port, tw->outptr, + tw->outlen); } else { // Nope, do it in blocks - if (screens[scrn].pastesize <= screens[scrn].outlen) - amount = screens[scrn].pastesize; + if (tw->pastesize <= tw->outlen) + amount = tw->pastesize; else - amount = screens[scrn].outlen; - amount = netwrite(screens[scrn].port, screens[scrn].outptr, amount); + amount = tw->outlen; + amount = netwrite(tw->port, tw->outptr, amount); } - if (screens[scrn].echo) - parse( &screens[scrn],(unsigned char *) screens[scrn].outptr,amount); + if (tw->echo) + parse( tw,(unsigned char *) tw->outptr,amount); - screens[scrn].outlen -= amount; - screens[scrn].outptr += (long) amount; - - if ((screens[scrn].isUploading) && (screens[scrn].outlen <= 0)) { - HLock(screens[scrn].outhand); // Lock the Handle down for safety - screens[scrn].outptr = *screens[scrn].outhand; + tw->outlen -= amount; + tw->outptr += (long) amount; + if ( tw->isUploading && tw->outlen <= 0 ) { uploadLength = 16384; - FSRead(screens[scrn].uploadRefNum, &uploadLength, screens[scrn].outptr); - - if (uploadLength > 0) { - - screens[scrn].outlen = uploadLength; // Set the length - HUnlock(screens[scrn].outhand); - SetHandleSize(screens[scrn].outhand, uploadLength); // now REALLY set the length - HLock(screens[scrn].outhand); - - screens[scrn].clientflags |= PASTE_IN_PROGRESS; - if (uploadLength == 16384) { - screens[scrn].isUploading = 1; - } else { - FSClose(screens[scrn].uploadRefNum); - screens[scrn].isUploading = 0; + HUnlock( tw->outhand ); + SetHandleSize(tw->outhand, uploadLength); + HLock( tw->outhand ); + FSRead(tw->uploadRefNum, &uploadLength, *tw->outhand); + if ( uploadLength > 0 ) { + SetHandleSize(tw->outhand, uploadLength); + if ( GetTranslationIndex(tw->outnational) != kTRJIS ) + tw->outhand = htrbuf_mac_nat(tw, tw->outhand); + HLock(tw->outhand); + tw->outptr = *tw->outhand; + tw->outlen = GetHandleSize(tw->outhand); + tw->clientflags |= PASTE_IN_PROGRESS; + if (uploadLength != 16384) { + tw->isUploading = 0; + FSClose(tw->uploadRefNum); } - screens[scrn].incount = 0; - screens[scrn].outcount = 0; - - trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); // LU: translate to national chars + tw->incount = 0; + tw->outcount = 0; + //pasteText(scrn); netputevent(USERCLASS, PASTELEFT, scrn, 0); return; } } - if ( screens[scrn].outlen <=0) { + if ( tw->outlen <= 0) { int left; - WindRec *tw = &screens[scrn]; tw->clientflags &= ~PASTE_IN_PROGRESS; - if (screens[scrn].isUploading) - FSClose(screens[scrn].uploadRefNum); + if (tw->isUploading) + FSClose(tw->uploadRefNum); HUnlock(tw->outhand); DisposeHandle(tw->outhand); tw->outptr = (char *) 0L; diff --git a/macssh/source/parse/parse.c b/macssh/source/parse/parse.c index 833c75b..2f1575a 100755 --- a/macssh/source/parse/parse.c +++ b/macssh/source/parse/parse.c @@ -10,6 +10,7 @@ #include "parse.h" // For our #defines #include "wind.h" /* For WindRec structure */ +#include "translate.h" /* For putln proto */ #include "ae.proto.h" @@ -42,6 +43,8 @@ static char munger[255]; /*#include */ +extern void syslog( int priority, const char *format, ...); + extern short scrn; extern WindRec *screens; @@ -63,22 +66,102 @@ static void telnet_wont(struct WindRec *tw, short option); void Parseunload(void) {} +/* + * kbflush + */ +void kbflush(struct WindRec *tw) +{ + if ( tw->kblen ) { + netwrite( tw->port, tw->kbbuf, tw->kblen); + tw->kblen = 0; + } +} + +/* + * kbwrite + */ +void kbwrite(struct WindRec *tw, unsigned char *string, short len) +{ + int i; + + for (i = 0; i < len; i++) { + if ( tw->kblen == MAXKB ) { + kbflush(tw); + } + tw->kbbuf[tw->kblen++] = string[i]; + } +} + void SendStringAsIfTyped(struct WindRec *tw, char *string, short len) { -// trbuf_nat_mac((unsigned char *)string, len, tw->national); - trbuf_mac_nat((unsigned char *)string, len, tw->national); // drh - bug fix + unsigned char outbuf[256]; + unsigned char trbuf[32]; + unsigned char *pbuf; + long inlen; + long outlen; + long buflen; + long trlen; + int i; + int j; + int res; - netpush(tw->port); + trflush_mac_nat(tw); - if (tw->kblen > 0) { /* need to flush buffer */ - netwrite(tw->port, tw->kbbuf, tw->kblen); - tw->kblen=0; + while (len) { + buflen = len > sizeof(outbuf) ? sizeof(outbuf) : len; + for ( i = 0, outlen = 0; i < buflen && outlen < sizeof(outbuf); ++i ) { + if ( /*string[i] != ESC &&*/ GetTranslationIndex(tw->outnational) != kTRJIS ) { + pbuf = tw->troutbuf; + if ( tw->troutcount >= sizeof(tw->troutbuf) ) { + // !!!! shouldn't occur... + Debugger(); + tw->troutcount = 0; + } + pbuf[tw->troutcount++] = string[i]; + inlen = tw->troutcount; + trlen = sizeof(trbuf); + res = trbuf_mac_nat( tw, pbuf, &inlen, trbuf, &trlen ); + if ( res && res != kTECPartialCharErr ) { + // translation failed, leave data as-is + trlen = tw->troutcount; + } else { + // translation ok, or no data yet + if ( inlen ) { + // keep a few chars + for (j = inlen; j <= tw->troutcount; j++) + pbuf[j - inlen] = pbuf[j]; + tw->troutcount -= inlen; + } + if ( !trlen ) { + // nothing yet + if ( tw->troutcount < sizeof(tw->troutbuf) ) + continue; + // temp translation buffer full, unable to translate... + // flush data ? + trlen = tw->troutcount; + res = trflush_mac_nat( tw ); + } else { + // translation complete + pbuf = trbuf; + } + } + tw->troutcount = 0; + for ( j = 0; j < trlen; ++j ) + outbuf[outlen++] = pbuf[j]; + } else { + outbuf[outlen++] = string[i]; + } + } + netpush(tw->port); + kbflush( tw ); + netwrite(tw->port, outbuf, outlen); + if (tw->echo) + parse(tw, (unsigned char *)outbuf, outlen); + len -= buflen; + string += buflen; } - netwrite(tw->port, string, len); - - if (tw->echo) - parse(tw, (unsigned char *)string, len); + tw->troutcount = 0; } // RAB BetterTelnet 2.0b3 @@ -544,15 +627,17 @@ void telnet_send_initial_options(WindRec *tw) if ((tw->protocol >= 1) && (tw->protocol <= 3)) { // initial rlogin stuff netwrite(tw->port, "\000", 1); if ((tw->protocol == 3) || (!tw->clientuser[0])) - // rexec sends username, rlogin/rsh need client username - // but we use server username if we don't have a client - // username... + // rexec sends username, rlogin/rsh need client username + // but we use server username if we don't have a client + // username... netwrite(tw->port, &tw->username[1], tw->username[0]); - else netwrite(tw->port, &tw->clientuser[1], tw->clientuser[0]); + else + netwrite(tw->port, &tw->clientuser[1], tw->clientuser[0]); netwrite(tw->port, "\000", 1); if (tw->protocol == 3) // rexec sends password, rlogin/rsh send server username netwrite(tw->port, &tw->password[1], tw->password[0]); - else netwrite (tw->port, &tw->username[1], tw->username[0]); + else + netwrite (tw->port, &tw->username[1], tw->username[0]); netwrite(tw->port, "\000", 1); if (tw->protocol == 1) { // rlogin sends terminal type & speed, rsh/rexec send command netwrite(tw->port, &tw->answerback[1], tw->answerback[0]); @@ -843,11 +928,7 @@ static void telnet_dont(struct WindRec *tw, short option) if (tw->lmode) { send_wont(tw->port, N_LINEMODE); - if (tw->kblen > 0) - { - netpush(tw->port); - netwrite(tw->port, tw->kbbuf, tw->kblen); - } + kbflush( tw ); tw->lmode = 0; tw->lmodeBits = 0; tw->litNext = 0; diff --git a/macssh/source/parse/parse.proto.h b/macssh/source/parse/parse.proto.h index 06e206b..304aa7c 100755 --- a/macssh/source/parse/parse.proto.h +++ b/macssh/source/parse/parse.proto.h @@ -1,5 +1,8 @@ /* parse.c */ + +void kbflush(struct WindRec *tw); +void kbwrite(struct WindRec *tw, unsigned char *string, short len); void SendStringAsIfTyped(struct WindRec *tw, char *string, short len); void SendCRAsIfTyped(struct WindRec *tw); void Parseunload(void); diff --git a/macssh/source/parse/translate.c b/macssh/source/parse/translate.c index d431a5b..07ddede 100755 --- a/macssh/source/parse/translate.c +++ b/macssh/source/parse/translate.c @@ -21,17 +21,30 @@ #include "wind.h" #include "vsdata.h" +#include "translate.h" #include "translate.proto.h" #include "vsinterf.proto.h" #include "LinkedList.proto.h" +#include "TextCommon.h" +#include "TextEncodingConverter.h" + +extern void syslog( int priority, const char *format, ...); +extern long dumpln( long base, char *dest, void *src, long len ); + +void VSprintf(char *fmt, ...); +void VSdump(char *p, int len); + +static void trTECInit(); + //#define DEBUG_TRANSLATION /*************** external variables ***************/ - extern WindRec *screens; /* The screen array from maclook.c */ extern short scrn; /* The current screen from maclook.c */ +extern int gVSemlogging; + /*************** global variables ***************/ BytePtr DefaultTable, @@ -39,34 +52,9 @@ BytePtr DefaultTable, FTPoutTable; Handle transTablesHdl; -short nNational; +short nNational = 0; +short gTableCount; -#if 0 -Boolean get_trsl (short id, Byte **table) -{ - Handle h; - long size; - - h = GetResource (TRSL,id); - - if ((h==NULL) || (ResError()!=noErr)) - { - DoError(106 | RESOURCE_ERRORCLASS, LEVEL2, NULL); - return (FALSE); - } - - size = GetHandleSize(h); - if (size != 256) - { - DoError(107 | RESOURCE_ERRORCLASS, LEVEL2, NULL); - return (FALSE); - } - - HLockHi(h); - *table = (Byte *) *h; - return (TRUE); -} -#endif short transBuffer(short oldtable, short newtable) /* translate entire buffer */ { @@ -102,39 +90,59 @@ short transBuffer(short oldtable, short newtable) /* translate entire buffer */ /*sprintf(tmp,"lineNo:%d, p:%08x, starts with:%c%c%c%c",lineNo,p,*(p->text),*(p->text+1),*(p->text+2),*(p->text+3)); putln(tmp);*/ if (p==NULL) { putln ("p is NULL"); return (-1); } if (p->text==NULL) { putln ("p->text is NULL"); return (-1); } - + // First convert the line back to Mac US format, and then to the new format. - trbuf_nat_mac((unsigned char *)p->text,width, oldtable); - trbuf_mac_nat((unsigned char *)p->text,width, newtable); - + // FIXME: cashes with 2 bytes characters... + // switchintranslation + //trbuf_mac_nat(tw, (unsigned char *)p->text, width, (unsigned char *)p->text, &outlen); + // switchintranslation + //trbuf_nat_mac((unsigned char *)p->text, width, (unsigned char *)p->text, &outlen); + p = p->next; } sprintf (tmp, "transBuffer:did convert %d lines", lineNo-1); putln (tmp); return (0); } -BytePtr GetTranslationResource(short id) + +short GetTranslationIndex(short table) { - Handle h; - - h = GetResource(MY_TRSL, id); - - if ((h == NULL) || (ResError() != noErr)) { - // Do nasty mean error here. BUGG - } - - DetachResource(h); - HLockHi(h); - return((BytePtr) *h); + if ( table > gTableCount ) { + return gTableCount - table; + } + return table; } -// table #'s 1...n correspond to tables in our master array, table #0 is the default table -BytePtr ReturnTablePtr(short table, Boolean out) + +BytePtr GetTranslationResource(short id) { - if (table > nNational || table < 1) return(DefaultTable + ((out == TRUE) * 256)); - return((BytePtr)(*transTablesHdl + ((table - 1) * 512) + ((out == TRUE) * 256))); + Handle h; + + h = GetResource(MY_TRSL, id); + if ( h == NULL || ResError() != noErr ) { + return NULL; + } + DetachResource(h); + HLockHi(h); + return (BytePtr)*h; } + +// table #'s 1...n correspond to tables in our master array, table #0 is the default table +BytePtr ReturnTablePtr(short table, Boolean out) +{ + BytePtr ptable; + + if (table < 1 || table > gTableCount) + ptable = DefaultTable; + else + ptable = (BytePtr)*transTablesHdl + (table - 1) * 512; + if ( out && ptable ) + ptable += 256; + return ptable; +} + + // The Default table (i.e. no translation) and the two FTP tables are stored in the // Application's resource fork as resources of type TRSL. The // tables added and removed by the user are stored in the prefs file as resources of @@ -147,143 +155,563 @@ void Setup_Default_Tables(void) FTPoutTable = FTPinTable + 256; } -/* -* Be very careful with calling putln from this procedure, since -* putln uses the translation tables. If the tables are not setup -* garbage output will appear. This is not harmful, but very -* annoying. -*/ -void trInit (MenuHandle whichMenu) +void BuildTranslateMenu(MenuHandle whichMenu) +{ + Str255 scratchPstring; + + short numberOfTerms = CountResources(USER_TRSL); + LinkedListNode *theHead = createSortedList2(USER_TRSL, numberOfTerms, NULL); + GetIndString(scratchPstring, MISC_STRINGS, NONE_STRING); //"None" string + AppendMenu(whichMenu, scratchPstring); + addListToMenu/*3*/(whichMenu, theHead, 2); + EnableItem(whichMenu, 0); // Make sure the entire menu is enabled + deleteList(&theHead); + if ( gTableCount < nNational ) { + // append hard-coded translations + AppendMenu(whichMenu, "\p "); + // WARNING: this string must match the one in NewPreferences + SetMenuItemText(whichMenu, gTableCount + 2, "\pJIS (ISO-2022-JP)"); + AppendMenu(whichMenu, "\p "); + SetMenuItemText(whichMenu, gTableCount + 3, "\pEUC-JP"); + AppendMenu(whichMenu, "\p "); + SetMenuItemText(whichMenu, gTableCount + 4, "\pShift-JIS"); + } +} + +#pragma mark - +/* + * Be very careful with calling putln from this procedure, since + * putln uses the translation tables. If the tables are not setup + * garbage output will appear. This is not harmful, but very + * annoying. + */ + +void trInit(MenuHandle whichMenu) { short i, numTables; Handle h; LinkedListNode *theHead; - nNational = 0; + trTECInit(); + Setup_Default_Tables(); - transTablesHdl = myNewHandle(0); UseResFile(TelInfo->ApplicationFile); - numTables = CountResources(USER_TRSL); - if (numTables) - { - Str255 NoneString; - theHead = createSortedList2(USER_TRSL,numTables,NULL); //now we have a sorted linked list of the names - GetIndString(NoneString,MISC_STRINGS,NONE_STRING); - AppendMenu(whichMenu,NoneString); - addListToMenu/*3*/(whichMenu, theHead, 2); - deleteList(&theHead); - - for (i = 2; i <= numTables + 1; i++) //start adding things from the second menu item (first is none) - { + gTableCount = CountResources(USER_TRSL); + if (gTableCount) { + transTablesHdl = myNewHandle(512 * gTableCount); + HLockHi(transTablesHdl); + nNational += gTableCount; + BuildTranslateMenu(whichMenu); + for (i = 0; i < gTableCount; i++) { + // start adding things from the second menu item (first is none) Str255 menuItemName; - GetMenuItemText(whichMenu, i,menuItemName); - h = GetNamedResource(USER_TRSL,menuItemName); + GetMenuItemText(whichMenu, i + 2, menuItemName); + h = GetNamedResource(USER_TRSL, menuItemName); if (h != NULL && ResError() == noErr) { - if ( GetHandleSize(h) == 512) { - nNational++; - // Append the table's data to the master array of table data - HUnlock(transTablesHdl); - if (mySetHandleSize(transTablesHdl, (nNational * 512))) { - ReleaseResource(h); - break; - } - HLockHi(transTablesHdl); + if ( GetHandleSize(h) == 512 ) { HLock(h); - BlockMoveData(*h, (*transTablesHdl) + ((nNational - 1) * 512), 512); + BlockMoveData(*h, *transTablesHdl + i * 512, 512); } - // Release the resource ReleaseResource(h); } } - } UseResFile(TelInfo->SettingsFile); } -/* Converts a char from 8-bit National to 8-bit Macintosh */ -void trbuf_nat_mac(unsigned char *buf, short len, short table) -{ - short i; - unsigned char *p; - BytePtr table_data; - table_data = ReturnTablePtr(table, FALSE); - - for (i=0,p=buf; iinnational; + + tw->fromconverter = NULL; + tw->toconverter = NULL; + tw->innational = 0x7fff; // force converter to load + tw->incharset = -1; + tw->outnational = 0x7fff; // force converter to load + tw->outcharset = -1; + switchintranslation(tw, national, kASCII); + switchouttranslation(tw, national, kASCII); +} + +/* + * disposetranslation + */ +void disposetranslation(WindRec *tw) +{ +#if GENERATINGPOWERPC + if ( tw->fromconverter ) { + TECDisposeConverter(tw->fromconverter); + tw->fromconverter = NULL; } - -} - -unsigned char ftp_iso_mac(unsigned char *ascii) -{ - short b; - - b = (short) *ascii; - *ascii = FTPinTable[b]; - return (*ascii); -} - - -void trbuf_ftp_mac(unsigned char *buf, short len) -{ - short i; - unsigned char ascii; - unsigned char *p; - - for (i=0,p=buf; itoconverter ) { + TECDisposeConverter(tw->toconverter); + tw->toconverter = NULL; } - +#endif +} + +/* + * switchintranslation + */ +void switchintranslation(WindRec *tw, short national, short charset) +{ +#if GENERATINGPOWERPC + short table; + OSStatus res; + TextEncoding outputEncoding; + TextEncoding inputEncoding; + + if (gVSemlogging) + return; + + table = GetTranslationIndex(national); + + //VSprintf("switchintranslation : %d, %d\n", table, charset); + + if ( tw->innational != national ) { + switch ( table ) { + case kTRJIS: + // kTextEncodingJIS_X0208_90 ? + // kTextEncodingJIS_X0212_90 ? + // kTextEncodingJIS_C6226_78 ? + inputEncoding = kTextEncodingISO_2022_JP; + outputEncoding = kTextEncodingMacJapanese; + break; + case kTREUC_JP: + inputEncoding = kTextEncodingEUC_JP; + outputEncoding = kTextEncodingMacJapanese; + break; + case kTShiftJIS: + inputEncoding = kTextEncodingShiftJIS; + outputEncoding = kTextEncodingMacJapanese; + break; +/* + case JISX0212: + inputEncoding = kTextEncodingJIS_X0212_90; + outputEncoding = kTextEncodingMacJapanese; + break; +*/ + default: + inputEncoding = 0; + break; + } + if ( tw->fromconverter ) { + TECDisposeConverter(tw->fromconverter); + tw->fromconverter = NULL; + } + + VSIw->trincount = 0; + VSIw->trinx = 0; + VSIw->trintag = 0; + + if ( inputEncoding ) { + outputEncoding = CreateTextEncoding(outputEncoding, kTextEncodingDefaultVariant, kTextEncodingDefaultFormat); + res = TECCreateConverter(&tw->fromconverter, inputEncoding, outputEncoding); + } + tw->innational = national; + tw->incharset = -1; + } + + switch ( table ) { + case kTRJIS: + if ( tw->incharset != charset ) { + tw->incharset = charset; + if ( tw->fromconverter ) { + short srclen; + short dstlen; + unsigned char buf[4]; + char *cname = NULL; + dstlen = 4; + res = TECFlushText(tw->fromconverter, buf, dstlen, &dstlen); + switch (charset) { + case kASCII: + cname = "kASCII"; + buf[0] = 0x1b; + buf[1] = '('; + buf[2] = 'B'; + break; + case kJISX0201_1976: + cname = "kJISX0201_1976"; + buf[0] = 0x1b; + buf[1] = '('; + buf[2] = 'J'; + break; + case kJISX0208_1978: + cname = "kJISX0208_1978"; + buf[0] = 0x1b; + buf[1] = '$'; + buf[2] = '@'; + break; + case kJISX0208_1983: + cname = "kJISX0208_1983"; + buf[0] = 0x1b; + buf[1] = '$'; + buf[2] = 'B'; + break; + case kJISX0201_1976Kana: // [Not Std ISO-2022-JP] + cname = "kJISX0201_1976Kana"; + buf[0] = 0x1b; + buf[1] = '('; + buf[2] = 'I'; + break; + case kJISX0212_1990: // [Not Std ISO-2022-JP] + cname = "kJISX0212_1990"; + buf[0] = 0x1b; + buf[1] = '$'; + buf[2] = 'D'; + break; + default: + return; + } + srclen = 3; + dstlen = 4; + res = TECConvertText(tw->fromconverter, buf, srclen, &srclen, buf, dstlen, &dstlen); + if ( res && res != kTECPartialCharErr ) { + VSprintf("TECConvertText switch %s failed : %d\n", cname, res); + } + } + } + break; + } +#else + if (gVSemlogging) + return; + tw->innational = national; + tw->incharset = charset; +#endif +} + +/* + * switchouttranslation + */ +void switchouttranslation(WindRec *tw, short national, short charset) +{ +#if GENERATINGPOWERPC + short table; + OSStatus res; + TextEncoding outputEncoding; + TextEncoding inputEncoding; + + if (gVSemlogging) + return; + + table = GetTranslationIndex(national); + + //VSprintf("switchouttranslation : %d, %d\n", table, charset); + + if ( tw->outnational != national ) { + switch ( table ) { + case kTRJIS: + // kTextEncodingJIS_X0208_90 ? + // kTextEncodingJIS_X0212_90 ? + // kTextEncodingJIS_C6226_78 ? + inputEncoding = kTextEncodingMacJapanese; + outputEncoding = kTextEncodingISO_2022_JP; + break; + case kTREUC_JP: + inputEncoding = kTextEncodingMacJapanese; + outputEncoding = kTextEncodingEUC_JP; + break; + case kTShiftJIS: + inputEncoding = kTextEncodingMacJapanese; + outputEncoding = kTextEncodingShiftJIS; + break; +/* + case JISX0212: + inputEncoding = kTextEncodingMacJapanese; + outputEncoding = kTextEncodingJIS_X0212_90; + break; +*/ + default: + inputEncoding = 0; + break; + } + if ( tw->toconverter ) { + TECDisposeConverter(tw->toconverter); + tw->toconverter = NULL; + } + if ( inputEncoding ) { + tw->troutcount = 0; + inputEncoding = CreateTextEncoding(inputEncoding, kTextEncodingDefaultVariant, kTextEncodingDefaultFormat); + res = TECCreateConverter(&tw->toconverter, inputEncoding, outputEncoding); + } + tw->outnational = national; + tw->outcharset = charset; + } + +#else + if (gVSemlogging) + return; + tw->outnational = national; + tw->outcharset = charset; +#endif +} + +/* flush input translation */ +int trflush_nat_mac(WindRec *tw) +{ + OSStatus res = 0; +#if GENERATINGPOWERPC + short table; + char buf[32]; + ByteCount len; + short charset; + + //tw->trincount = 0; + //tw->trinx = 0; + //tw->trintag = 0; + table = GetTranslationIndex(tw->innational); + if ( table < 0 ) { + if ( tw->fromconverter ) { + len = sizeof(buf); + res = TECFlushText(tw->fromconverter, buf, len, &len); + charset = tw->incharset; + tw->incharset = -1; + switchintranslation(tw, tw->innational, charset); + } + } +#endif + return res; +} + +/* flush output translation */ +int trflush_mac_nat(WindRec *tw) +{ + OSStatus res = 0; +#if GENERATINGPOWERPC + short table; + char buf[32]; + ByteCount len; + short charset; + + tw->troutcount = 0; + table = GetTranslationIndex(tw->outnational); + if ( table < 0 ) { + if ( tw->toconverter ) { + len = sizeof(buf); + res = TECFlushText(tw->toconverter, buf, len, &len); + charset = tw->outcharset; + tw->outcharset = -1; + switchintranslation(tw, tw->outnational, charset); + } + } +#endif + return res; } -/* Converts a char from 8-bit Macintosh to 8-bit National */ -unsigned char mac_nat(unsigned char *ascii, short table) +/* Converts a buffer from 8/16-bit National to 8/16-bit Macintosh */ +/* WARNING: ouptut size can be twice as big as input */ +int trbuf_nat_mac(WindRec *tw, unsigned char *buf, long *len, unsigned char *out, long *outlen) { - short b; - BytePtr table_data = ReturnTablePtr(table, TRUE); - - b = (short) *ascii; - *ascii = table_data[b]; - return (*ascii); + OSStatus res = 0; + short table; + long i = *len; + + table = GetTranslationIndex(tw->innational); + if ( table >= 0 ) { + BytePtr table_data = ReturnTablePtr(table, FALSE); + if ( table_data ) { + while (i--) + *out++ = table_data[*buf++]; + } else { + memcpy(out, buf, *len); + } + *outlen = *len; +#if GENERATINGPOWERPC + } else { + switch ( table ) { + case kTRJIS: + switch (tw->incharset) { + case kASCII: + case kJISX0201_1976: + case kJISX0208_1978: + case kJISX0208_1983: + case kJISX0212_1990: + if ( tw->fromconverter ) { + res = TECConvertText(tw->fromconverter, buf, *len, len, out, *outlen, outlen); + } else { + memcpy(out, buf, *len); + *outlen = *len; + } + break; + case kJISX0201_1976Kana: + // single byte + // FIXME + memcpy(out, buf, *len); + *outlen = *len; + break; + default: + memcpy(out, buf, *len); + *outlen = *len; + break; + } + break; + case kTREUC_JP: + case kTShiftJIS: + case JISX0212: + if ( tw->fromconverter ) { + res = TECConvertText(tw->fromconverter, buf, *len, len, out, *outlen, outlen); + } else { + memcpy(out, buf, *len); + *outlen = *len; + } + break; + default: + memcpy(out, buf, *len); + *outlen = *len; + break; + } +#endif + } + return res; } -unsigned char ftp_mac_iso(unsigned char *ascii) +/* Converts a buffer from 8/16-bit Macintosh to 8/16-bit National */ +/* WARNING: ouptut size can be twice as big as input */ +int trbuf_mac_nat(WindRec *tw, unsigned char *buf, long *len, unsigned char *out, long *outlen) { - short b; - - b = (short) *ascii; - *ascii = FTPoutTable[b]; - return (*ascii); + OSStatus res = 0; + short table; + short i = *len; + + table = GetTranslationIndex(tw->outnational); + if ( table >= 0 ) { + BytePtr table_data = ReturnTablePtr(table, TRUE); + if ( table_data ) { + while (i--) + *out++ = table_data[*buf++]; + } else { + memcpy(out, buf, *len); + } + *outlen = *len; +#if GENERATINGPOWERPC + } else { + switch ( table ) { + case kTRJIS: + case kTREUC_JP: + case kTShiftJIS: + case JISX0212: + if ( tw->toconverter ) { + res = TECConvertText(tw->toconverter, buf, *len, len, out, *outlen, outlen); + } else { + memcpy(out, buf, *len); + *outlen = *len; + } + break; + default: + memcpy(out, buf, *len); + *outlen = *len; + break; + } +#endif + } + return res; } -void trbuf_mac_nat(unsigned char *buf, short len, short table) + +/* Converts a handle from 8/16-bit National to 8/16-bit Macintosh */ +Handle htrbuf_nat_mac(WindRec *tw, Handle hin) { - short i; - unsigned char ascii; - unsigned char *p; - - for (i=0,p=buf; i + extern THPrint PrRecHandle; /* LU - our print record handle from menu.c */ extern Cursor *theCursors[]; extern long TempItemsDirID; @@ -64,6 +67,12 @@ extern VSscrndata *VSscreens; extern WindRec *console; extern void syslog( int priority, const char *format, ...); +extern Boolean gInitialized; + +int gVSemlogging = 0; + +void VSprintf(char *fmt, ...); +void VSdump(char *p, int len); #define CUR_DEF 0 #define CUR_NONE 1 @@ -147,7 +156,7 @@ void VSprOFF(void) OSErr sts; GrafPtr savePort; char tmp[100]; /* only for debugging */ - short temp; /* NCSA: SB - the screen # */ + short sn; /* NCSA: SB - the screen # */ THPrint PrRecHandle; putln ("printer redirection OFF"); @@ -174,13 +183,13 @@ void VSprOFF(void) SysBeep(1); sprintf(tmp,"PrOpenDoc: ERROR %d",sts); putln(tmp); } else { - temp = findbyVS(VSIwn); /* NCSA: SB */ - if (temp < 0) { + sn = findbyVS(VSIwn); /* NCSA: SB */ + if (sn < 0) { PrClose(); /* NCSA: SB */ DisposeHandle((Handle)PrRecHandle); return; /* NCSA: SB */ } - printPages (prPort, PrRecHandle, Title, VSmaxwidth(VSIwn), NULL, VSIw->refNum, 0L,temp); + printPages (prPort, PrRecHandle, Title, VSmaxwidth(VSIwn), NULL, VSIw->refNum, 0L,sn); PrCloseDoc(prPort); if ((sts=PrError()) != noErr) { sprintf(tmp,"PrCloseDoc: ERROR %d",sts); @@ -217,6 +226,33 @@ void VSprOFF(void) #define ENDOFPRT '\033[4i' /* [4i (0x1b5b3469) */ #define ENDOFPRT2 '[?4i' // only valid if (prbuf2 == '\033') +static OSErr VStranslatewrite(char *string, long len) +{ + OSErr theErr = 0; + char buf[512]; + long buflen; + long count; + WindRecPtr tw; + RSdata *temp; + short sn; + + sn = findbyVS(VSIwn); + if ( sn >= 0 ) { + tw = &screens[sn]; + while (!theErr && len) { + buflen = len > 256 ? 256 : len; + count = sizeof(buf); + trbuf_mac_nat(tw, (unsigned char *)string, &buflen, (unsigned char *)buf, &count); + theErr = FSWrite(VSIw->refNum, &count, buf); + len -= buflen; + string += buflen; + } + } else { + theErr = FSWrite(VSIw->refNum, &len, string); + } + return theErr; +} + void VSpr(unsigned char **pc, short *pctr) { long count; /* number of chars to print to file */ @@ -247,17 +283,15 @@ void VSpr(unsigned char **pc, short *pctr) if (**pc == 0) { // RAB BetterTelnet 1.0fc7 // We don't want NULLs here! count--; - trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); - FSWrite(VSIw->refNum,&count,start); + VStranslatewrite(start, count); start += (count + 1); count = 0; } (*pc)++; (*pctr)--; } - - trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); - if ((sts=FSWrite(VSIw->refNum,&count,start)) != noErr) { + sts = VStranslatewrite(start, count); + if ( sts != noErr ) { SysBeep(1); sprintf(tmp,"FSWrite: ERROR %d",sts); putln(tmp); } @@ -266,10 +300,94 @@ void VSpr(unsigned char **pc, short *pctr) } +/* + * VSprintf + */ + +void VSprintf(char *fmt, ...) +{ + va_list args; + char string_buf[1024]; + int len; + short sx; + + if ( gInitialized && !gVSemlogging && console && console->wind && VSIwn != console->vs ) { + ++gVSemlogging; + sx = VSIwn; + //VSvalids(sx); + //RSsetwind(sx); + va_start( args, fmt ); + len = vsnprintf( string_buf, sizeof(string_buf) - 1, fmt, args ); + va_end( args ); + if ( len > 0 ) { + putlln( string_buf, len ); + } + //VSvalids(sx); + VSIwn = sx; + VSIw = VSscreens[sx].loc; + RSsetwind(sx); + --gVSemlogging; + } +} + +/* + * VSdump + */ + +void VSdump(char *p, int len) +{ + va_list args; + char string_buf[1024]; + static int gVSemlogging = 0; + short sx; + + if ( gInitialized && !gVSemlogging && console && console->wind && VSIwn != console->vs) { + ++gVSemlogging; + sx = VSIwn; + dumpln( (long)p, 0, p, len ); + VSIwn = sx; + VSIw = VSscreens[sx].loc; + --gVSemlogging; + } +} + + +/* + * VSdump + */ + +static void trflush(WindRec *tw) +{ + if ( tw ) { + trflush_nat_mac( tw ); + VSIw->trinx = 0; + VSIw->trincount = 0; + } +} + +/* escape states for VSem */ + +enum { + esc_root = 0, /* default */ + esc_basic, /* processing ESC character */ + esc_csi, /* processing ESC '[' character */ + esc_decl, + esc_descl, + esc_G0, + esc_G1, + esc_G2, + esc_G3, + esc_G0j, + esc_G2j, + esc_XTerm +}; + /* LU - that is the end of the new routines needed for printer redirection */ /* LU - now we just patch up VSem() to use this code, and were done! */ +unsigned char vsoutbuf[512]; + void VSem ( unsigned char *c, /* pointer to character string */ @@ -282,11 +400,13 @@ void VSem { register short sx; register short escflg; /* state of escape sequence interpretation */ + short escflags; /* state of escape sequence interpretation */ VSAttrib attrib; short insert, extra, offend; char *current, *start; VSAttrib *acurrent; - WindRec *screen; + short sn; + WindRec *tw; Boolean tryit; Boolean captured; short savedX; @@ -294,11 +414,17 @@ void VSem unsigned char savedChar; long val; short mw; + Boolean needwrap; + int i; escflg = VSIw->escflg; + escflags = VSIw->escflags; captured = false; +//VSprintf( "VSem:" ); +//VSdump( c, ctr ); + #ifdef DEBUG_CAPTURE if (TelInfo->debug) { if (VSscreens[VSIwn].captureRN) { @@ -313,13 +439,13 @@ void VSem } } #endif - screen = &screens[findbyVS(VSIwn)]; - + sn = findbyVS(VSIwn); + tw = (sn >= 0) ? &screens[sn] : NULL; while (ctr > 0) { mw = VSIw->maxwidth; - if ((VSIw->lattrib & 3)) { + if (VSisdecdwh(VSIw->lattrib)) { mw >>= 1; if ( !(VSIw->maxwidth & 1) ) mw -= 1; @@ -330,19 +456,19 @@ void VSem /* PR - when we return from VSpr there may (ctr!=0) É */ /* PR - É or may not (ctr==0) be chars left in *c to print */ tryit = 0; - while (escflg == 0 && ctr > 0 && *c < 32 && !tryit) { + while (escflg == esc_root && ctr > 0 && *c < 32 && !tryit) { switch (*c) { case 0x1b: /* esc */ - escflg++; + escflg = esc_basic; break; - case 0x0e: /* shift out */ + case 0x0e: /* Lock Shift G1 */ if (VSIw->G1) VSIw->attrib = VSgraph(VSIw->attrib); else VSIw->attrib = VSnotgraph(VSIw->attrib); VSIw->charset = 1; break; - case 0x0f: /* shift in */ + case 0x0f: /* Lock Shift G0 */ if (VSIw->G0) VSIw->attrib = VSgraph(VSIw->attrib); else @@ -354,10 +480,9 @@ void VSem RSbell(VSIwn); break; case 0x08: /* backspace */ - VSIw->x--; - if (VSIw->x < 0) - /* hit left margin */ - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; + trflush(tw); break; case 0x0c: /* ff */ VSIindex(); @@ -379,7 +504,7 @@ void VSem VSIindex(); break; default: - if ( *c >= 0x10 && screen->vtemulation >= 2 ) { + if ( *c >= 0x10 && VSIw->vtemulation >= 2 ) { tryit = 1; c--; ctr++; @@ -389,7 +514,8 @@ void VSem c++; ctr--; } - if (escflg == 0 && ctr > 0 && (*c & 0x80) && *c < 0xA0 && screen->vtemulation != 0) { + if ( escflg == esc_root && ctr > 0 + && (*c & 0x80) && *c < 0xA0 && VSIw->vtemulation != 0 && VSIw->vteightbits ) { // VT220 eightbit starts here switch (*c) { case 0x84: /* ind */ //same as ESC D @@ -407,19 +533,34 @@ void VSem goto ShortCut; case 0x9b: /* csi */ //same as ESC [ VSIapclear(); - escflg = 2; + escflg = esc_csi; + escflags = 0; c++; //CCP ctr--; break; - case 0x86: /* ssa */ // - same as ESC F - case 0x87: /* esa */ // - same as ESC G - case 0x8e: /* ss2 */ // - same as ESC N - case 0x8f: /* ss3 */ // - same as ESC O - case 0x90: /* dcs */ // - same as ESC P - case 0x93: /* sts */ // - same as ESC S - case 0x96: /* spa */ // - same as ESC V - case 0x97: /* epa */ // - same as ESC W - case 0x9d: /* osc */ // - same as ESC ] + case 0x86: /* ssa */ // - same as ESC 'F' + case 0x87: /* esa */ // - same as ESC 'G' + goto ShortCut; + case 0x8e: /* ss2 */ // - same as ESC 'N' + // switch to G2 for next char only + // FIXME + goto ShortCut; + case 0x8f: /* ss3 */ // - same as ESC 'O' + // switch to G3 for next char only + // FIXME + goto ShortCut; + case 0x90: /* dcs */ // - same as ESC 'P' + case 0x93: /* sts */ // - same as ESC 'S' + case 0x96: /* spa */ // - same as ESC 'V' + case 0x97: /* epa */ // - same as ESC 'W' + goto ShortCut; + case 0x9d: /* osc */ // - same as ESC ']' + if (tw && tw->Xterm) { + escflg = esc_XTerm; + escflags = 0; + break; + } + goto ShortCut; case 0x9e: /* pm */ // - same as ESC ^ case 0x9f: /* apc */ // - same as ESC _ default: @@ -427,164 +568,314 @@ void VSem } }//end if vt220 - while (ctr > 0 && escflg == 0 && (*c >= 32 || tryit) && !((*c & 0x80) && (*c < 0xA0) - && screen->vtemulation != 0)) { - //loop around, printing lines of text one at a time - start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */ - current = start; /* where to put next char */ + while (escflg == esc_root && ctr > 0 && (*c >= 32 || tryit) + && !((*c & 0x80) && *c < 0xA0 && VSIw->vtemulation != 0 && VSIw->vteightbits)) { + + // loop around, printing lines of text one at a time + + // where to put next char + current = start = &VSIw->linest[VSIw->y]->text[VSIw->x]; + // where to put corresponding attribute byte if (VSIw->oldScrollback) { acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; } else { - acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; /* where to put corresponding attribute byte */ + acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; } - - attrib = VSIw->attrib; /* current writing attribute */ - insert = VSIw->IRM; /* insert mode (boolean) */ - offend = 0; /* wrapped to next line (boolean) */ - extra = 0; /* overwriting last character of line */ - sx = VSIw->x; /* starting column of area needing redrawing */ - if (VSIw->x > mw) { - if (VSIw->DECAWM) { // wrap to next line + attrib = VSIw->attrib; // current writing attribute + insert = VSIw->IRM; // insert mode (boolean) + offend = 0; // wrapped to next line (boolean) + extra = 0; // overwriting last character of line + sx = VSIw->x; // starting column of area needing redrawing + + if ( VSIw->x > mw ) { + if (VSIw->DECAWM) { // wrap to next line VSIw->x = 0; + VSIw->linest[VSIw->y]->lattr |= kVSwrap; VSIindex(); - } else //stay at right margin + } else { // stay at right margin VSIw->x = mw; - + } current = start = &VSIw->linest[VSIw->y]->text[VSIw->x]; if (VSIw->oldScrollback) acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; else acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; sx = VSIw->x; - } /* if */ + } - while (ctr > 0 && (*c >= 32 || tryit) && offend == 0 && !((*c & 0x80) && *c < 0xA0 - && screen->vtemulation != 0)) { - //Write characters on a single line + // Write characters on a single line + while (ctr > 0 && (*c >= 32 || tryit) && offend == 0 + && !((*c & 0x80) && *c < 0xA0 && VSIw->vtemulation != 0 && VSIw->vteightbits)) { + // translate to mac chars + if ( tw ) { + int res; + long inlen; + unsigned char trbuf[32]; + long trlen; + unsigned char *pbuf; + VSAttrib trattr; - VSIw->lastchar = *c; + pbuf = VSIw->trinbuf; + pbuf[VSIw->trincount++] = *c; + inlen = VSIw->trincount; + trlen = sizeof(trbuf); +//VSprintf( "itrin:" ); +//VSdump( pbuf, inlen ); + res = trbuf_nat_mac( tw, pbuf, &inlen, trbuf, &trlen ); + if ( res && res != kTECPartialCharErr ) { +//VSprintf( "###itrfailed: %d\n", res ); + // translation failed, leave data as-is + if ( VSIw->x > mw ) { + // hit right margin, autowrap now + if ( !VSIw->DECAWM ) { + // just eat it + ++c; + --ctr; + } else { + // autowrap to start of next line + ++VSIw->x; + offend = 1; + if ( VSIw->trinx ) { + ++sx; // one less char to display on the right + } + } + --VSIw->trincount; + continue; + } + trlen = VSIw->trincount; + trattr = attrib | kVSansi2b; + } else { + // translation ok, or no data yet + if ( inlen ) { + // keep a few chars + for (i = inlen; i <= VSIw->trincount; i++) { + pbuf[i - inlen] = pbuf[i]; + } + VSIw->trincount -= inlen; + } + if ( !trlen ) { + // nothing yet + if ( VSIw->trincount < sizeof(VSIw->trinbuf) ) { + if ((*acurrent & kVSansi2b)) { + // try to display next byte too ? + extra = 1; + } + ++VSIw->x; + ++VSIw->trinx; + ++current; + ++acurrent; + ++c; + --ctr; + if (insert) { + // make room for the char(s) + VSIinschar(1, 0); + } + continue; + } + // temp translation buffer full, unable to translate... + trlen = VSIw->trincount; +//VSprintf( "###itrfull: %d\n", trlen ); + VSIw->trincount = 0; + //res = trflush_nat_mac( tw ); + trattr = attrib; + } else { + // translation complete + pbuf = trbuf; + trattr = attrib | kVSansi2b; + extra = 0; + } + } + if (insert) { + // make room for the char + VSIinschar(1, 1); + } + current -= VSIw->trinx; + acurrent -= VSIw->trinx; + for (i = 0, --current, --acurrent; i < trlen; ++i) { + *(++current) = pbuf[i]; + *(++acurrent) = trattr; // tag first chars + } + VSIw->lastchar = *current; - trbuf_nat_mac(c,1, screen->national); //translate to national chars - if (insert) //make room for the char - VSIinschar(1); - *current = *c; - *acurrent = attrib; - c++; - ctr--; - if (VSIw->x < mw) { - //advance the cursor position - acurrent++; - current++; - VSIw->x++; + // set attribute + if ( trlen == 1 && (*current & 0x80) && !VSIw->trintag + && GetTranslationIndex(tw->innational) < 0 ) { + // tag allowed in multi-byte + VSIw->trintag = 1; + } else { + // don't tag last char + *acurrent = attrib; + VSIw->trintag = 0; + } + if ( VSIw->x == sx && sx > 0 && (acurrent[-1] & kVSansi2b)) { + // display previous byte too + --sx; + --start; + *acurrent = attrib; + VSIw->trintag = 0; + } + if ((*acurrent & kVSansi2b)) { + // try to display next byte too ? + extra = 1; + } + VSIw->trinx = 0; + VSIw->trincount = 0; +//VSprintf( "itrout:" ); +//VSdump( pbuf, trlen ); } else { - //hit right margin + /* no window, no translation */ + VSIw->lastchar = *c; + if (insert) // make room for the char + VSIinschar(1, 1); + *current = *c; + *acurrent = attrib; + } + ++c; + --ctr; + if ( VSIw->x < mw ) { + // advance the cursor position + ++acurrent; + ++current; + ++VSIw->x; + } else { + // hit right margin if (VSIw->DECAWM) { - //autowrap to start of next line - VSIw->x++; + // autowrap to start of next line + ++VSIw->x; offend = 1; // terminate inner loop } else { - //stay at right margin + // stay at right margin VSIw->x = mw; extra = 1; // cursor position doesn't advance } } - } //we've got a line full of text in the virtual screen + } // we've got a line full of text in the virtual screen - //now update the screen to show what we've done + // now update the screen to show what we've done extra += VSIw->x - sx; - if (insert) { - RSinsstring(VSIwn, VSIw->x - extra, VSIw->y, VSIw->lattrib, VSIw->attrib, extra, start); + if ( insert ) { + RSinsstring( VSIwn, VSIw->x - extra, VSIw->y, VSIw->lattrib, VSIw->attrib, extra, start ); } else { - short x2,y2,offset, sxCopy=sx,yCopy = VSIw->y, extraCopy = extra; - if (!VSIclip(&sxCopy, &yCopy, &x2, &y2, &extraCopy, &offset)) { - RSdraw(VSIwn, sxCopy,yCopy, VSIw->lattrib, VSIw->attrib,extraCopy,(char *) (start + offset)); + short x2, y2, offset, cx = sx, cy = VSIw->y, extraCopy = extra; + if (!VSIclip(&cx, &cy, &x2, &y2, &extraCopy, &offset)) { +//VSprintf( "idraw:" ); +//VSdump( start + offset, extraCopy ); + RSdraw( VSIwn, cx, cy, VSIw->lattrib, VSIw->attrib, extraCopy, start + offset ); } } - if (!captured) - VScapture((unsigned char *) start, extra); - } /* while */ + if ( !captured ) { + VScapture( (unsigned char *)start, extra ); + } + } - while ( escflg == 1 && ctr > 0 ) { + while ( escflg == esc_basic && ctr > 0 ) { /* basic escape sequence processing */ switch (*c) { case 0x08: - VSIw->x--; - if (VSIw->x < 0) - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; break; - case '[': /* csi */ + case '[': // csi VSIapclear(); - escflg++; - VSIw->escflags = 0; + escflg = esc_csi; + escflags = 0; break; case '7': VSIsave(); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case '8': VSIrestore(); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'c': VSIreset(); - break; + goto ShortCut; case 'D': VSIindex(); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'E': VSIw->x = 0; VSIindex(); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'M': VSIrindex(); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; + case 'N': // Single Shift G2 + // switch to G2 for next char only + // FIXME + goto ShortCut; + case 'O': // Single Shift G3 + // switch to G2 for next char only + // FIXME + goto ShortCut; case '>': VSIw->DECPAM = 0; - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case '=': VSIw->DECPAM = 1; - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'Z': VTsendident(); - goto ShortCut; /* BYU 2.4.12 */ - case ' ': /* BYU 2.4.12 */ - case '*': /* BYU 2.4.12 */ + goto ShortCut; + case ' ': // sure ? case '#': - escflg = 3; + escflg = esc_decl; break; case '(': - escflg = 4; + escflg = esc_G0; break; case ')': - escflg = 5; + escflg = esc_G1; + break; + case '*': + escflg = esc_G2; + break; + case '+': + escflg = esc_G3; + break; + case '$': + escflg = esc_G0j; + escflags = 0; + break; + case '.': + escflg = esc_G2j; break; case 'H': VSIw->tabs[VSIw->x] = 'x'; - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; #ifdef CISB case 'I': bp_ESC_I(); break; #endif CISB - case ']': // WNR - XTerm - if (screen->Xterm) // WNR - XTerm - escflg = 6; // WNR - XTerm - break; // WNR - XTerm - + case ']': + if (tw && tw->Xterm) { + escflg = esc_XTerm; + escflags = 0; + break; + } + goto ShortCut; + case 'n': // Lock Shift G2, Left + case '}': // Lock Shift G2, Right + case 'o': // Lock Shift G3, Left + case '|': // Lock Shift G3, Right + // switch to charset + // FIXME + goto ShortCut; default: - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; } /* switch */ c++; ctr--; } /* while */ - while ( escflg == 2 && ctr > 0 ) { + while ( escflg == esc_csi && ctr > 0 ) { /* "control sequence" processing */ switch (*c) { case 0x08: - VSIw->x--; - if (VSIw->x < 0) - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; break; case '0': case '1': @@ -613,6 +904,11 @@ void VSem VSIw->parmptr++; break; + case '"': + /* start Compatibility Level (DECSCL) */ + escflg = esc_descl; + break; + case 'A': /* cursor up */ sx = VSIw->parms[0]; if (sx < 1) sx = 1; @@ -622,7 +918,7 @@ void VSem VSIw->y = VSIw->top; /* NCSA: SB */ VSIrange(); VSIflush(); // RAB BetterTelnet 2.0b3 - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'X': /* Erases characters at the cursor position and the next n-1 characters */ @@ -635,14 +931,13 @@ void VSem savedY = VSIw->y; savedChar = VSIw->lastchar; VSIw->lastchar = ' '; - /* leave current attribute for linux */ - if (screen->vtemulation != 3) { - VSIw->attrib &= 0x80; // all off + /* leave current attribute as-is for linux ??? */ + if (VSIw->vtemulation != 3) { + VSIw->attrib &= (kVSansi2b | kVSgrph); // all off, keep multi-byte / graphic } // FALL-THROUGH case 'b': /* repeat last char n times ? */ while ( VSIw->parms[0] > 0 ) { - int i; int len = VSIw->parms[0]; unsigned char repeatbuf[256]; short savecaptureRN; @@ -652,12 +947,16 @@ void VSem VSIw->parms[0] -= len; for (i = 0; i < len; ++i) repeatbuf[i] = VSIw->lastchar; - VSIw->escflg = 0; + VSIw->escflg = esc_root; /* disable capture of already captured data */ - savecaptureRN = VSscreens[VSIwn].captureRN; - VSscreens[VSIwn].captureRN = 0; + if ( TelInfo->debug ) { + savecaptureRN = VSscreens[VSIwn].captureRN; + VSscreens[VSIwn].captureRN = 0; + } VSem(repeatbuf, len); - VSscreens[VSIwn].captureRN = savecaptureRN; + if ( TelInfo->debug ) { + VSscreens[VSIwn].captureRN = savecaptureRN; + } } if (*c == 'X') { VSIw->x = savedX; @@ -674,7 +973,7 @@ void VSem VSIw->y = VSIw->bottom; /* NCSA: SB */ VSIrange(); VSIflush(); // RAB BetterTelnet 2.0b3 - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; case 'C': /* cursor right */ sx = VSIw->parms[0]; @@ -690,230 +989,8 @@ void VSem VSIrange(); if (VSIw->x > mw) VSIw->x = mw; - goto ShortCut; /* BYU 2.4.12 */ - - case 'd': /* Y cursor position ? */ - VSIw->y = VSIw->parms[0] - 1; - if (VSIw->DECAWM && VSIw->x > mw) - VSIw->x = 0; - if (VSIw->y < 0) - VSIw->y = 0; - if (VSIw->y > VSIw->lines) - VSIw->y = VSIw->lines; goto ShortCut; - case 'D': /* cursor left */ - sx = VSIw->parms[0]; - if (sx < 1) sx = 1; - if (VSIw->DECAWM && VSIw->x <= 0) { - // autowrap - if (VSIw->y <= 0) - goto ShortCut; - VSIw->y--; - VSIw->x = mw + 1; - } - VSIw->x -= sx; - VSIrange(); - goto ShortCut; /* BYU 2.4.12 */ - - case 'G': /* X cursor position ? */ - if (VSIw->DECAWM && VSIw->x > mw) { - // autowrap - if (VSIw->y >= VSIw->lines) - goto ShortCut; - VSIw->y++; - } - VSIw->x = VSIw->parms[0] - 1; - if (VSIw->x < 0) - VSIw->x = 0; - if (VSIw->x > mw) - VSIw->x = mw; - goto ShortCut; - - case 'f': - case 'H': - /* absolute cursor positioning */ - VSIw->x = VSIw->parms[1] - 1; - if (VSIw->DECORG) - /* origin mode -- position relative to top of scrolling region */ - VSIw->y = VSIw->parms[0] - 1 + VSIw->top; - else - VSIw->y = VSIw->parms[0] - 1; - /* Don't use actual VSIrange 'cause it will wrap us to first column if - we are past screen edge. This causes "resize" to break */ - if (VSIw->x < 0) /* JMB 2.6 */ - VSIw->x = 0; /* JMB 2.6 */ - if (VSIw->x > mw) /* JMB 2.6 */ - VSIw->x = mw; /* JMB 2.6 */ - if (VSIw->y < 0) /* JMB 2.6 */ - VSIw->y = 0; /* JMB 2.6 */ - if (VSIw->y > VSIw->lines) /* JMB 2.6 */ - VSIw->y = VSIw->lines; /* JMB 2.6 */ - if ((VSIw->forcesave)&&(VSIw->y == 0)&&(VSIw->x == 0)) //CCP better FORCESAVE - VSIw->possibleForce = TRUE; - - if (VSIw->y != VSIw->bottom) VSIflush(); // RAB BetterTelnet 2.0b3 - goto ShortCut; /* BYU 2.4.12 */ - - case 'i': /* PR: media copy */ - if (VSIw->parms[VSIw->parmptr]==5) { /* PR */ - /*c++; ctr--; */ /* PR */ - VSprON(); /* PR - set status and open temp file etc */ - /* PR - chars will be redirected at top of loop É */ - /* PR - É in this procedure */ - } /* PR */ - escflg = 0; /* PR */ - break; /* PR */ - - case 'J': - /* erase to beginning/end/whole of screen */ - switch (VSIw->parms[0]) - { - case -1: - case 0: - VSIeeos(); - break; - case 1: - VSIebos(); - break; - case 2: - VSIes(); - break; - default: - goto ShortCut; /* BYU 2.4.12 */ - } /* switch */ - goto ShortCut; /* BYU 2.4.12 */ - - case 'K': - /* erase to beginning/end/whole of line */ - switch (VSIw->parms[0]) - { - case -1: - case 0: - VSIeeol(); - break; - case 1: - VSIebol(); - break; - case 2: - VSIel(-1); - break; - default: - goto ShortCut; /* BYU 2.4.12 */ - } /* switch */ - goto ShortCut; /* BYU 2.4.12 */ - - case 'm': -#if 0 - if (VSIw->parms[0] == -2) { - /* clear selection => unused */ -/* - clear_selection(); - if (par[0]) - complement_mask = par[0]<<8 | par[1]; - else - complement_mask = s_complement_mask; -*/ - goto ShortCut; - } -#endif - /* set/clear attributes */ - { - short temp = 0; - - if (VSIw->parms[VSIw->parmptr] < 0) - VSIw->parms[VSIw->parmptr] = 0; - - while (temp <= VSIw->parmptr) { - short p = VSIw->parms[temp]; - if (p == 0) { - VSIw->attrib &= 0x80; // all off - } else if (p > 0 && p < 8 ) { - VSIw->attrib |= VSa(p); // set an attribute - } else if (p >= 10 && p < 20 ) { - // 10 : Primary (default) font - // 11..19 : alternate fonts - } else if (p > 20 && p < 28) { - VSIw->attrib &= ~VSa(p - 20); // clear an attribute - } else if (screen->ANSIgraphics) { - if (p >= 30 && p < 38) { - VSIw->attrib = VSansifg((VSIw->attrib & 0xf0ff) | ((p- 30)<< 8)); - } else if (p >= 38 && p < 40) { // Turn off foreground color - VSIw->attrib &= 0xfffef0ff; - } else if (p >= 40 && p < 48) { - VSIw->attrib = VSansibg((VSIw->attrib & 0x0fff) | ((p- 40)<<12)); - } else if (p >= 48 && p < 50) { // Turn off background color - VSIw->attrib &= 0xfffd0fff; - } else if (p >= 90 && p < 98) { - VSIw->attrib = VSansifg2((VSIw->attrib & 0xf0ff) | ((p- 90)<< 8)); - } else if (p >= 100 && p < 108) { - VSIw->attrib = VSansibg2((VSIw->attrib & 0x0fff) | ((p-100)<<12)); - } - } - temp++; - } /* while */ - } - goto ShortCut; /* BYU 2.4.12 */ - - case 'n': - if ( VSIw->parms[0] == -2 ) { - switch ( VSIw->parms[1] ) { - case 15: /* (request for printer status) */ - VTsendprintstat(); - break; - case 25: /* request for UDK (use defined keys) status */ - VTsendudkstat(); - break; - } - } else { - switch (VSIw->parms[0]) { - case 5: - VTsendstat(); - break; - case 6: - VTsendpos(); - break; - } - } - goto ShortCut; - - case 'S': /* what is this one ? */ - goto ShortCut; - - - case '"': - /* start Compatibility Level (DECSCL) */ - VSIw->escflags |= 2; - break; - - case 'p': - /* set the compatibility level of the terminal */ - if ((VSIw->escflags & 2)) { - if ( VSIw->parms[0] == 61 ) { - // Set terminal for level 1 compatibility (VT100 mode) - // FIXME - } else if ( VSIw->parms[0] == 62 ) { - if ( VSIw->parms[1] == -1 || VSIw->parms[1] == 0 || VSIw->parms[1] == 2 ) { - // Set terminal for level 2 compatibility (VT200 mode, 8-bit controls). - // FIXME - } else if ( VSIw->parms[1] == 1 ) { - // Set terminal for level 2 compatibility (VT200 mode, 7-bit controls). - // FIXME - } - } - } - goto ShortCut; - - - case 'q': - /* flash dem LEDs. What LEDs? */ - goto ShortCut; /* BYU 2.4.12 */ - - case '>': - /* maybe secondary ident request */ - VSIw->escflags |= 1; - break; - case 'c': if ( VSIw->parms[0] == -2 ) { /* not the same meaning !!! */ /* set cursor_type */ @@ -942,35 +1019,229 @@ void VSem RSsetcurstype(VSIwn, val); } } else { - if (!(VSIw->escflags & 1)) { + if (!(escflags & 1)) { VTsendident(); } else { VTsendsecondaryident(); } } - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; + + case 'd': /* Y cursor position ? */ + VSIw->y = VSIw->parms[0] - 1; + if (VSIw->DECAWM && VSIw->x > mw) + VSIw->x = 0; + if (VSIw->y < 0) + VSIw->y = 0; + if (VSIw->y > VSIw->lines) + VSIw->y = VSIw->lines; + goto ShortCut; + + case 'D': /* cursor left */ + sx = VSIw->parms[0]; + if (sx < 1) sx = 1; + if (VSIw->DECAWM && VSIw->x <= 0) { + // autowrap + if (VSIw->y <= 0) + goto ShortCut; + VSIw->y--; + VSIw->x = mw + 1; + } + VSIw->x -= sx; + VSIrange(); + goto ShortCut; + + case 'G': /* X cursor position ? */ + if (VSIw->DECAWM && VSIw->x > mw) { + // autowrap + if (VSIw->y >= VSIw->lines) + goto ShortCut; + VSIw->y++; + } + VSIw->x = VSIw->parms[0] - 1; + if (VSIw->x < 0) + VSIw->x = 0; + if (VSIw->x > mw) + VSIw->x = mw; + goto ShortCut; + + case 'g': + if (VSIw->parms[0] == 3) + /* clear all tabs */ + VSItabclear(); + else if (VSIw->parms[0] <= 0) + /* clear tab at current position */ + VSIw->tabs[VSIw->x] = ' '; + goto ShortCut; + + case 'h': + /* set options */ + VSIsetoption(1); + goto ShortCut; + + case 'f': + case 'H': + /* absolute cursor positioning */ + VSIw->x = VSIw->parms[1] - 1; + if (VSIw->DECORG) + /* origin mode -- position relative to top of scrolling region */ + VSIw->y = VSIw->parms[0] - 1 + VSIw->top; + else + VSIw->y = VSIw->parms[0] - 1; + /* Don't use actual VSIrange 'cause it will wrap us to first column if + we are past screen edge. This causes "resize" to break */ + if (VSIw->x < 0) /* JMB 2.6 */ + VSIw->x = 0; /* JMB 2.6 */ + if (VSIw->x > mw) /* JMB 2.6 */ + VSIw->x = mw; /* JMB 2.6 */ + if (VSIw->y < 0) /* JMB 2.6 */ + VSIw->y = 0; /* JMB 2.6 */ + if (VSIw->y > VSIw->lines) /* JMB 2.6 */ + VSIw->y = VSIw->lines; /* JMB 2.6 */ + if ((VSIw->forcesave)&&(VSIw->y == 0)&&(VSIw->x == 0)) //CCP better FORCESAVE + VSIw->possibleForce = TRUE; + + if (VSIw->y != VSIw->bottom) VSIflush(); // RAB BetterTelnet 2.0b3 + goto ShortCut; + + case 'i': /* PR: media copy */ + if (VSIw->parms[VSIw->parmptr]==5) { /* PR */ + /*c++; ctr--; */ /* PR */ + VSprON(); /* PR - set status and open temp file etc */ + /* PR - chars will be redirected at top of loop É */ + /* PR - É in this procedure */ + } /* PR */ + escflg = esc_root; /* PR */ + break; /* PR */ + + case 'J': + /* erase to beginning/end/whole of screen */ + switch ( VSIw->parms[0] ) { + case -1: + case 0: + VSIeeos(); + break; + case 1: + VSIebos(); + break; + case 2: + VSIes(); + break; + default: + goto ShortCut; + } + goto ShortCut; + + case 'K': + /* erase to beginning/end/whole of line */ + switch ( VSIw->parms[0] ) { + case -1: + case 0: + VSIeeol(); + break; + case 1: + VSIebol(); + break; + case 2: + VSIel(-1); + break; + default: + goto ShortCut; + } + goto ShortCut; + case 'L': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIinslines(VSIw->parms[0], -1); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; + + case 'l': + /* reset options */ + VSIsetoption(0); + goto ShortCut; + case 'M': VSIflush(); // RAB BetterTelnet 2.0b3 if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdellines(VSIw->parms[0], -1); - goto ShortCut; /* BYU 2.4.12 */ - case '@': - if (VSIw->parms[0] < 1) - VSIw->parms[0] = 1; - VSIinschar(VSIw->parms[0]); - VSredrawLine(VSIwn); //redraws current line goto ShortCut; + + case 'm': + if (VSIw->parms[0] == -2) { + /* clear selection => unused */ + goto ShortCut; + } else { + /* set/clear attributes */ + short temp = 0; + + if (VSIw->parms[VSIw->parmptr] < 0) + VSIw->parms[VSIw->parmptr] = 0; + + while (temp <= VSIw->parmptr) { + short p = VSIw->parms[temp]; + if (p == 0) { + VSIw->attrib &= kVSansi2b | kVSgrph; // all off + } else if (p > 0 && p < 8 ) { + VSIw->attrib |= VSa(p); // set an attribute + } else if (p >= 10 && p < 20 ) { + // 10 : Primary (default) font + // 11..19 : alternate fonts + } else if (p > 20 && p < 28) { + VSIw->attrib &= ~VSa(p - 20); // clear an attribute + } else if (tw && tw->ANSIgraphics) { + if (p >= 30 && p < 38) { + VSIw->attrib = VSansifg((VSIw->attrib & 0xfffcf0ff) | ((p- 30)<< 8)); + } else if (p >= 38 && p < 40) { // Turn off foreground color + VSIw->attrib = VSIw->attrib & 0xfffef0ff; + } else if (p >= 40 && p < 48) { + VSIw->attrib = VSansibg((VSIw->attrib & 0xfffc0fff) | ((p- 40)<<12)); + } else if (p >= 48 && p < 50) { // Turn off background color + VSIw->attrib = VSIw->attrib & 0xfffd0fff; + } else if (p >= 90 && p < 98) { + VSIw->attrib = VSansifg2((VSIw->attrib & 0xfffcf0ff) | ((p- 90)<< 8)); + } else if (p >= 100 && p < 108) { + VSIw->attrib = VSansibg2((VSIw->attrib & 0xfffc0fff) | ((p-100)<<12)); + } + } + temp++; + } + } + goto ShortCut; + + case 'n': + if ( VSIw->parms[0] == -2 ) { + switch ( VSIw->parms[1] ) { + case 15: /* (request for printer status) */ + VTsendprintstat(); + break; + case 25: /* request for UDK (use defined keys) status */ + VTsendudkstat(); + break; + } + } else { + switch (VSIw->parms[0]) { + case 5: + VTsendstat(); + break; + case 6: + VTsendpos(); + break; + } + } + goto ShortCut; + case 'P': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdelchars(VSIw->parms[0]); - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; + + case 'q': + /* flash dem LEDs. What LEDs? */ + goto ShortCut; + case 'r': if ((VSIw->parms[0] - 1 == VSIw->top) && (VSIw->parms[1] - 1 == VSIw->bottom)) goto ShortCut; // RAB BetterTelnet 2.0b3 @@ -993,88 +1264,76 @@ void VSem if (VSIw->bottom > VSIw->lines) VSIw->bottom = VSIw->lines; - if (VSIw->top >= VSIw->bottom) /* NCSA: SB */ - { /* NCSA: SB */ - if (VSIw->bottom >=1) /* NCSA: SB */ - VSIw->top = VSIw->bottom -1; /* NCSA: SB */ - else VSIw->bottom = VSIw->top +1; /* NCSA: SB */ - } /* NCSA: SB */ + if (VSIw->top >= VSIw->bottom) { + if (VSIw->bottom >=1) + VSIw->top = VSIw->bottom -1; + else VSIw->bottom = VSIw->top +1; + } VSIw->x = 0; VSIw->y = 0; if (VSIw->DECORG) VSIw->y = VSIw->top; /* origin mode relative */ - goto ShortCut; /* BYU 2.4.12 */ - case 'h': - /* set options */ - VSIsetoption(1); - goto ShortCut; /* BYU 2.4.12 */ - case 'l': - /* reset options */ - VSIsetoption(0); - goto ShortCut; /* BYU 2.4.12 */ - case 'g': - if (VSIw->parms[0] == 3) - /* clear all tabs */ - VSItabclear(); - else if (VSIw->parms[0] <= 0) - /* clear tab at current position */ - VSIw->tabs[VSIw->x] = ' '; - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; + + case 'S': /* what is this one ? */ + goto ShortCut; + + case '>': + /* maybe secondary ident request */ + escflags |= 1; + break; + + case '@': + if (VSIw->parms[0] < 1) + VSIw->parms[0] = 1; + VSIinschar(VSIw->parms[0], 1); + VSredrawLine(VSIwn); //redraws current line + goto ShortCut; case '!': /* BYU 2.4.12 - More private DEC stuff? */ case '\'': /* BYU 2.4.12 - More private DEC stuff? */ -// case '\"': /* BYU 2.4.12 - More private DEC stuff? */ - escflg++; /* BYU 2.4.12 */ - break; /* BYU 2.4.12 */ - default: /* Dang blasted strays... */ -if (screen != console) { -sx = VSIwn; -syslog(0, "unknown csi : 0x%x\n", *c); -VSvalids(sx); -} - goto ShortCut; /* BYU 2.4.12 */ - } /* switch */ + escflg = esc_decl; + break; + default: +// VSprintf( "unknown csi : 0x%x\n", *c ); + goto ShortCut; + } /* switch */ c++; ctr--; } /* while */ - while ( escflg == 3 && ctr > 0 ) { + while ( escflg == esc_decl && ctr > 0 ) { /* "#" handling */ short lattrib = -1; switch (*c) { case 0x08: - VSIw->x--; - if (VSIw->x < 0) - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; break; - case '3': /* Double Height Line (DECDHL) Top Half */ - /* applies to the whole line */ - lattrib = 1; + case '3': // Double Height Line (DECDHL) Top Half - applies to the whole line + lattrib = kVSdecdhlt; break; - case '4': /* Double Height Line (DECDHL) Bottom Half */ - /* applies to the whole line */ - lattrib = 2; + case '4': // Double Height Line (DECDHL) Bottom Half - applies to the whole line + lattrib = kVSdecdhlb; break; - case '5': /* Single-Width Line (DECSWL) */ + case '5': // Single-Width Line (DECSWL) - applies to the whole line lattrib = 0; break; - case '6': /* Double-Width Line (DECDWL) */ - lattrib = 4; + case '6': // Double-Width Line (DECDWL) - applies to the whole line + // unsupported yet... + lattrib = kVSdecdhlt | kVSdecdhlb; break; - case '8': /* alignment display */ + case '8': // alignment display VTalign(); goto ShortCut; default: goto ShortCut; } /* switch */ if ( lattrib != -1 ) { - VSIw->lattrib = lattrib; - if (VSIw->oldScrollback) { - VSIw->attrst[VSIw->y]->lattr = lattrib; - } else { - VSIw->linest[VSIw->y]->lattr = lattrib; - } - /* refresh line with new width */ + VSIw->lattrib &= ~(kVSdecdhlt | kVSdecdhlb); + VSIw->lattrib |= lattrib; + VSIw->linest[VSIw->y]->lattr = VSIw->lattrib; + // refresh line with new width VSredrawLine(VSIwn); goto ShortCut; } @@ -1082,103 +1341,278 @@ VSvalids(sx); ctr--; } /* while */ - while ( escflg == 4 && ctr > 0 ) { - /* "(" handling (selection of G0 character set) */ + while ( escflg == esc_descl && ctr > 0 ) { + /* '"' handling */ + short lattrib = -1; switch (*c) { case 0x08: - VSIw->x--; - if (VSIw->x < 0) - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; break; - case 'A': /* UK */ - case 'B': /* US */ - case '1': /* "soft" */ - VSIw->G0 = 0; - if (!VSIw->charset) - VSIw->attrib = VSnotgraph(VSIw->attrib); - goto ShortCut; /* BYU 2.4.12 */ - case '0': /* DEC special graphics */ - case '2': /* "soft" */ - VSIw->G0 = 1; - if (!VSIw->charset) - VSIw->attrib = VSgraph(VSIw->attrib); - goto ShortCut; /* BYU 2.4.12 */ + case 'p': + /* set the compatibility level of the terminal */ + if ( VSIw->parms[0] == 61 ) { + // Set terminal for level 1 compatibility (VT100 mode) + VSIw->vtemulation = 0; + } else if ( VSIw->parms[0] == 62 ) { + if ( VSIw->parms[1] == -1 || VSIw->parms[1] == 0 || VSIw->parms[1] == 2 ) { + // Set terminal for level 2 compatibility (VT200 mode, 8-bit controls). + VSIw->vtemulation = 1; + VSIw->vteightbits = 1; + } else if ( VSIw->parms[1] == 1 ) { + // Set terminal for level 2 compatibility (VT200 mode, 7-bit controls). + VSIw->vtemulation = 1; + VSIw->vteightbits = 0; + } + } + goto ShortCut; default: - goto ShortCut; /* BYU 2.4.12 */ + goto ShortCut; } /* switch */ c++; ctr--; } /* while */ - - while ( escflg == 5 && ctr > 0 ) { + + while ( escflg == esc_G0 && ctr > 0 ) { + /* "(" handling (selection of G0 character set) single byte */ + switch (*c) { + case 0x08: + if (VSIw->x > 0) + --VSIw->x; + break; + case ' ': + case '@': + goto ShortCut; + case 'A': /* UK */ // FIXME: should we use the same translation as ASCII ? + case 'B': /* US - ASCII */ + case '1': /* "soft" */ + VSIw->G0 = 0; + if (!VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + if (tw) + switchintranslation(tw, kTRJIS, kASCII); + goto ShortCut; + case '0': /* DEC special graphics */ + case '2': /* "soft" */ + VSIw->G0 = 1; + if (!VSIw->charset) { + VSIw->attrib = VSgraph(VSIw->attrib); + } + goto ShortCut; + case 'J': /* JIS X 0201-Roman */ + // The "Roman" character set of JIS X 0201 [JISX0201] is identical to + // ASCII except for backslash () and tilde (~). The backslash is + // replaced by the Yen sign, and the tilde is replaced by overline. This + // set is Japan's national variant of ISO 646 [ISO646]. + if (tw) + switchintranslation(tw, kTRJIS, kJISX0201_1976); + goto ShortCut; + case 'I': /* Not Std ISO-2022-JP */ + if (tw) + switchintranslation(tw, kTRJIS, kJISX0201_1976Kana); + goto ShortCut; + default: + goto ShortCut; + } /* switch */ + c++; + ctr--; + } /* while */ + + while ( escflg == esc_G1 && ctr > 0 ) { /* ")" handling (selection of G1 character set) */ switch (*c) { case 0x08: - VSIw->x--; - if (VSIw->x < 0) - VSIw->x = 0; + if (VSIw->x > 0) + --VSIw->x; break; case 'A': /* UK */ case 'B': /* US */ case '1': /* "soft" */ VSIw->G1 = 0; - if (VSIw->charset) + if (VSIw->charset) { VSIw->attrib = VSnotgraph(VSIw->attrib); - goto ShortCut; /* BYU 2.4.12 */ + } + goto ShortCut; case '0': /* DEC special graphics */ case '2': /* "soft" */ VSIw->G1 = 1; - if (VSIw->charset) + if (VSIw->charset) { VSIw->attrib = VSgraph(VSIw->attrib); - goto ShortCut; /* BYU 2.4.12 */ + } + goto ShortCut; default: - goto ShortCut; /* BYU 2.4.12 */ - } /* switch */ + goto ShortCut; + } /* switch */ + c++; + ctr--; + } /* while */ + + while ( escflg == esc_G2 && ctr > 0 ) { + /* "*" handling (selection of G2 character set) */ + switch (*c) { + case 0x08: + if (VSIw->x > 0) + --VSIw->x; + break; + default: + // FIXME... + goto ShortCut; + } + c++; + ctr--; + } /* while */ + + while ( escflg == esc_G3 && ctr > 0 ) { + /* "+" handling (selection of G3 character set) */ + switch (*c) { + case 0x08: + if (VSIw->x > 0) + --VSIw->x; + break; + default: + // FIXME... + goto ShortCut; + } + c++; + ctr--; + } /* while */ + + while ( escflg == esc_G0j && ctr > 0 ) { + /* "$" handling (selection of G0 character set) multibytes */ + switch (*c) { + case 0x08: + if (VSIw->x > 0) + --VSIw->x; + break; + + case '@': /* JIS X 0208-1978 */ + // The JIS X 0208 [JISX0208] character sets consist of Kanji, Hiragana, + // Katakana and some other symbols and characters. Each character takes + // up two bytes. + if ( escflags == 0 ) { + /* set G0 character set to this one... */ + VSIw->G0 = 0; + if (!VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + if (tw) + switchintranslation(tw, kTRJIS, kJISX0208_1978); + } + goto ShortCut; + + case 'B': /* JIS X 0208-1983 */ + if ( escflags == 0 ) { + /* set G0 character set to this one... */ + VSIw->G0 = 0; + if (!VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + if (tw) + switchintranslation(tw, kTRJIS, kJISX0208_1983); + //switchintranslation(tw, JISX0208_83, 0); + } + goto ShortCut; + + case 'A': /* GB2312-1980 */ + if ( escflags == 0 ) { + /* set G0 character set to this one... */ + VSIw->G0 = 0; + if (!VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + // FIXME + //if (tw) + //switchintranslation(tw, ISO2022CN, kxxxxxxxxxxx); + } + goto ShortCut; + + case '(': + if ( escflags == 0 ) { + escflags = 1; + break; + } + goto ShortCut; + + case 'C': /* KSC5601-1987 */ + goto ShortCut; + + case 'D': /* JIS X 0212-1990 */ + if ( escflags == 1 ) { + /* set G0 character set to this one... */ + VSIw->G0 = 0; + if (!VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + if (tw) + switchintranslation(tw, kTRJIS, kJISX0212_1990); + //switchintranslation(tw, JISX0212, 0); + } + goto ShortCut; + + default: + goto ShortCut; + } /* switch */ + c++; + ctr--; + } /* while */ + + while ( escflg == esc_G2j && ctr > 0 ) { + /* "." handling (selection of G2 character set) */ + switch (*c) { + case 0x08: + if (VSIw->x > 0) + --VSIw->x; + break; + case 'A': /* ISO8859-1 */ + case 'F': /* ISO8859-7(Greek) */ + // FIXME... + //VSIw->G2 = 0; + if (VSIw->charset) { + VSIw->attrib = VSnotgraph(VSIw->attrib); + } + goto ShortCut; + default: + goto ShortCut; + } c++; ctr--; } /* while */ // Handle XTerm rename functions, code contributed by Bill Rausch // Modified by JMB to handle ESC]2; case as well. - if ( escflg >= 6 && escflg < 9 && ctr > 0 ) { - static char *tmp; + if ( escflg == esc_XTerm && ctr > 0 ) { static Str255 newname; - - if ( escflg == 6 ) { + if ( escflags == 0 ) { if ( *c == '0' || *c == '2') { - escflg++; + escflags = 1; c++; ctr--; } else if ( *c == 'P') { /* palette escape sequence */ - escflg = 9; + escflags = 3; c++; ctr--; } else if ( *c == 'R') { /* reset palette */ - // FIXME: RESTORE PREVIOUS SAVED COLORS - //reset_palette(currcons); + RSresetcolors( VSIwn ); goto ShortCut; } else { goto ShortCut; } } - - if ( escflg == 7 && ctr > 0 && *c == ';' ) { - ctr--; + if ( escflags == 1 && ctr > 0 && *c == ';' ) { c++; - escflg++; + ctr--; + escflags = 2; newname[0] = 0; - tmp = (char *)&newname[1]; } - - while ( escflg == 8 && ctr > 0 && *c != 7 && *c != 033) { + while ( escflags == 2 && ctr > 0 && *c != 7 && *c != 033) { if (*newname < 255) { - *tmp++ = *c; - (*newname)++; + newname[++(*newname)] = *c; } c++; ctr--; } - if ( escflg == 8 && ctr > 0 && (*c == 7 || *c == 033) ) { + if ( escflags == 2 && ctr > 0 && (*c == 7 || *c == 033) ) { set_new_window_name( newname, RSgetwindow(VSIwn) ); if (*c != 07) { /* This will be undone in the ShortCut below. */ @@ -1187,45 +1621,34 @@ VSvalids(sx); } goto ShortCut; } - } /* if */ - -/* Linux */ - if ( escflg == 9 && ctr > 0 ) { - if ( (*c>='0'&&*c<='9') || (*c>='A'&&*c<='F') || (*c>='a'&&*c<='f') ) { - VSIw->parms[VSIw->parmptr++] = (*c>'9' ? (*c&0xDF)-'A'+10 : *c-'0'); - if ( VSIw->parmptr == 7 ) { - // FIXME: MUST SAVE PREVIOUS COLORS FOR RESTORE - RGBColor newColor; - newColor.red = 16 * VSIw->parms[1] + VSIw->parms[2]; - newColor.green = 16 * VSIw->parms[3] + VSIw->parms[4]; - newColor.blue = 16 * VSIw->parms[5] + VSIw->parms[6]; - -if (screen != console) { -sx = VSIwn; -syslog(0, "palette escape sequence\n"); -VSvalids(sx); -} - - RSsetcolors(VSIwn, VSIw->parms[0], &newColor); - goto ShortCut; - } - } else { - goto ShortCut; - } + if ( escflags == 3 && ctr > 0 ) { + if ( (*c>='0'&&*c<='9') || (*c>='A'&&*c<='F') || (*c>='a'&&*c<='f') ) { + VSIw->parms[VSIw->parmptr++] = (*c>'9' ? (*c&0xDF)-'A'+10 : *c-'0'); + if ( VSIw->parmptr == 7 ) { + RGBColor newColor; + newColor.red = 16 * VSIw->parms[1] + VSIw->parms[2]; + newColor.green = 16 * VSIw->parms[3] + VSIw->parms[4]; + newColor.blue = 16 * VSIw->parms[5] + VSIw->parms[6]; + RSsetcolors(VSIwn, VSIw->parms[0] + 4, &newColor); + goto ShortCut; + } + } else { + goto ShortCut; + } + } } -/* Linux */ - - if ( escflg > 2 && ctr > 0 ) { + + if ( escflg > esc_csi && ctr > 0 ) { ShortCut: /* BYU 2.4.12 - well, sacrificing style for speed */ if ( VSIw->possibleForce && *c != 'H' ) //CCP better forcesave VSIw->possibleForce = FALSE; escflg = 0; + escflags = 0; c++; ctr--; } } /* while (ctr > 0) */ VSIw->escflg = escflg; - + VSIw->escflags = escflags; } /* VSem */ - diff --git a/macssh/source/ssh/PasswordDialog.c b/macssh/source/ssh/PasswordDialog.c index 50fc980..af1dbab 100755 --- a/macssh/source/ssh/PasswordDialog.c +++ b/macssh/source/ssh/PasswordDialog.c @@ -41,6 +41,8 @@ extern WindRec *ssh2_window(); extern void setctxprompt(const char *prompt); extern char *getctxprompt(); +extern pthread_key_t ssh2threadkey; + extern TelInfoRec *TelInfo; extern Boolean gAEavail; @@ -390,7 +392,7 @@ static void GetLabelFromPrompt(const char *prompt, StringPtr host, StringPtr use memcpy( host, p, *p + 1 ); p = wind->sshdata.login; memcpy( user, p, *p + 1 ); - } else { + } else if (pthread_getspecific(ssh2threadkey)) { /* use key label as both host name and user name */ int l = strlen(prompt); *host = 4 + l; @@ -398,6 +400,13 @@ static void GetLabelFromPrompt(const char *prompt, StringPtr host, StringPtr use memcpy(host + 5, prompt, l); *user = l; memcpy(user + 1, prompt, l); + } else { + int l = strlen(prompt); + *host = 6 + l; + memcpy(host + 1, "Macro ", 6); + memcpy(host + 7, prompt, l); + *user = l; + memcpy(user + 1, prompt, l); } } @@ -460,10 +469,14 @@ static void AddPassToKeychain(const char *prompt, StringPtr password) *password, password + 1, &theItem); if (theStatus == noErr) { unsigned char *theDescriptionText; - if (strstr(prompt, "assword for")) - theDescriptionText = "\pMacSSH password"; - else - theDescriptionText = "\pMacSSH passphrase"; + if (pthread_getspecific(ssh2threadkey)) { + if (strstr(prompt, "assword for")) + theDescriptionText = "\pMacSSH password"; + else + theDescriptionText = "\pMacSSH passphrase"; + } else { + theDescriptionText = "\pMacSSH macro password"; + } theAttribute.tag = kDescriptionKCItemAttr; theAttribute.length = *theDescriptionText; theAttribute.data = theDescriptionText + 1; @@ -510,11 +523,14 @@ Boolean SSH2PasswordDialog(const char *prompt, StringPtr password) Boolean addKey = false; ModalFilterUPP internalBufferFilterUPP; ConstStringPtr keyPrompt = "\pEnter passphrase for private key "; + ConstStringPtr macroPrompt = "\pEnter password for macro "; WindRec *wind; #if GENERATINGCFM - if ( strcmp(prompt, getctxprompt()) && GetPassFromKeychain(prompt, password) ) { - setctxprompt(prompt); + if ( (!pthread_getspecific(ssh2threadkey) || strcmp(prompt, getctxprompt())) + && GetPassFromKeychain(prompt, password) ) { + if (pthread_getspecific(ssh2threadkey)) + setctxprompt(prompt); return true; } #endif @@ -536,10 +552,14 @@ Boolean SSH2PasswordDialog(const char *prompt, StringPtr password) if ( wind && strstr(prompt, "assword for") ) { pprompt[0] = strlen(prompt); memcpy(pprompt + 1, prompt, pprompt[0]); - } else { + } else if (pthread_getspecific(ssh2threadkey)) { memcpy(pprompt, keyPrompt, keyPrompt[0] + 1); memcpy(pprompt + pprompt[0] + 1, prompt, strlen(prompt)); pprompt[0] += strlen(prompt); + } else { + memcpy(pprompt, macroPrompt, macroPrompt[0] + 1); + memcpy(pprompt + pprompt[0] + 1, prompt, strlen(prompt)); + pprompt[0] += strlen(prompt); } GetDialogItem(dlog, 5, &itemType, &itemHandle, &itemRect); SetDialogItemText(itemHandle, pprompt); diff --git a/macssh/source/ssh/console.stubs.c b/macssh/source/ssh/console.stubs.c index 401a1d1..fab82e3 100755 --- a/macssh/source/ssh/console.stubs.c +++ b/macssh/source/ssh/console.stubs.c @@ -404,7 +404,7 @@ int WriteCharsToTTY(int id, void *ctx, char *buffer, int n) written = n; } /* - syslog( 0, "write\n"); + syslog( 0, "from ssh\n"); dumpln(0, 0, buffer, written); */ return written; @@ -456,7 +456,7 @@ int ReadCharsFromTTY(int id, void *ctx, char *buffer, int n) buffer[0] = EOF; } /* - syslog( 0, "read\n"); + syslog( 0, "to ssh\n"); dumpln(0, 0, buffer, len); */ return len; diff --git a/macssh/source/tek/vgtek.c b/macssh/source/tek/vgtek.c index dee6551..d9cf685 100755 --- a/macssh/source/tek/vgtek.c +++ b/macssh/source/tek/vgtek.c @@ -269,7 +269,15 @@ short drawc(short vw, short c) /* character to draw */ if ((c < 32) || (c > 137)) return(0); // Is this return value correct? c -= 32; - pstroke = (VGwin[vw]->TEKtype) ? VGTEKfont[c] : VGfont[c]; + + /* bounds checking to avoid crash... */ + //pstroke = (VGwin[vw]->TEKtype) ? VGTEKfont[c] : VGfont[c]; + if (VGwin[vw]->TEKtype) { + pstroke = (c < (sizeof(VGTEKfont) / sizeof(VGTEKfont[0]))) ? VGTEKfont[c] : ""; + } else { + pstroke = (c < (sizeof(VGfont) / sizeof(VGfont[0]))) ? VGfont[c] : ""; + } + while (*pstroke) { strokex = x; @@ -383,6 +391,10 @@ short VGnewwin short vw = 0; short theScrn; + theScrn = findbyVS(theVS); + if (theScrn < 0) + return(-1); + while ((vw < MAXVG) && (VGwin[vw] != nil)) vw++; if (vw == MAXVG) return(-1); @@ -403,7 +415,6 @@ short VGnewwin VGwin[vw]->RGdevice = device; VGwin[vw]->RGnum = (*RG[device].newwin)(); - theScrn = findbyVS(theVS); VGwin[vw]->TEKtype = screens[theScrn].tektype; // 0 = 4014, 1 = 4105 if (VGwin[vw]->RGnum < 0) @@ -518,6 +529,7 @@ void VGdumpstore(short vw, short (*func )(short)) */ void VGdraw(short vw, char c) /* the latest input char */ { + short sn; char cmd; char value; char goagain; /* true means go thru the function a second time */ @@ -528,10 +540,14 @@ void VGdraw(short vw, char c) /* the latest input char */ if (VGcheck(vw)) { return; - } + } vp = VGwin[vw]; /* BYU */ + sn = findbyVS(vp->theVS); + if (sn < 0) + return; + temp[0] = c; temp[1] = (char) 0; @@ -808,7 +824,7 @@ void VGdraw(short vw, char c) /* the latest input char */ state[vw] = DONE; break; case 12: /* form feed = clrscr */ - if (screens[findbyVS(vp->theVS)].tekclear) { + if (sn >= 0 && screens[sn].tekclear) { VGpage(vw); VGclrstor(vw); } diff --git a/macssh/source/telnet.rsrc b/macssh/source/telnet.rsrc index c926b99..3b4c677 100755 Binary files a/macssh/source/telnet.rsrc and b/macssh/source/telnet.rsrc differ diff --git a/macssh/www/download/ChangeLog b/macssh/www/download/ChangeLog index b271d4a..9bf968b 100755 Binary files a/macssh/www/download/ChangeLog and b/macssh/www/download/ChangeLog differ