home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
ckc095.tar.gz
/
ckc095.tar
/
ckmco2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-22
|
57KB
|
2,070 lines
/*
* FILE ckmco2.c
*
* Module of mackermit: contains code for dealing with the Mac side
* of terminal emulation.
*/
#include "ckcdeb.h"
#define __SEG__ ckmcon
#include <quickdraw.h>
#include <controls.h>
#include <devices.h>
#include <serial.h>
#include <files.h>
#include <events.h>
#include <windows.h>
#include <dialogs.h>
#include <menus.h>
#include <toolutils.h>
#include <osutils.h>
#include <resources.h>
#include <ctype.h>
#include <Script.h>
#include <Memory.h>
#include "ckmdef.h"
#include "ckmasm.h" /* Assembler code */
#include "ckmres.h" /* kermit resources */
#include "ckmcon.h" /* defines, etc. for terminal emulator */
extern WindowPtr terminalWindow; /* the terminal window */
Rect ScreenRect;
ControlHandle t_vscroll;
/*
* (UoR) don't need scrollrect any more (use scroll_up and scroll_down), use
* ScreenRect for mouse check
*/
/* Screen book keeping variables */
extern int screensize, /* variable number of lines on screen */
topmargin, /* Edges of adjustable window */
bottommargin,
graphicsinset[4], /* (UoR) current character sets */
Gl_set, /* (UoR) current chosen set */
Gr_set, /* (PWP) current chosen upper set */
screeninvert, /* (UoR) inverted screen flag */
insert,
newline, /* (UoR) linefeed mode by default */
autowrap, /* Autowrap on by default */
relorigin, /* (UoR) relative origin off */
autorepeat, /* (UoR) auto repeat flag */
appl_mode, /* (PWP) application mode */
curskey_mode, /* (PWP) cursor key application mode */
smoothscroll, /* do smooth scrolling (PWP: or not) */
transparent, /* do not show control characters */
blockcursor, /* show block or underline cursor */
cursor_shown, /* (PWP) show the cursor */
mouse_arrows, /* mouse down in screen does arrow keys */
visible_bell, /* true if we do blink instead of bell */
eightbit_disp, /* do 8 bit wide to the screen */
blinkcursor; /* true if we make the cursor blink */
extern ucharptr *scr, *scr_attrs; /* virtual screen pointer */
extern ucharptr real_scr[MAX_SCREENSIZE]; /* The real screen, including scrollback */
extern ucharptr real_attrs[MAX_SCREENSIZE]; /* the attributes of each character */
int display_topline; /* top line actually displayed */
int display_totlines; /* number of real lines in screen + scrollback */
extern int curlin, curcol; /* Cursor position */
extern int savcol, savlin; /* Cursor save variables */
extern int savsty, savfnt, savgrf, savmod, savset[2]; /* (UoR) cursor save
* variables */
extern int savund; /* PWP for saved underlining */
extern int scrtop, scrbot; /* Absolute scrolling region bounds */
int textstyle = 0; /* (UoR) current style */
int current_style = 0;
int draw_sing_chars = FALSE;
int oldlin = -1;
int oldcol = 0; /* (UoR) for last mouse position */
/* (PWP) variables for controling the selected text */
int from_lin = -1;
int from_col = 0;
int to_lin;
int to_col;
Boolean have_selection = 0;
#define ABS(a) ((a) < 0 ? -(a) : (a))
int cursor_invert = FALSE, /* (UoR) for flashing cursor */
cur_drawn = FALSE;
long last_flash = 0;
char **myclip_h; /* internal clipboard */
int myclip_size; /* size of above */
static int mousecurs_drawn = FALSE; /* (PWP) is the mouse cursor drawn? */
static int in_front = 0; /* PWP: true when we are the front window */
extern Boolean usingRAMdriver,
have_128roms; /* true if we are a Plus or better */
RgnHandle dummyRgn; /* dummy region for ScrollRect */
/* Initialized in mac_init */
long MyCaretTime; /* (UoR) ticks between flashes */
extern Cursor *textcurs, *normcurs, *watchcurs; /* mouse cursor shapes */
extern int to_printer; /*JAO*/
extern int to_screen; /*JAO*/
extern int printer_is_on_line_num; /*JAO*/
extern Handle hPrintBuffer; /*JAO*/
extern long lPrintBufferSize; /*JAO*/
extern long lPrintBufferChars; /*JAO*/
extern long lPrintBufferAt; /*JAO*/
extern DialogPtr bufferingDialog; /*JAO*/
extern DialogPtr overflowingDialog; /*JAO*/
extern MenuHandle menus[]; /* handle on our menus */ /*JAO*/
/* keyboard handling stuff */
extern char keytable[512]; /* the key redefintion flag table */
extern modrec modtable[NUMOFMODS]; /* modifier records */
#define myKeyCodeMask 0x7F00
#define keyModifierMask 0x1F00
#define ctrlCodeMask 0x1F
#define metaOrBits 0x80
#define UnmodMask 0x80 /* action bits */
#define CapsMask 0x40
#define CtrlMask 0x20
#define MetaMask 0x10
Boolean have_scriptmgr = FALSE;
long old_KCHR, old_SICN; /* pointers to current system key script, icon */
long cur_KCHR;
/***** forward decls ********/
void cursor_draw(), cursor_erase();
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* keyboard event handling routines */
/****************************************************************************/
InitKeyStuff()
{
have_scriptmgr = NGetTrapAddress(num_UnknownTrap, 1) !=
NGetTrapAddress(num_ScriptTrap, 1);
if (have_scriptmgr) {
old_KCHR = GetScript( smRoman, smScriptKeys);
old_SICN = GetScript( smRoman, smScriptIcon);
}
cur_KCHR = old_KCHR;
UpdateOptKey(1); /* get things set right initially */
}
UpdateOptKey(enable)
int enable;
{
int i;
int futzit = 0;
if (enable) {
for (i = 0; i < NUMOFMODS; i++) {
/* shift what to look for into high byte */
if ((modtable[i].modbits) & (optionKey >> 4)) /* if Option is selected */
futzit = 1;
}
} else { /* allways turn off when disabling window */
futzit = 0;
}
(void) FutzOptKey(futzit);
}
FutzOptKey(enable)
int enable;
{
int err;
if (have_scriptmgr) { /* if we are system 4.1 or later... */
if (enable) { /* no deadkeys */
if (cur_KCHR != old_KCHR)
return (1); /* we are allready fine */
if (GetEnvirons(smKeyScript) == smRoman) { /* only if in roman script */
/* set the key map */
err = SetScript (smRoman, smScriptKeys, NODEAD_KCHR);
if (err != noErr) {
printerr ("Trouble setting custom keymap (KCHR):", err);
return (0);
}
/* set the icon */
err = SetScript (smRoman, smScriptIcon, NODEAD_SICN);
if (err != noErr) {
printerr ("Trouble setting custom keymap icon (SICN):", err);
return (0);
}
KeyScript (smRoman);
cur_KCHR = NODEAD_KCHR;
return (1); /* success! */
} else {
printerr("Can't disable Option key -- you have a non-US keyboard",0);
return (0);
}
} else { /* back to normal */
if (cur_KCHR == old_KCHR)
return (1); /* we are allready fine */
/* set the key map */
err = SetScript (smRoman, smScriptKeys, old_KCHR);
if (err != noErr) {
printerr ("Trouble resetting default keymap (KCHR):", err);
return (0);
}
/* set the icon */
err = SetScript (smRoman, smScriptIcon, old_SICN);
if (err != noErr) {
printerr ("Trouble resetting default keymap icon (SICN):", err);
return (0);
}
KeyScript (smRoman);
cur_KCHR = old_KCHR;
return (1); /* success! */
}
} else {
/* do something or other to do the old way */
/* printerr("Kermit can't disable Option on old systems",0); */
}
return (0);
}
/****************************************************************************/
/* return the ASCII character which is generated by the keyCode specified */
/* with no modifiers pressed */
/****************************************************************************/
unsigned char
DeModifyChar (keyCode, modifiers)
long keyCode, modifiers;
{
long c;
long mystate, retval;
short s_keycode;
Handle kchr_h;
THz curZone;
#ifdef COMMENT
ProcHandle KeyTrans;
if (keyCode > 64)
KeyTrans = (ProcHandle) 0x2A2; /* keypad decode */
else
KeyTrans = (ProcHandle) 0x29E; /* keyboard decode */
SaveRegs (); /* save all registers */
AllRegs ();
/* setup regs for procedure call */
/* loadD1 ((long) modifiers); */ /* no modifiers */
loadD1 ((long) 0); /* no modifiers */
loadD2 ((long) keyCode); /* set the keycode */
loadA0 (*KeyTrans); /* load the content of Key1Trans to A0 */
/* run the translation routine */
execute (); /* call the Key1Trans procedure */
/* move the result from reg D0 to c */
loadA0 (&c); /* set destination address */
pushD0 (); /* move register D0 to stack */
poptoA0 (); /* load the stacktop to (A0) */
RestoreRegs (); /* restore all registers */
AllRegs ();
#endif /* COMMENT */
if (have_scriptmgr) { /* if we are system 4.1 or later... */
mystate = 0;
kchr_h = GetResource('KCHR', cur_KCHR);
if (kchr_h == NIL) {
printerr("DeModifyChar: couldn't get KCHR address",0);
return(0);
}
LoadResource(kchr_h);
HLock(kchr_h);
s_keycode = (modifiers & 0xff00) | (keyCode & 0xff);
c = KeyTrans(*kchr_h, s_keycode, &mystate);
HUnlock(kchr_h);
curZone = GetZone(); /* as per John Norstad's (Disinfectant) */
SetZone(HandleZone(kchr_h)); /* "Toolbox Gotchas" */
ReleaseResource(kchr_h);
SetZone(curZone);
}
return (c);
} /* DeModifyChar */
unsigned char obuf[2] = {1, 0}; /* single char output buffer */
/****************************************************************************/
/* send a character to the line if it is in ASCII range. Do local echo if */
/* necessary */
/****************************************************************************/
OutputChar (c)
unsigned char c;
{
/*
* PWP: NO 7 bit masking!!! If we do this, then I can't use Emacs, and
* the European users will be VERY unhappy, 'cause they won't be able to
* send all of their characters.
*/
obuf[1] = c; /* store character */
writeps (obuf); /* and write it out */
if (duplex != 0) {
cursor_erase (); /* remove from screen */
printit ((char) c); /* Echo the char to the screen */
flushbuf (); /* flush the character */
cursor_draw (); /* put it back */
}
} /* OutputChar */
#ifdef COMMENT
/****************************************************************************/
/* Bittest returns the setting of an element in a Pascal PACKED ARRAY [0..n]
OF Boolean such as the KeyMap argument returned by GetKey
/****************************************************************************/
Boolean
bittest (bitmap, bitnum)
char bitmap[];
int bitnum;
{
return (0x01 & (bitmap[bitnum / 8] >> (bitnum % 8)));
} /* bittest */
/* PWP: or, as a macro, */
#define bittest(bitmap,bitnum) (0x01 & (bitmap[bitnum / 8] >> (bitnum % 8)))
#endif /* COMMENT */
/****************************************************************************/
/* Process a character received from the keyboard */
/****************************************************************************/
handle_char (evt)
EventRecord *evt;
{
short i;
short len;
short theCode;
short modCode;
short theModBits;
char flags;
char tmpstr[256];
unsigned char c;
/* (UoR) check for auto repeated keys */
if ((autorepeat == FALSE) && (evt->what == autoKey))
return;
ObscureCursor (); /* PWP: hide the cursor until next move */
modCode = evt->modifiers & keyModifierMask;
theCode = ((evt->message & myKeyCodeMask) >> 8) + (modCode >> 1);
/* check for a special code for this key */
if (BitTst (keytable, theCode)) {
GetMacro (theCode, &flags, tmpstr); /* get the macrostring */
if (flags) { /* check special flags */
switch (flags) {
case shortBreak:
sendbreak (5);
return;
case longBreak:
sendbreak (70);
return;
case leftArrowKey:
do_arrow (leftARROW);
return;
case rightArrowKey:
do_arrow (rightARROW);
return;
case upArrowKey:
do_arrow (UPARROW);
return;
case downArrowKey:
do_arrow (DOWNARROW);
return;
case keycomma:
case keyminus:
case keyperiod:
/* there is no keyslash */
case key0:
case key1:
case key2:
case key3:
case key4:
case key5:
case key6:
case key7:
case key8:
case key9:
do_keypad(flags - keycomma);
return;
case keypf1:
case keypf2:
case keypf3:
case keypf4:
do_pfkey(flags - keypf1);
return;
case keyenter:
do_keyenter();
return;
}
}
/* send key macro string */
/*
* PWP: note, we DON'T have to convert it to a Pascal string, 'cause
* the macros are now stored as Pascal strings
*/
writeps (tmpstr); /* send it to the line */
if (duplex != 0)
printps (tmpstr); /* echo it locally */
return;
}
for (i = 0; i < NUMOFMODS; i++) {
/* shift what to look for into high byte */
theModBits = modtable[i].modbits << 4;
len = strlen (modtable[i].prefix);
if ((theModBits || len) &&
((theModBits & modCode) == (theModBits & keyModifierMask))) {
/* send prefix if there is one */
if (len) {
/* PWP: these are saved as Pascal strings now */
BlockMove (modtable[i].prefix, tmpstr, (modtable[i].prefix[0] + 1));
writeps (tmpstr); /* send it to the line */
if (duplex != 0)
printps (tmpstr); /* echo it locally */
}
/*
* get the unmodified ASCII code if the unmodify action bit is
* active
*/
if (theModBits & UnmodMask)
c = DeModifyChar ((long) ((evt->message & myKeyCodeMask) >> 8),
(long) (modCode & shiftKey));
/* PWP: we pass through the shiftedness of this key */
else
c = evt->message & charCodeMask; /* otherwise get the
* standard char */
/* make an uppercase character if the caps action bit is active */
if ((theModBits & CapsMask) && islower (c))
c = _toupper (c);
/* make a control character if the control action bit is active */
if (theModBits & CtrlMask)
c &= ctrlCodeMask;
/* PWP: for Meta characters (yes, I use Emacs) */
if (theModBits & MetaMask)
c |= metaOrBits;
OutputChar (c);
return;
} /* if */
} /* for */
/* get the ASCII code and send it */
OutputChar (evt->message & charCodeMask);
} /* handle_char */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* general rectangle routines */
/****************************************************************************/
/****************************************************************************/
/*
* Routine makerect
*
* Make a rectangle in r starting on line lin and column col extending
* numlin lines and numcol characters.
*
*/
/****************************************************************************/
makerect (r, lin, col, numlin, numcol)
Rect *r;
int lin;
int col;
int numlin;
int numcol;
{
r->top = lin * LINEHEIGHT + TOPMARGIN;
r->left = col * CHARWIDTH + LEFTMARGIN;
r->bottom = r->top + numlin * LINEHEIGHT;
r->right = r->left + numcol * CHARWIDTH;
} /* makerect */
/* (PWP) do what makerect does, then invert the rect */
invertchars (lin, col, numlin, numcol)
int lin;
int col;
int numlin;
int numcol;
{
Rect r;
r.top = lin * LINEHEIGHT + TOPMARGIN;
r.left = col * CHARWIDTH + LEFTMARGIN;
r.bottom = r.top + numlin * LINEHEIGHT;
r.right = r.left + numcol * CHARWIDTH;
InvertRect (&r);
}
/* Make rect r (made by makerect()) into the right shape
for underlining */
makertou (r)
Rect *r;
{
r->top = r->bottom - 1;
}
/****************************************************************************/
/* Connect support routines */
/****************************************************************************/
consetup ()
{
PenMode (srcCopy); /* (PWP) was patXor */
flushio (); /* Get rid of pending characters */
init_term (); /* Set up some terminal variables */
TextFont (VT100FONT); /* (UoR) Set initial font to VT100 */
TextMode (srcXor); /* (UoR) use XOR mode (for inverse) */
TextFace (0); /* PWP: be safe. We allways stay like this */
clear_screen (); /* Clear the screen */
home_cursor (); /* Go to the upper left */
cursor_save (); /* Save this position */
cursor_draw (); /* (UoR) be sure to draw it */
} /* consetup */
void
term_reset ()
{
PenMode (srcCopy); /* (PWP) was patXor */
flushio (); /* Get rid of pending characters */
screen_to_bottom (); /* slide the visible region to active area */
graphicsinset[0] = ASCII_SET;
graphicsinset[1] = GRAF_SET;
norm_char();
Gl_set = 0;
Gr_set = 1;
textstyle = 0;
current_style = 0;
draw_sing_chars = 0;
screeninvert = FALSE; /* (UoR) inverted screen flag */
insert = FALSE;
newline = FALSE; /* (UoR) linefeed mode by default */
autowrap = TRUE; /* Autowrap on by default */
relorigin = FALSE; /* (UoR) relative origin off */
autorepeat = TRUE; /* (UoR) auto repeat flag */
appl_mode = FALSE; /* (PWP) keypad application mode */
curskey_mode = FALSE; /* (PWP) cursor key application mode */
smoothscroll = FALSE; /* do smooth scrolling (PWP: or not) */
transparent = TRUE; /* do not show control characters */
blockcursor = TRUE; /* show block or underline cursor */
cursor_shown = TRUE; /* (PWP) show the cursor */
mouse_arrows = FALSE; /* mouse down in screen does arrow keys */
visible_bell = FALSE; /* true if we do blink instead of bell */
eightbit_disp = FALSE; /* default to 7 bits */
blinkcursor = TRUE; /* true if we make the cursor blink */
have_selection = FALSE; /* (PWP) we have no selected text */
TextFont (VT100FONT); /* (UoR) Set initial font to VT100 */
TextMode (srcXor); /* (UoR) use XOR mode (for inverse) */
TextFace (0); /* PWP: be safe. We allways stay like this */
clear_screen (); /* Clear the screen */
home_cursor (); /* Go to the upper left */
cursor_save (); /* Save this position */
cursor_draw (); /* (UoR) be sure to draw it */
} /* consetup */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/*
* Flushio:
* Initialize some communications constants, and clear screen and
* character buffers. */
/****************************************************************************/
flushio ()
{
int err;
err = KillIO (innum);
if (err)
printerr ("Bad input clear", err);
err = KillIO (outnum);
if (err)
printerr ("Bad ouput clear", err);
} /* flushio */
/****************************************************************************/
/* sendbreak - sends a break across the communictions line.
*
* The argument is in units of approximately 0.05 seconds (or 50
* milliseconds). To send a break of duration 250 milliseconds the
* argument would be 5; a break of duration 3.5 seconds would be (umm,
* lets see now) 70.
*
*/
/****************************************************************************/
sendbreak (msunit)
int msunit;
{
long finalticks;
/* delay wants 1/60th units. We have 3/60 (50 ms.) units, convert */
msunit = msunit * 3;
SerSetBrk (outnum); /* start breaking */
Delay ((long) msunit, &finalticks); /* delay */
SerClrBrk (outnum); /* stop breaking */
} /* sendbreak */
/****************************************************************************/
/* toggledtr - Turn DTR off, wait a bit, turn it back on.
*
* the argument is in the same units as sendbreak (see above).
*/
/****************************************************************************/
toggle_dtr (msunit)
int msunit;
{
long finalticks;
CntrlParam cpb;
int err;
if (usingRAMdriver) {
/* delay wants 1/60th units. We have 3/60 (50 ms.) units, convert */
msunit = msunit * 3;
cpb.csCode = 18; /* lower DTR */
cpb.ioCRefNum = outnum;
err = PBControl (&cpb, FALSE);
if (err != noErr)
printerr ("toggle_dtr() trouble lowering DTR: ", err);
Delay ((long) msunit, &finalticks); /* delay */
cpb.csCode = 17; /* raise DTR */
cpb.ioCRefNum = outnum;
err = PBControl (&cpb, FALSE);
if (err != noErr)
printerr ("toggle_dtr() trouble raising DTR: ", err);
}
} /* sendbreak */
/****************************************************************************/
/* do_xon - xon the output port and send an xon (control-Q) character */
/****************************************************************************/
do_xon ()
{
CntrlParam cpb;
int err;
if (usingRAMdriver) {
cpb.csCode = 22; /* clear XOFF for my output */
cpb.ioCRefNum = outnum;
err = PBControl (&cpb, FALSE);
if (err != noErr)
printerr ("do_xon() trouble unblocking output port: ", err);
cpb.csCode = 24; /* unconditionally send XON */
cpb.ioCRefNum = outnum;
err = PBControl (&cpb, FALSE);
if (err != noErr)
printerr ("do_xon() trouble sending XON: ", err);
} else {
OutputChar ('\021'); /* XON */
}
} /* sendbreak */
/*************************************************/
/* cursor drawing stuff */
/*************************************************/
Boolean
cursor_rect (line, col, r)
Rect *r;
{
if (line - display_topline >= screensize) /* if cursor not on screen */
return FALSE;
makerect (r, line - display_topline, col, 1, 1); /* Get character rectangle */
if (!blockcursor)
r->top = r->bottom - 1;
return TRUE;
} /* cursor_rect */
void
cursor_draw ()
{
/* Line(CHARWIDTH,0);*//* Draw cursor */
Rect r;
/* if (cur_drawn) return; */
if (!cursor_shown) return; /* (PWP) not if we are hiding cursor */
if (!cursor_invert) {
if (cursor_rect (curlin, curcol, &r)) {
if (in_front) {
InvertRect (&r);
} else {
PenMode (patXor);
FrameRect (&r);
PenMode (patCopy);
}
}
}
if ((oldlin >= 0) && (!mousecurs_drawn)) { /* (UoR) replace mouse cursor */
makerect (&r, oldlin, oldcol, 1, 1);
PenMode (patXor);
FrameRect (&r);
PenMode (patCopy);
mousecurs_drawn = TRUE;
}
cursor_invert = TRUE;
cur_drawn = TRUE;
} /* cursor_draw */
void
cursor_erase ()
{
/* Line(-CHARWIDTH,0);*//* Erase cursor */
Rect r;
/* if (!cur_drawn) return; */
if (cursor_invert) {
if (cursor_rect (curlin, curcol, &r)) {
if (in_front) {
InvertRect (&r);
} else {
PenMode (patXor);
FrameRect (&r);
PenMode (patCopy);
}
}
}
if ((oldlin >= 0) && (mousecurs_drawn)) { /* (UoR) remove mouse cursor */
makerect (&r, oldlin, oldcol, 1, 1);
PenMode (patXor);
FrameRect (&r);
PenMode (patCopy);
mousecurs_drawn = FALSE;
}
cursor_invert = FALSE;
cur_drawn = FALSE;
} /* cursor_erase */
void
flash_cursor (theWindow)
WindowPtr theWindow;
{
register long tc;
Rect r;
if (theWindow == (WindowPtr) NIL) {
last_flash = TickCount ();
return;
}
tc = TickCount ();
if (((tc - last_flash) > MyCaretTime) ||
(tc - last_flash) < 0L) {
last_flash = tc;
if (cur_drawn) {
if (cursor_rect (curlin, curcol, &r)) {
if (blinkcursor && in_front) { /* PWP: only blink if asked for */
InvertRect (&r);
cursor_invert = !cursor_invert;
} else if (!cursor_invert) { /* make sure that the cursor
* shows up */
if (in_front) {
InvertRect (&r);
} else {
PenMode (patXor);
FrameRect (&r);
PenMode (patCopy);
}
cursor_invert = TRUE;
}
}
}
}
} /* flash_cursor */
/****************************************************************************/
/* PWP -- like waitasec(), but don't get any characters. Used for
visable bell. */
/****************************************************************************/
waitnoinput ()
{
long ticks = 2, end_time;
Delay (ticks, &end_time); /* pause for 1/30th second */
} /* waitnoinput */
/****************************************************************************/
/* (UoR) get any characters, and pause for a while */
/****************************************************************************/
waitasec ()
{
waitnoinput();
inpchars ();
} /* waitasec */
/****************************************************************************/
/* updateCursor -- taken from NCSA Telnet for the Macintosh, v 2.2 */
/****************************************************************************/
void
updateCursor(force, myfrontwindow)
int force;
WindowPeek myfrontwindow;
{
static Point lastPoint;
static int optwasdown = 0;
static Cursor *lastCursor=0L; /* what we set the cursor to last */
Cursor *thisCursor;
int optDown;
char allthekeys[16]; /* Someplace to put the keymap */
int newlin, newcol;
Point MousePt;
Rect r;
/* SetPort(myfrontwindow); */
GetMouse(&MousePt);
if ( (!force) && (MousePt == lastPoint) && (optDown == optwasdown))
return;
if (force)
lastCursor=0L;
if (protocmd != 0) { /* if doing a transfer */
thisCursor = watchcurs;
} else if (((myfrontwindow == terminalWindow) ||
((myfrontwindow == NIL) &&
(FrontWindow() == terminalWindow))) &&
PtInRect (&MousePt, &ScreenRect)) {
GetKeys(allthekeys);
optDown = allthekeys[7] & 4; /* should be symbolic */
if (mouse_arrows || optDown) {
newlin = (MousePt.v - TOPMARGIN) / LINEHEIGHT;
newcol = (MousePt.h - LEFTMARGIN + CHARWIDTH/2) / CHARWIDTH;
if ((oldlin != newlin) || (oldcol != newcol)) {
PenMode (patXor); /* For FrameRect calls */
if (oldlin >= 0) { /* if old rectangle */
if (mousecurs_drawn) {
makerect (&r, oldlin, oldcol, 1, 1);
FrameRect (&r);
}
} else { /* else if drawing for the first time */
HideCursor ();
}
makerect (&r, newlin, newcol, 1, 1);
FrameRect (&r);
PenMode (patCopy); /* reset to normal pen mode */
oldlin = newlin;
oldcol = newcol;
mousecurs_drawn = TRUE;
}
lastPoint=MousePt;
optwasdown=optDown;
return;
} else {
thisCursor = textcurs;
}
} else {
thisCursor = normcurs; /* default cursor shape */
}
if (lastCursor!= thisCursor) {
SetCursor(thisCursor);
lastCursor = thisCursor;
}
lastPoint=MousePt;
optwasdown=optDown;
if (oldlin >= 0) { /* if we hade drawn a movement outline */
if (mousecurs_drawn) {
PenMode (patXor); /* For FrameRect calls */
makerect (&r, oldlin, oldcol, 1, 1);
FrameRect (&r);
}
oldlin = -1;
mousecurs_drawn = FALSE;
ShowCursor ();
PenMode (patCopy); /* reset to normal pen mode */
}
}
/****************************************************************************/
/* Put characters onto the actual screen */
/****************************************************************************/
char outbuf[MAXCOL + 1];
int outcnt = 0, outcol;
static int to_mac_style[] = {
normal, underline, italic, underline|italic,
bold, bold|underline, bold|italic, bold|underline|italic
};
/****************************************************************************/
/* flushbuf() -- draw all the buffered characters on the screen */
/****************************************************************************/
flushbuf ()
{
register int i;
Rect r;
if (outcnt == 0)
return; /* Nothing to flush */
if (to_printer) { /*JAO*/
for (i = 0; i < outcnt; i++) {
(*hPrintBuffer)[lPrintBufferAt++] = outbuf[i];
if (lPrintBufferAt == lPrintBufferSize)
lPrintBufferAt = 0L;
lPrintBufferChars++;
if (lPrintBufferChars == lPrintBufferSize) {
overflowingDialog = GetNewDialog(OVERFLOWINGBOXID, NILPTR, (WindowPtr) - 1);
DrawDialog(overflowingDialog);
}
}
}
if (!to_screen) return; /*JAO*/
makerect (&r, curlin, outcol, 1, outcnt);
EraseRect (&r);
if (draw_sing_chars) {
for (i = 0; i < outcnt; i++) {
MOVETOCHAR(outcol + i, curlin - display_topline);
DrawChar(outbuf[i] & 0377);
}
} else { /* non-blinking */
MOVETOCHAR(outcol, curlin - display_topline);
DrawText (outbuf, 0, outcnt); /* Output the string */
}
if (textstyle & VT_INVERT) {
InvertRect (&r);
}
outcnt = 0; /* Say no more chars to output */
} /* flushbuf */
/****************************************************************************/
/* set_style(style) - set the correct stuff for displaying chars in style */
/****************************************************************************/
int
set_style(style)
int style;
{
int m_sty, m_font;
static int o_sty = 0, o_font = 0;
Handle theRsrc;
if (style == current_style) return;
current_style = style;
m_sty = to_mac_style[style & STY_MSTY];
m_font = ((style & STY_FONT) >> 3) + VT100FONT;
draw_sing_chars = style & VT_BLINK;
if (!have_128roms && (m_sty & bold)) { /* if on an old mac and bolding */
if (m_font = VT100FONT) {
m_font = VT100BOLD;
m_sty &= ~bold;
} else {
draw_sing_chars = 1;
}
}
if (m_font != o_font) {
TextFont (m_font); /* new font */
o_font = m_font;
}
if (m_sty != o_sty) {
TextFace (m_sty); /* new text face */
o_sty = m_sty;
}
}
/****************************************************************************/
/****************************************************************************/
void
draw_line_attrs(lin, v)
register int lin, v;
{
register int o, i, sty, j;
Rect r;
if ((v < 0) || (v > screensize))
printerr("draw_line_attrs, v out of range:", v);
sty = scr_attrs[lin][0];
o = 0;
i = 0;
do {
if ((scr_attrs[lin][i] != sty) || (i == MAXCOL)) { /* if this style != current style */
makerect (&r, v, o, 1, i-o);
EraseRect (&r);
set_style(sty);
if (draw_sing_chars) {
for (j = o; j < i; j++) {
MOVETOCHAR(j, v);
DrawChar(scr[lin][j] & 0377);
}
} else { /* non-blinking */
MOVETOCHAR(o, v);
DrawText (scr[lin], o, i-o); /* Output this part */
}
if (sty & VT_INVERT) {
InvertRect (&r);
}
o = i; /* now left extent == current */
sty = scr_attrs[lin][i]; /* new current style */
}
i++;
} while (i <= MAXCOL);
}
/****************************************************************************/
/****************************************************************************/
void
scroll_term()
{
register int new_topline, delta, lin, i;
int fl, fc, tl, tc;
Rect r; /* cannot be register */
new_topline = screensize - display_totlines + GetCtlValue (t_vscroll);
if ((new_topline > 0) || (new_topline < screensize - MAX_SCREENSIZE)) {
printerr("BUG: in scroll_term(), new_topline out of range:", new_topline);
return;
}
if ((delta = (display_topline - new_topline)) == 0)
return; /* we didn't move */
makerect (&r, 0, 0, screensize, MAXCOL);
if ((delta >= screensize) || (-delta >= screensize)) { /* if whole screen */
EraseRect(&r);
lin = new_topline; /* new top line */
for (i = 0; i < screensize; i++) {
draw_line_attrs(lin, i);
lin++;
}
display_topline = new_topline;
if (have_selection)
invert_text(from_lin, from_col, to_lin, to_col);
return; /* we are done */
}
/* if we get here, we are not doing the whole screen */
ScrollRect (&r, 0, delta * LINEHEIGHT, dummyRgn);
if (delta > 0) { /* scrolling down (pushing top arrow) */
lin = new_topline; /* new top line */
for (i = 0; (i < delta) && (i < screensize); i++) {
draw_line_attrs(lin, i);
lin++;
}
display_topline = new_topline;
if (have_selection &&
(from_lin < display_topline + delta) &&
(to_lin >= display_topline)) {
if (from_lin < display_topline) {
fl = display_topline;
fc = 0;
} else {
fl = from_lin;
fc = from_col;
}
if (to_lin >= display_topline + delta) {
tl = display_topline + delta - 1;
tc = MAXCOL;
} else {
tl = to_lin;
tc = to_col;
}
invert_text(fl, fc, tl, tc);
}
} else { /* scrolling up (pushing bottom arrow) */
lin = display_topline + screensize; /* one past old bottom line */
/*********** PWP: delta is negative here ****************/
i = screensize + delta;
if (i < 0) i = 0; /* bounds */
while (i < screensize)
draw_line_attrs(lin++, i++);
display_topline = new_topline;
if (have_selection &&
(from_lin < (display_topline + screensize)) &&
(to_lin >= (display_topline + screensize + delta))) {
if (from_lin < display_topline + screensize + delta) {
fl = display_topline + screensize + delta;
fc = 0;
} else {
fl = from_lin;
fc = from_col;
}
if (to_lin >= display_topline + screensize) {
tl = display_topline + screensize - 1;
tc = MAXCOL;
} else {
tl = to_lin;
tc = to_col;
}
invert_text(fl, fc, tl, tc);
}
}
}
void pascal
doscroll (WHICHCONTROL, THECODE)
ControlHandle WHICHCONTROL;
short THECODE;
{
register int amount = 0, val, max;
if (THECODE == inUpButton)
amount = -1;
if (THECODE == inDownButton)
amount = 1;
if (amount == 0)
return;
val = GetCtlValue (WHICHCONTROL) + amount;
max = GetCtlMax (WHICHCONTROL);
if ((val < 0) || (val > max))
return;
SetCtlValue (WHICHCONTROL, val);
scroll_term ();
} /* doscroll */
/****************************************************************************/
/* we move the displayed region to the bottom when we recieve characters */
/****************************************************************************/
screen_to_bottom()
{
if (display_topline != toplin) {
SetCtlValue (t_vscroll, display_totlines - screensize);
scroll_term ();
}
}
/****************************************************************************/
/* update_vscroll - adjust the scaling of the vertical scroll bar, or */
/* disable it if we havn't saved anything back yet */
/****************************************************************************/
update_vscroll ()
{
if (in_front && display_totlines > screensize) {
SetCtlMax (t_vscroll, display_totlines - screensize);
SetCtlValue (t_vscroll, display_totlines - screensize);
HiliteControl (t_vscroll, 0);
} else {
HiliteControl (t_vscroll, 255);
}
} /* sizescrollbars */
/****************************************************************************/
/****************************************************************************/
t_pagescroll (code, amount, ctrlh)
ControlHandle ctrlh;
{
Point myPt;
register int val, max;
max = GetCtlMax (ctrlh);
val = GetCtlValue (ctrlh);
do {
GetMouse (&myPt);
if (TestControl (ctrlh, &myPt) != code)
continue;
val += amount;
if (val < 0)
val = 0;
if (val > max)
val = max;
SetCtlValue (ctrlh, val);
scroll_term ();
} while (StillDown ());
} /* pagescroll */
termmouse(evt)
EventRecord *evt;
{
int actrlcode;
long ticks;
ControlHandle acontrol;
GrafPtr savePort;
GetPort (&savePort); /* save the current port */
SetPort (terminalWindow);
GlobalToLocal (&evt->where);/* convert to local */
if (mouse_arrows || (evt->modifiers & optionKey)) {
if (PtInRect (&evt->where, &ScreenRect)) { /* In terminal content? */
mouse_cursor_move(evt);
SetPort (savePort); /* restore previous port */
return; /* yes, do mouse stuff */
}
}
cursor_erase();
actrlcode = FindControl (&evt->where, terminalWindow, &acontrol);
switch (actrlcode) {
case inUpButton:
case inDownButton:
(void) TrackControl (acontrol, &evt->where, doscroll);
break;
case inPageUp:
t_pagescroll (actrlcode, -(screensize/2), acontrol);
break;
case inPageDown:
t_pagescroll (actrlcode, (screensize/2), acontrol);
break;
case inThumb:
(void) TrackControl (acontrol, &evt->where, (ProcPtr) NIL);
scroll_term ();
break;
case 0: /* in the window content itself */
mouse_region_select(evt);
break;
}
/* MOVETOCHAR(curcol, curlin - display_topline); */
cursor_draw();
SetPort (savePort); /* restore previous port */
}
do_arrow(dir) /* dir is 'A' (up), 'B' (down), 'C' (right), or 'D' (left) */
unsigned char dir;
{
OutputChar('\033'); /* ESC */
if (curskey_mode)
OutputChar('O'); /* SS3 */
else
OutputChar('['); /* CSI */
OutputChar(dir);
}
do_keypad (n) /* char to send is n + ',' */
int n;
{
if (appl_mode) {
OutputChar('\033'); /* ESC */
OutputChar('O'); /* SS3 */
OutputChar((unsigned char) n + 'l');
} else {
OutputChar((unsigned char) n + ','); /* normal digit or glyph */
}
}
do_pfkey(n) /* pf1 == 0 ... pf4 == 3 */
int n;
{
OutputChar('\033'); /* ESC */
OutputChar('O'); /* SS3 */
OutputChar((unsigned char) n + 'P');
}
do_keyenter()
{
if (appl_mode) {
OutputChar('\033'); /* ESC */
OutputChar('O'); /* SS3 */
OutputChar('M');
} else {
OutputChar('\015');
}
}
mouse_cursor_move (evt)
EventRecord *evt;
{
int mouselin;
int mousecol;
int tempcol;
int templin;
int i;
Point MousePt;
MousePt = evt->where;
mouselin = (MousePt.v - TOPMARGIN) / LINEHEIGHT;
mousecol = (MousePt.h - LEFTMARGIN + CHARWIDTH/2) / CHARWIDTH;
tempcol = curcol;
templin = curlin;
if (mousecol < tempcol)
for (i = tempcol; i > mousecol; i--) {
do_arrow (leftARROW);
waitasec ();
/* If tabs are used, we may go too far, so end loop */
if (curcol <= mousecol)
i = mousecol;
}
if (mouselin < templin)
for (i = templin; i > mouselin; i--) {
do_arrow (UPARROW);
waitasec ();
}
else if (mouselin > templin)
for (i = templin; i < mouselin; i++) {
do_arrow (DOWNARROW);
waitasec ();
}
if (curlin == mouselin)
tempcol = curcol; /* for short lines */
if (tempcol < mousecol)
for (i = tempcol; i < mousecol; i++) {
do_arrow (rightARROW);
waitasec ();
/* If tabs are used, we may go too far, so end loop */
if (curcol >= mousecol)
i = mousecol;
}
} /* mouse_cursor_move */
invert_text(from_lin, from_col, to_lin, to_col)
{
Rect r;
int t;
if (from_lin > to_lin) { /* make from < to */
t = to_lin;
to_lin = from_lin;
from_lin = t;
t = to_col;
to_col = from_col;
from_col = t;
}
from_lin -= display_topline; /* convert to screen coords */
if (from_lin < 0) {
from_lin = 0;
from_col = 0;
}
if (from_lin >= screensize)
return;
to_lin -= display_topline; /* convert to screen coords */
if (to_lin < 0)
return;
if (to_lin >= screensize) {
to_lin = screensize-1;
to_col = MAXCOL;
}
if (from_lin == to_lin) { /* if only one line */
if (from_col > to_col) {
t = to_col;
to_col = from_col;
from_col = t;
}
if (from_col != to_col) /* then invert the characters in between */
invertchars(from_lin, from_col, 1, to_col - from_col);
} else {
if (from_col < MAXCOL)
invertchars(from_lin, from_col, 1, MAXCOL - from_col);
t = to_lin - from_lin - 1;
if (t > 0)
invertchars(from_lin+1, 0, t, MAXCOL);
if (to_col > 0)
invertchars(to_lin, 0, 1, to_col);
}
}
mouse_region_select (evt)
EventRecord *evt;
{
int mouselin;
int mousecol;
int i, shift, sval, smax;
Point MousePt;
/* if no selection, then a shift drag is just a drag */
if (have_selection)
shift = (evt->modifiers) & shiftKey;
else
shift = 0;
/* if not adding to region, remove old one */
if (!shift && have_selection)
invert_text(from_lin, from_col, to_lin, to_col);
MousePt = evt->where;
mouselin = (MousePt.v - TOPMARGIN) / LINEHEIGHT + display_topline;
if (mouselin < display_topline)
mouselin = display_topline;
if (mouselin >= display_topline + screensize)
mouselin = display_topline + screensize-1;
mousecol = (MousePt.h - LEFTMARGIN + CHARWIDTH/2) / CHARWIDTH;
if (mousecol < 0) mousecol = 0;
if (mousecol > MAXCOL) mousecol = MAXCOL;
if (shift) {
/* swap from_* and to_* if closer to from */
if (ABS((MAXCOL * from_lin + from_col) - (MAXCOL * mouselin + mousecol)) <
ABS((MAXCOL * to_lin + to_col) - (MAXCOL * mouselin + mousecol))) {
i = to_lin;
to_lin = from_lin;
from_lin = i;
i = to_col;
to_col = from_col;
from_col = i;
}
} else {
from_lin = mouselin;
from_col = mousecol;
to_lin = mouselin;
to_col = mousecol;
}
while (StillDown()) {
GetMouse(&MousePt);
mouselin = (MousePt.v - TOPMARGIN) / LINEHEIGHT + display_topline;
mousecol = (MousePt.h - LEFTMARGIN + CHARWIDTH/2) / CHARWIDTH;
if (mouselin < display_topline) {
sval = GetCtlValue (t_vscroll) - 1;
smax = GetCtlMax (t_vscroll);
if ((sval >= 0) && (sval <= smax)) {
SetCtlValue (t_vscroll, sval);
scroll_term ();
}
mouselin = display_topline;
mousecol = 0;
} else if (mouselin >= display_topline + screensize) {
sval = GetCtlValue (t_vscroll) + 1;
smax = GetCtlMax (t_vscroll);
if ((sval >= 0) && (sval <= smax)) {
SetCtlValue (t_vscroll, sval);
scroll_term ();
}
mouselin = display_topline + screensize-1;
mousecol = MAXCOL;
} else if (mousecol < 0) {
mousecol = 0;
} else if (mousecol > MAXCOL) {
mousecol = MAXCOL;
}
if ((mousecol != to_col) || (mouselin != to_lin)) {
invert_text(to_lin, to_col, mouselin, mousecol);
to_lin = mouselin;
to_col = mousecol;
}
}
if (from_lin > to_lin) { /* make from < to */
int t;
t = to_lin;
to_lin = from_lin;
from_lin = t;
t = to_col;
to_col = from_col;
from_col = t;
} else if (from_lin == to_lin) {
if (from_col > to_col) {
int t;
t = to_col;
to_col = from_col;
from_col = t;
}
}
if ((from_lin != to_lin) || (from_col != to_col))
have_selection = TRUE;
else
have_selection = FALSE;
}
/* (PWP) if the selection is within [tlin,blin], then remove it */
maybe_nuke_selection(tlin, blin)
int tlin, blin;
{
if (have_selection &&
((from_lin < tlin) || (to_lin > blin)) &&
((to_lin > tlin) || (from_lin < blin))) {
have_selection = FALSE;
invert_text(from_lin, from_col, to_lin, to_col);
}
}
/* copy the current selction to the (internal) clipboard */
scr_copy()
{
int lin, i, rcol;
long sz;
char *dp;
if (myclip_h == NIL) {
printerr("scr_copy: clip handle not allocated", 0);
return;
}
if (have_selection) {
/****** find out how big the text to copy is ******/
if (from_lin == to_lin) {
sz = to_col - from_col + 1;
} else {
for (rcol = MAXCOL; rcol > from_col; rcol--) /* first */
if (scr[from_lin][rcol-1] != ' ')
break;
sz = rcol - from_col + 1; /* chars plus one for the newline */
for (lin = from_lin+1; lin < to_lin; lin++) { /* in between */
for (rcol = MAXCOL; rcol > 0; rcol--)
if (scr[lin][rcol-1] != ' ')
break;
sz += rcol + 1; /* chars plus one for the newline */
}
for (rcol = to_col; rcol > 0; rcol--) /* last */
if (scr[to_lin][rcol-1] != ' ')
break;
sz += rcol; /* chars */
if (to_col >= MAXCOL)
sz++;
}
/****** allocate and lock a buffer for the text ******/
if (sz > GetHandleSize ((Handle) myclip_h)) {
HUnlock((Handle) myclip_h);
SetHandleSize((Handle) myclip_h, sz);
}
HLock((Handle) myclip_h);
dp = *myclip_h;
/****** copy the characters over to the clip ******/
if (from_lin == to_lin) {
for (i = from_col; i < to_col; i++)
*dp++ = scr[from_lin][i];
} else {
/* trim off spaces */
for (rcol = MAXCOL; rcol > from_col; rcol--) /* first */
if (scr[from_lin][rcol-1] != ' ')
break;
for (i = from_col; i < rcol; i++)
*dp++ = scr[from_lin][i];
*dp++ = '\r';
for (lin = from_lin+1; lin < to_lin; lin++) { /* in between */
for (rcol = MAXCOL; rcol > 0; rcol--)
if (scr[lin][rcol-1] != ' ')
break;
for (i = 0; i < rcol; i++)
*dp++ = scr[lin][i];
*dp++ = '\r';
}
for (rcol = to_col; rcol > 0; rcol--) /* last */
if (scr[to_lin][rcol-1] != ' ')
break;
for (i = 0; i < rcol; i++)
*dp++ = scr[to_lin][i];
if (to_col >= MAXCOL)
*dp++ = '\r';
}
myclip_size = (dp - *myclip_h);
/****** check to make sure we didn't overflow the clipboard ******/
if (myclip_size > sz)
fatal ("Overflow! myclip_size - sz ==", myclip_size - sz);
/****** We are done. Unlock the handle ******/
HUnlock((Handle) myclip_h);
} else {
SysBeep(3);
}
}
/* paste the clipboard into the terminal, by "typing" it in */
scr_paste()
{
char *cp, *endp;
if (myclip_size > 0) {
HLock((Handle) myclip_h);
cp = *myclip_h;
endp = cp + myclip_size;
for (; cp < endp; cp++) {
OutputChar(*cp);
if (*cp == '\r')
waitasec ();
}
} else {
SysBeep(3);
}
}
/****************************************************************************/
/****************************************************************************/
#ifdef COMMENT
show_inval_rgn(w)
WindowPeek w;
{
RgnHandle r = NewRgn();
CopyRgn (w->updateRgn, r);
OffsetRgn(r, /* convert to local grafport coords */
(((w->port).portBits).bounds).left,
(((w->port).portBits).bounds).top);
FillRgn(r, qd.black);
DisposeRgn(r);
}
#endif /* COMMENT */
/****************************************************************************/
/*
* (UoR)
*
* Scroll lines within the scroll region upwards from line tlin
* to line blin (lines are assumed to be in the region)
*
* (PWP) scroll_screen is the combination of scroll_up and scroll_down.
* dir is the number of lines to scroll, <0 if up, >0 if down.
* (actually, right now only -1 and 1 are handled.)
*/
/****************************************************************************/
void
scroll_screen (tlin, blin, dir) /* these are in scr[][] cordinates */
register int tlin;
register int blin;
register int dir;
{
register int i, now;
int abstop, absbot;
char *savedline, *savedattr; /* temporary to hold screen line pointer */
Rect r, opened_r; /* cannot be register */
Point save_pt;
GrafPtr currWindow; /* cannot be register */
RgnHandle newupdateRgn;
abstop = tlin; /* really tlin - display_topline, but we are at bottom */
absbot = blin; /* so display_topline == 0 */
makerect (&r, abstop, 0, absbot - abstop + 1, MAXCOL);
if (dir < 0)
makerect (&opened_r, absbot, 0, 1, MAXCOL);
else
makerect (&opened_r, abstop, 0, 1, MAXCOL);
/* (PWP) if our selected region overlaps, but is not enclosed by the region
we want to scroll, then remove it, because the region no longer contains
what the user thought it did. */
if (have_selection && (tlin != toplin) && (blin != botlin) &&
((from_lin < tlin) || (to_lin > blin)) &&
((to_lin > tlin) || (from_lin < blin))) {
have_selection = FALSE;
invert_text(from_lin, from_col, to_lin, to_col);
}
if (!in_front) {
/* compensate update region for scrolling */
GetPort (&currWindow);
/* scroll the old updateRgn */
OffsetRgn (((WindowPeek) currWindow)->updateRgn, 0, -LINEHEIGHT);
}
/* do the scrolling */
newupdateRgn = NewRgn();
if (smoothscroll && in_front) {
for (i = 1; i <= LINEHEIGHT; i += 1) {
/* PWP: wait for a vertical reblank (in a sneaky way) */
now = TickCount ();
while (TickCount () == now)
/* wait... */ ;
if (dir < 0)
ScrollRect (&r, 0, -1, newupdateRgn);
else
ScrollRect (&r, 0, 1, newupdateRgn);
}
} else {
ScrollRect (&r, 0, dir * LINEHEIGHT, newupdateRgn);
if (!in_front) {
InvalRgn(newupdateRgn);
ValidRect(&opened_r);
}
}
DisposeRgn(newupdateRgn);
if (dir < 0) {
/* adjust the internal character buffers */
if ((tlin == toplin) && (blin == botlin)) { /* if whole screen */
display_totlines++;
if (display_totlines > MAX_SCREENSIZE)
display_totlines = MAX_SCREENSIZE; /* bounds */
tlin = screensize - display_totlines; /* top of saved buffer */
}
savedline = scr[tlin];
savedattr = scr_attrs[tlin];
for (i = tlin+1; i <= blin; i++) {
scr[i-1] = scr[i];
scr_attrs[i-1] = scr_attrs[i];
}
scr[blin] = savedline;
scr_attrs[blin] = savedattr;
zeroline (blin); /* clear the line */
/* adjust selection */
if (have_selection && (from_lin >= tlin) && (to_lin <= blin)) {
from_lin--;
to_lin--;
}
} else {
/* adjust the internal buffers */
savedline = scr[blin];
savedattr = scr_attrs[blin];
for (i = blin-1; i >= tlin; i--) {
scr[i+1] = scr[i];
scr_attrs[i+1] = scr_attrs[i];
}
scr[tlin] = savedline;
scr_attrs[tlin] = savedattr;
zeroline (tlin);
/* adjust selection */
if (have_selection && (from_lin >= tlin) && (to_lin <= blin)) {
from_lin++;
to_lin++;
}
}
} /* scroll_up */
/****************************************************************************/
/* redraw the terminal screen (we got a redraw event) */
/****************************************************************************/
term_redraw ()
{
int i, lin;
Rect r;
BackPat(qd.white);
PenPat(qd.black);
r = terminalWindow->portRect; /* copy the window size */
/* r.right -= 15; */ /* subtract control */
/* makerect (&r, 0, 0, screensize, MAXCOL); */ /* PWP: clear the screen first */
EraseRect (&r);
DrawGrowIcon (terminalWindow);
DrawControls (terminalWindow);
/* erase the bottom scroll line */
PenMode(patBic);
MoveTo(0, (terminalWindow->portRect).bottom - 15);
LineTo((terminalWindow->portRect).right - 16,
(terminalWindow->portRect).bottom - 15);
PenNormal();
/* update_vscroll(); */
/* SetCtlValue (t_vscroll, GetCtlValue (t_vscroll)); */
lin = display_topline;
for (i = 0; i < screensize; i++) {
draw_line_attrs(lin, i);
lin++;
}
if (have_selection)
invert_text(from_lin, from_col, to_lin, to_col);
if (cur_drawn && cursor_invert) { /* (UoR) only if cursor is showing */
cursor_invert = FALSE; /* (UoR) make sure we draw it */
cursor_draw (); /* redraw cursor */
last_flash = TickCount (); /* (UoR) reset timer */
}
} /* term_redraw */
term_activate(hilite)
int hilite;
{
cursor_erase (); /* remove cursor from screen */
in_front = hilite;
if (in_front) {
HiliteControl (t_vscroll, 0);
UpdateOptKey(1);
} else {
HiliteControl (t_vscroll, 255);
UpdateOptKey(0);
}
cursor_draw ();
}
/****************************************************************************/
/* initalize the terminal emulator. */
/****************************************************************************/
init_term ()
{
register int i, j;
char *cp;
topmargin = TOPMARGIN; /* Edges of adjustable window */
bottommargin = bottomMARGIN;
if ((cp = (char *)NewPtr(((long)(MAXCOL+1) * (long) MAX_SCREENSIZE))) == NIL)
fatal("Could not allocate screen buffer", 0);
for (i = 0; i < MAX_SCREENSIZE; i++) {
real_scr[i] = cp + (i * (MAXCOL+1)); /* divvy up screen buffer */
for (j = 0; j < MAXCOL; j++)
real_scr[i][j] = ' ';
real_scr[i][MAXCOL] = '\0'; /* Terminate the lines as strings */
if ((real_attrs[i] = (char *)NewPtr((long)(MAXCOL+1))) == NIL)
fatal("Could not allocate screen attribute line", i);
for (j = 0; j < MAXCOL; j++)
real_attrs[i][j] = 0;
real_attrs[i][MAXCOL] = '\0'; /* Terminate the lines as strings */
}
scr = &real_scr[MAX_SCREENSIZE - screensize];
if (scr[0] == NIL)
fatal("init_term: scr assignment botched for [0]", 0);
if (scr[screensize-1] == NIL)
fatal("init_term: scr assignment botched for [screensize-1]", 0);
scr_attrs = &real_attrs[MAX_SCREENSIZE - screensize];
if (scr_attrs[0] == NIL)
fatal("init_term: scr assignment botched for [0]", 0);
if (scr_attrs[screensize-1] == NIL)
fatal("init_term: scr assignment botched for [screensize-1]", 0);
scrtop = toplin; /* Scrolling region equals all */
scrbot = botlin;
display_topline = toplin; /* init display w/elevator at bottom */
display_totlines = screensize;
makerect (&ScreenRect, 0, 0, screensize, MAXCOL);
/* (UoR) full screen rectangle */
SizeWindow(terminalWindow,
rightMARGIN + 1 + 16, /* add extra to side for asthetics */
bottomMARGIN + TOPMARGIN, /* add extra to bottom for asthetics */
FALSE);
/* PWP: make the window match it's real size */
DrawGrowIcon (terminalWindow);
/* erase the bottom scroll line */
PenMode(patBic);
MoveTo(0, (terminalWindow->portRect).bottom - 15);
LineTo((terminalWindow->portRect).right - 16,
(terminalWindow->portRect).bottom - 15);
PenNormal();
t_vscroll = GetNewControl (RCMDVSCROLL, terminalWindow);
sizevscroll();
InitKeyStuff(); /* find the original KCHR keymaps */
/* ClipRect(&ScreenRect); */
} /* init_term */
/****************************************************************************/
/* sizevscroll - called when window is created and after a window grow */
/* sequence to resize the scroll window's bars. */
/****************************************************************************/
sizevscroll ()
{
register Rect *r;
r = &terminalWindow->portRect;/* window size */
HideControl (t_vscroll);
MoveControl (t_vscroll, r->right - 15, r->top - 1);
SizeControl (t_vscroll, 16, r->bottom - r->top - 13);
SetCtlMin (t_vscroll, 0);
update_vscroll();
ShowControl (t_vscroll);
} /* sizescrollbars */
/****************************************************************************/
/* grow_term_to(size) -- change the size of the terminal window to size.
this is called by growterm() (see below) and the terminal settings dialog
handler (termsetdialog()).
/****************************************************************************/
grow_term_to (size)
int size;
{
long gr;
int height;
int width;
char *savedline;
int i, j, d;
GrafPtr savePort;
if ((size < 1) || (size > MAX_SCREENSIZE))
size = 24; /* the default case */
if (size > display_totlines) { /* if getting bigger than we were */
for (i = screensize - display_totlines, j = screensize - size;
i < screensize; i++, j++) {
savedline = scr[i]; /* save used line */
scr[i] = scr[j]; /* copy empty line to old line */
scr[j] = savedline; /* copy old line to new line */
savedline = scr_attrs[i]; /* do the same for attribute lines */
scr_attrs[i] = scr_attrs[j];
scr_attrs[j] = savedline;
}
display_totlines = size;
} else {
curlin += size - screensize; /* adjust cursor row to match stretch */
if (curlin < 0)
curlin = 0;
if (curlin > size-1)
curlin = size-1;
}
screensize = size;
if (screensize > MAX_SCREENSIZE)
screensize = MAX_SCREENSIZE; /* bounds check */
scr = &real_scr[MAX_SCREENSIZE - screensize];
scr_attrs = &real_attrs[MAX_SCREENSIZE - screensize];
bottommargin = bottomMARGIN; /* this changes */
scrtop = toplin; /* Scrolling region equals all */
scrbot = botlin;
display_topline = 0; /* re-init display w/elevator at bottom */
makerect (&ScreenRect, 0, 0, screensize, MAXCOL);
/* (UoR) full screen rectangle */
SizeWindow(terminalWindow,
rightMARGIN + 1 + 16, /* add extra to side for asthetics */
bottomMARGIN + TOPMARGIN, /* add extra to bottom for asthetics */
FALSE);
/* PWP: make the window match it's real size */
sizevscroll (); /* size the scroll bars */
/* ClipRect(&ScreenRect); */
GetPort (&savePort);
SetPort (terminalWindow);
InvalRect (&terminalWindow->portRect); /* invalidate whole window rectangle */
SetPort (savePort);
} /* growwindow */
/****************************************************************************/
/****************************************************************************/
growterm (p)
Point *p;
{
long gr;
int height;
int width;
int size;
Rect growRect;
GrafPtr savePort;
growRect = qd.screenBits.bounds;
growRect.top = 50; /* minimal horizontal size */
growRect.left = rightMARGIN + 18; /* minimal vertical size */
growRect.right = rightMARGIN + 18; /* minimal vertical size */
gr = GrowWindow (terminalWindow, p, &growRect);
if (gr == 0)
return;
height = HiWord (gr);
width = LoWord (gr);
size = (height - (2 * TOPMARGIN)) / LINEHEIGHT;
if (size > MAX_SCREENSIZE)
screensize = MAX_SCREENSIZE; /* bounds check */
if (size < 1)
size = 1;
grow_term_to(size);
} /* growterm */