home *** CD-ROM | disk | FTP | other *** search
- {$S-,I-,V-}
- {$M 16384,16384,600000}
-
- {$I TPDEFINE.INC}
-
- {************************************************************}
- {* TPKEYS.PAS 5.04 *}
- {* Keyboard installation program for Turbo Professional 5.0 *}
- {* By TurboPower Software *}
- {************************************************************}
-
- program TpKeys;
-
- uses
- TpEnhKbd,
- TpString,
- TpDos,
- TpCrt,
- {$IFDEF UseMouse}
- TpMouse, {Turbo Professional mouse routines}
- {$ENDIF}
- TpCmd,
- TpClone,
- TpWindow,
- TpMenu,
- {the following units are not actually used}
- TpEdit,
- TpEntry,
- TpPick,
- TpHelp;
-
- type
- StringPointer = ^string;
- var
- MainMenu : Menu; {pointer to menu system}
- Ch : Char; {menu selection character}
- Key : MenuKey; {menu choice key}
-
- OrigMode : Word; {video mode when program started}
- OrigAttr : Byte; {vide attribute when program started}
-
- LoColor : Byte; {low video color}
- TiColor : Byte; {title color}
- CfColor : Byte; {conflict color}
- ChColor : Byte; {changed key color}
- EdColor : Byte; {edit window color}
- FrColor : Byte; {border frame color}
- StColor : Byte; {status message color}
-
- const
- NameLength = 26; {Maximum length for command name}
-
- PriCmdCol = 28; {Where '1: ' appears}
- PriMinCol = 31; {Where primary key sequence starts}
- PriMaxCol = 45; {Where primary key sequence ends}
-
- SecCmdCol = 46; {Where '2: ' appears}
- SecMinCol = 49; {Where secondary key sequence starts}
- SecMaxCol = 63; {Where secondary key sequence ends}
-
- TerCmdCol = 64; {Where '3: ' appears}
- TerMinCol = 67; {Where tertiary key sequence starts}
- TerMaxCol = 80; {Where tertiary key sequence ends}
-
- CmdWid = 14; {Number of columns where the command is displayed}
- FirstRow = 4; {First row where keys are installed}
- LastRow = 22; {Last row where keys are installed}
- StatCol = 2; {Column for status messages}
- StatRow = 24; {Row for status messages}
- StatWid = 78; {maximum length of status messages}
-
- EditWinLeft = 3; {coordinates for key edit window}
- EditWinRight = 78;
- EditWinTop = 11;
- EditWinBot = 13;
- EditCmdWid = 74; {internal width of key edit window}
- EditCmdCol = 65; {column for Command/Literal message}
-
- SingBarChar = '─';
- DoubBarChar = '═';
-
- EditPrompt : string[72] =
- '-delete C-clear R-restore ┘-accept ESC-cancel Scroll Lock-literal';
- BrowsePrompt : string[67] =
- '--scroll PgUp-PgDn-page ┘-modify R-restore defaults ESC-exit';
-
- type
- String80 = string[80];
-
- NameString = string[NameLength];
- NameArray = array[1..MaxCommands] of NameString;
- MapArray = array[1..MaxCommands] of Byte;
- ByteArray = array[0..MaxKeys] of Byte;
-
- var
- EditCP : ClonePack; {TPEDIT - clone file}
- EntryCP : ClonePack; {TPENTRY - clone file}
- HelpCP : ClonePack; {TPHELP - clone file}
- MenuCP : ClonePack; {TPMENU - clone file}
- PickCP : ClonePack; {TPPICK - clone file}
-
- EditPos : LongInt; {TPEDIT - file pointer}
- EntryPos : LongInt; {TPENTRY - file pointer}
- HelpPos : LongInt; {TPHELP - file pointer}
- MenuPos : LongInt; {TPMENU - file pointer}
- PickPos : LongInt; {TPPICK - file pointer}
-
- MenuKeySet2 : array[0..MenuKeyMax] of Byte; {TPMENU - packed keys}
-
- EditUK : UnpackedKeyArray; {TPEDIT - unpacked keys}
- EntryUK : UnpackedKeyArray; {TPENTRY - unpacked keys}
- HelpUK : UnpackedKeyArray; {TPHELP - unpacked keys}
- MenuUK : UnpackedKeyArray; {TPMENU - unpacked keys}
- PickUK : UnpackedKeyArray; {TPPICK - unpacked keys}
-
- OUK : UnpackedKeyArray; {Original unpacked key array}
- P : UnpackedKeyPtr; {Pointer to current unpacked key array}
- N : ^NameArray; {Pointer to current name array}
- NNames : Word; {Current number of command names}
- M : ^MapArray; {Pointer to current order map array}
- NMaps : Word; {Current number of displayed commands}
-
- Modified : Boolean; {True when installation changes may have occurred}
-
- {$IFDEF UseMouse}
- const
- MapLeftButton : Boolean = True;
-
- {used to translate mouse buttons to keys}
- ButtonCodes : array[$E9..$EF] of Word = (
- $011B, {all three buttons = ESC}
- $011B, {right and center buttons = ESC}
- $011B, {left and center buttons = ESC}
- $011B, {center button = ESC}
- $011B, {both buttons = ESC}
- $011B, {right button = ESC}
- $1C0D); {left button = Enter}
- {$ENDIF}
-
- {.F-}
- const
- EditFileName : string[6] = 'TPEDIT';
-
- {names of TpEdit commands -- array must start with 1 (RSchar)}
- EditNames : array[RSchar..RSuser9] of NameString = (
- '', {RSchar}
- 'Enter control char', {RSctrlChar}
- 'Accept string', {RSenter}
- 'Cancel', {RSquit}
- 'Restore string', {RSrestore}
- 'Cursor to start of line', {RShome}
- 'Cursor to end of line', {RSend}
- 'Cursor left', {RSleft}
- 'Cursor right', {RSright}
- 'Cursor left one word', {RSwordLeft}
- 'Cursor right one word', {RSwordRight}
- 'Delete previous char', {RSback}
- 'Delete char at cursor', {RSdel}
- 'Delete to end of line', {RSdelEol}
- 'Delete from start of line', {RSdelBol}
- 'Delete entire line', {RSdelLine}
- 'Delete word', {RSdelWord}
- 'Toggle insert mode', {RSins}
- 'Help', {RShelp}
- 'User 0', {RSuser0}
- 'User 1', {RSuser1}
- 'User 2', {RSuser2}
- 'User 3', {RSuser3}
- 'User 4', {RSuser4}
- 'User 5', {RSuser5}
- 'User 6', {RSuser6}
- 'User 7', {RSuser7}
- 'User 8', {RSuser8}
- 'User 9' {RSuser9}
- );
-
- {Display map for TpEdit commands -- 0 inserts a divider bar}
- EditDisplay = 31;
- EditMap : array[1..EditDisplay] of Byte = (
- RSleft, RSright, RSwordLeft, RSwordRight, RShome, RSend,
- 0,
- RSback, RSdel, RSdelEol, RSdelBol, RSdelLine, RSdelWord, RSins,
- 0,
- RSenter, RSquit, RSctrlChar, RSrestore, RShelp,
- 0,
- RSuser0, RSuser1, RSuser2, RSuser3, RSuser4,
- RSuser5, RSuser6, RSuser7, RSuser8, RSuser9);
-
- EntryFileName : string[7] = 'TPENTRY';
- EntryNames : array[ESChar..ESmouse] of NameString = (
- '', {ESchar}
- 'Enter control char', {ESctrlChar}
- 'Restore string', {ESrestore}
- 'Cursor to start of line', {EShome}
- 'Cursor to end of line', {ESend}
- 'Cursor left', {ESleft}
- 'Cursor right', {ESright}
- 'Cursor left one word', {ESwordLeft}
- 'Cursor right one word', {ESwordRight}
- 'Delete previous char', {ESback}
- 'Delete char at cursor', {ESdel}
- 'Delete entire field', {ESdelLine}
- 'Delete to end of field', {ESdelEol}
- 'Delete from start of field', {ESdelBol}
- 'Delete word', {ESdelWord}
- 'Toggle insert mode', {ESins}
- 'Help', {EShelp}
- 'Next subfield', {EStab}
- 'Previous subfield', {ESbackTab}
- 'Increment choice', {ESincChoice}
- 'Decrement choice', {ESdecChoice}
- 'Next field', {ESnextField}
- 'Previous field', {ESprevField}
- 'Next field down', {ESdownField}
- 'Next field up', {ESupField}
- 'Next record', {ESnextRec}
- 'Previous record', {ESprevRec}
- 'First field', {ESfirstFld}
- 'Last field', {ESlastFld}
- 'Previous page', {ESpageUp}
- 'Next page', {ESpageDown}
- '', {ESnested} {shouldn't be assigned!}
- 'User 0', {ESuser0}
- 'User 1', {ESuser1}
- 'User 2', {ESuser2}
- 'User 3', {ESuser3}
- 'User 4', {ESuser4}
- 'User 5', {ESuser5}
- 'User 6', {ESuser6}
- 'User 7', {ESuser7}
- 'User 8', {ESuser8}
- 'User 9', {ESuser9}
- 'Accept data', {ESdone}
- 'Cancel', {ESquit}
- '', {ESclickExit} {shouldn't be assigned!}
- 'Mouse select' {ESmouse}
- );
- EntryDisplay = 48;
- EntryMap : array[1..EntryDisplay] of Byte = (
- ESleft, ESright, ESwordLeft, ESwordRight, EShome, ESend, EStab, ESbackTab,
- 0,
- ESback, ESdel, ESdelEol, ESdelBol, ESdelLine, ESdelWord, ESins,
- 0,
- ESnextField, ESprevField, ESdownField, ESupField,
- ESnextRec, ESprevRec, ESfirstFld, ESlastFld, ESpageUp, ESpageDown,
- 0,
- ESdone, ESquit, ESmouse, ESctrlChar, ESrestore, EShelp,
- 0,
- ESincChoice, ESdecChoice,
- 0,
- ESuser0, ESuser1, ESuser2, ESuser3, ESuser4,
- ESuser5, ESuser6, ESuser7, ESuser8, ESuser9);
-
- HelpFileName : string[6] = 'TPHELP';
- HelpNames : array[HKSAlpha..HKSUser3] of NameString = (
- '', {HKSAlpha}
- 'Cursor up', {HKSUp}
- 'Cursor down', {HKSDown}
- 'Page up', {HKSPgUp}
- 'Page down', {HKSPgDn}
- 'Cursor left', {HKSLeft}
- 'Cursor right', {HKSRight}
- 'Exit from help system', {HKSExit}
- 'Select cross-ref topic', {HKSSelect}
- 'Previous help topic', {HKSPrev}
- 'First help page', {HKSHome}
- 'Last help page', {HKSEnd}
- 'Display help index', {HKSIndex}
- 'Mouse select', {HKSProbe}
- 'User 0', {HKSuser0}
- 'User 1', {HKSuser1}
- 'User 2', {HKSuser2}
- 'User 3' {HKSuser3}
- );
- HelpDisplay = 19;
- HelpMap : array[1..HelpDisplay] of Byte = (
- HKSUp, HKSDown, HKSLeft, HKSRight,
- HKSHome, HKSEnd, HKSPgUp, HKSPgDn,
- 0,
- HKSSelect, HKSProbe, HKSPrev, HKSIndex, HKSExit,
- 0,
- HKSUser0, HKSUser1, HKSUser2, HKSUser3);
-
- MenuFileName : string[6] = 'TPMENU';
- MenuNames : array[MKSAlpha..MKSuser3] of NameString = (
- '', {MKSAlpha}
- 'Cursor up', {MKSUp}
- 'Cursor down', {MKSDown}
- '', {unused}
- '', {unused}
- 'Cursor left', {MKSLeft}
- 'Cursor right', {MKSRight}
- 'Exit from menu', {MKSExit}
- 'Select item', {MKSSelect}
- 'Help', {MKSHelp}
- 'First menu item', {MKSHome}
- 'Last menu item', {MKSEnd}
- 'Mouse select', {MKSProbe}
- 'User 0', {MKSuser0}
- 'User 1', {MKSuser1}
- 'User 2', {MKSuser2}
- 'User 3' {MKSuser3}
- );
- MenuDisplay = 17;
- MenuMap : array[1..MenuDisplay] of Byte = (
- MKSUp, MKSDown, MKSLeft, MKSRight,
- 0,
- MKSHome, MKSEnd,
- 0,
- MKSSelect, MKSProbe, MKSExit, MKSHelp,
- 0,
- MKSUser0, MKSUser1, MKSUser2, MKSUser3);
-
- PickFileName : string[6] = 'TPPICK';
- PickNames : array[PKSAlpha..PKSUser3] of NameString = (
- '', {PKSAlpha}
- 'Cursor up', {PKSUp}
- 'Cursor down', {PKSDown}
- 'Page up', {PKSPgUp}
- 'Page down', {PKSPgDn}
- 'Cursor left', {PKSLeft}
- 'Cursor right', {PKSRight}
- 'Exit from pick list', {PKSExit}
- 'Select item', {PKSSelect}
- 'Help', {PKSHelp}
- 'First menu item', {PKSHome}
- 'Last menu item', {PKSEnd}
- 'Mouse select', {PKSProbe}
- 'User 0', {PKSuser0}
- 'User 1', {PKSuser1}
- 'User 2', {PKSuser2}
- 'User 3' {PKSuser3}
- );
- PickDisplay = 19;
- PickMap : array[1..PickDisplay] of Byte = (
- PKSUp, PKSDown, PKSLeft, PKSRight,
- 0,
- PKSHome, PKSEnd, PKSPgUp, PKSPgDn,
- 0,
- PKSSelect, PKSProbe, PKSExit, PKSHelp,
- 0,
- PKSUser0, PKSUser1, PKSUser2, PKSUser3);
- {.F+}
-
- {$IFDEF UseMouse}
-
- function ReadKeyWord : Word;
- {-Get a key from the keyboard or mouse}
- var
- I : Word;
- begin
- I := ReadKeyOrButton;
- case Hi(I) of
- $E9..$EE :
- ReadKeyWord := ButtonCodes[Hi(I)];
- $EF :
- if MapLeftButton then
- ReadKeyWord := ButtonCodes[$EF]
- else
- ReadKeyWord := $EF00;
- else
- ReadKeyWord := I
- end;
- end;
-
- function ReadKey : Char;
- {-Special ReadKey routine that accounts for mouse}
- const
- ScanCode : Char = #0;
- var
- Key : Word;
- begin
- if ScanCode <> #0 then begin
- {return the scan code}
- ReadKey := ScanCode;
- ScanCode := #0;
- end
- else begin
- {get the next keystroke}
- Key := ReadKeyWord;
-
- {return the low byte}
- ReadKey := Char(Lo(Key));
-
- {if it's 0, save the scan code for the next call}
- if Lo(Key) = 0 then
- ScanCode := Char(Hi(Key));
- end;
- end;
-
- function KeyPressed : Boolean;
- {-Special KeyPressed routine that accounts for mouse}
- begin
- KeyPressed := TpCrt.KeyPressed or MousePressed;
- end;
-
- {$ENDIF}
-
- function ErrorMessage(Status : Word) : string;
- {-Return Turbo runtime error messages}
- var
- S : string;
- begin
- case Status of
- 000 : S := '';
- 002 : S := 'File not found';
- 003 : S := 'Path not found';
- 004 : S := 'Too many open files';
- 005 : S := 'File access denied';
- 006 : S := 'Invalid file handle';
- 012 : S := 'Invalid file access code';
- 015 : S := 'Invalid drive number';
- 016 : S := 'Cannot remove current directory';
- 017 : S := 'Cannot rename across drives';
- 100 : S := 'Disk read error';
- 101 : S := 'Disk write error';
- 102 : S := 'File not assigned';
- 103 : S := 'File not open';
- 104 : S := 'File not open for input';
- 105 : S := 'File not open for output';
- 106 : S := 'Invalid numeric format';
- 150 : S := 'Disk is write-protected';
- 151 : S := 'Unknown unit';
- 152 : S := 'Drive not ready';
- 153 : S := 'Unknown command';
- 154 : S := 'CRC error in data';
- 155 : S := 'Bad drive request structure length';
- 156 : S := 'Disk seek error';
- 157 : S := 'Unknown media type';
- 158 : S := 'Sector not found';
- 159 : S := 'Printer out of paper';
- 160 : S := 'Device write fault';
- 161 : S := 'Device read fault';
- 162 : S := 'Hardware failure';
- 200 : S := 'Division by zero';
- 201 : S := 'Range check error';
- 202 : S := 'Stack overflow';
- 203 : S := 'Insufficient memory';
- 204 : S := 'Invalid pointer operation';
- 205 : S := 'Floating point overflow';
- 206 : S := 'Floating point underflow';
- 207 : S := 'Invalid floating point operation';
- else
- S := 'Turbo runtime error '+Long2Str(Status);
- end;
- ErrorMessage := S;
- end;
-
- procedure Error(Msg : string);
- {-Report error and halt}
- begin
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- Window(1, 1, ScreenWidth, ScreenHeight);
- ClrScr;
- WriteLn(Msg);
- Halt(1);
- end;
-
- procedure ClrStatLine;
- {-Clear status line}
- begin
- FastWrite(CharStr(' ', StatWid), StatRow, StatCol, StColor);
- end;
-
- procedure InitMenu(var M : Menu);
- {-Initialize menu system}
- const
- Color1 : MenuColorArray = ($1F, $5F, $1B, $5F, $1B, $00, $00, $00);
- Mono1 : MenuColorArray = ($0F, $70, $07, $70, $0F, $00, $00, $00);
- Frame1 : FrameArray = '╒╘╕╛═│';
- begin
- {we'll do our own color mapping}
- MapColors := False;
- if (WhichHerc <> HercInColor) and (CurrentMode <> 3) then
- Color1 := Mono1;
-
- M := NewMenu([], nil);
- SubMenu(1, 1, 0, Horizontal, Frame1, Color1,
- ' TPKEYS - Turbo Professional 5.0 Keyboard Installation ');
- MenuWidth(80);
- MenuItem(' TPEDIT ', 4, 0, 1, '');
- MenuItem(' TPENTRY ', 18, 0, 2, '');
- MenuItem(' TPHELP ', 34, 0, 3, '');
- MenuItem(' TPMENU ', 50, 0, 4, '');
- MenuItem(' TPPICK ', 65, 0, 5, '');
- PopSublevel;
-
- ResetMenu(M);
- end;
-
- procedure Init;
- {-Initialize data structures}
- begin
- {Assure 80 column}
- CheckBreak := False;
- OrigMode := LastMode;
- OrigAttr := TextAttr;
-
- {assure 80 column text mode}
- case CurrentMode of
- 0..1 : TextMode(CurrentMode+2);
- 2..3, 7 : {ok} ;
- else TextMode(3);
- end;
-
- {assure 25-line mode}
- if Hi(LastMode) <> 0 then
- SelectFont8x8(False);
-
- {Set up colors}
- if (CurrentMode = 3) or (WhichHerc = HercInColor) then begin
- LoColor := $0F;
- TiColor := $0B;
- ChColor := $0C;
- EdColor := $1F;
- CfColor := $4F;
- FrColor := $1F;
- StColor := $1B;
- end
- else begin
- LoColor := $07;
- TiColor := $0F;
- ChColor := $0F;
- EdColor := $70;
- CfColor := $70;
- FrColor := $0F;
- StColor := $07;
- end;
-
- TextAttr := LoColor;
- ClrScr;
- Modified := False;
-
- FrameWindow(StatCol-1, StatRow-1, StatCol+StatWid, StatRow+1,
- FrColor, FrColor, '');
- ClrStatLine;
-
- {$IFDEF UseMouse}
- if MouseInstalled then begin
- {use a diamond for our mouse cursor}
- if (CurrentMode = 3) or (WhichHerc = HercInColor) then
- SoftMouseCursor($0000, $4F04)
- else
- SoftMouseCursor($0000, $0F04);
- ShowMouse;
-
- {enable mouse support}
- EnableMenuMouse;
- end;
- {$ENDIF}
- end;
-
- procedure StatMessage(Msg : string);
- {-Write a message to status line}
- var
- Col : Byte;
- begin
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- ClrStatLine;
- if Length(Msg) > StatWid then
- Msg[0] := Char(StatWid);
- Col := (80-Length(Msg)) shr 1;
- FastWrite(Msg, 24, StatCol+Col, StColor);
- GoToXYAbs(StatCol+Col+Length(Msg), 24);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- end;
-
- function PromptYesNo(Msg : string) : Boolean;
- {-Return true if yes answer}
- var
- Ch : Char;
- begin
- StatMessage(Msg);
- repeat
- Ch := Upcase(ReadKey);
- until (Ch = 'Y') or (Ch = 'N');
- PromptYesNo := (Ch = 'Y');
- end;
-
- procedure PromptEsc(Msg : string);
- {-Prompt for <Esc> to be pressed}
- var
- Ch : Char;
- begin
- StatMessage(Msg+'. Press <Esc>');
- repeat
- Ch := ReadKey;
- until Ch = #27;
- end;
-
- procedure PressEsc(Msg : string);
- {-Write a message and wait for <Esc>}
- var
- Ch : Char;
- begin
- StatMessage(Msg+'. Press <Esc> to correct...');
- repeat
- Ch := ReadKey;
- until Ch = #27;
- end;
-
- procedure CheckCloneError(FPos : LongInt; Msg : string);
- {-Check the opening of the installation program}
- begin
- if CloneError <> 0 then
- if FPos = 0 then
- Error(Msg)
- else
- Error(ErrorMessage(CloneError));
- end;
-
- procedure InitClonePrim(FName : String80; var CP : ClonePack;
- var ID : string; var Pos : LongInt);
- {-Primitive routine to initialize a unit for cloning}
- begin
- {open file for cloning}
- FName := DefaultExtension(FName, 'TPU');
- if not ExistOnPath(FName, FName) then
- CloneError := 2
- else
- Pos := InitForCloning(FName, CP, ID, Length(ID)+1);
-
- {check for errors}
- if CloneError = 2 then
- Error(FName+' not found')
- else
- CheckCloneError(Pos, FName+' ID string not found');
-
- {skip over ID string}
- Inc(Pos, Length(ID)+1);
- end;
-
- procedure Open;
- {-Open the TPU files for installation}
- begin
- {don't change time *or* date stamps on TPU files--it might force
- unnecessary recompilation of other units}
- DateUpdate := UpdateNone;
-
- WriteLn('Finding identification strings...');
- InitClonePrim(EditFileName, EditCP, EditKeyID, EditPos);
- InitClonePrim(EntryFileName, EntryCP, EntryKeyID, EntryPos);
- InitClonePrim(MenuFileName, MenuCP, MenuKeyID, MenuPos);
- InitClonePrim(HelpFileName, HelpCP, HelpKeyID, HelpPos);
- InitClonePrim(PickFileName, PickCP, PickKeyID, PickPos);
- end;
-
- procedure LoadPrim(var CP : ClonePack; FPos : LongInt;
- var Defaults; DefSize : Word);
- {-Primitive routine to load defaults for a unit}
- begin
- {load defaults}
- LoadDefaults(CP, FPos, Defaults, DefSize);
-
- {check for errors}
- CheckCloneError(1, '');
- end;
-
- procedure Load;
- {-Load the default settings}
- begin
- LoadPrim(EditCP, EditPos, EditKeySet, SizeOf(EditKeySet));
- LoadPrim(EntryCP, EntryPos, EntryKeySet, SizeOf(EntryKeySet));
- LoadPrim(MenuCP, MenuPos, MenuKeySet2, SizeOf(MenuKeySet2));
- LoadPrim(HelpCP, HelpPos, HelpKeySet, SizeOf(HelpKeySet));
- LoadPrim(PickCP, PickPos, PickKeySet, SizeOf(PickKeySet));
- end;
-
- procedure UnpackPrim(var PK, UK);
- {-Primitive routine to unpack the commands for a unit}
- var
- I : Word;
- begin
- I := UnpackKeys(PK, UK, MaxCommands, 3);
- end;
-
- procedure Unpack;
- {-Unpack all of the key arrays}
- begin
- UnpackPrim(EditKeySet, EditUK);
- UnpackPrim(EntryKeySet, EntryUK);
- UnpackPrim(MenuKeySet2, MenuUK);
- UnpackPrim(HelpKeySet, HelpUK);
- UnpackPrim(PickKeySet, PickUK);
- end;
-
- procedure PackPrim(var PK, UK; MaxBytes : Word);
- {-Primitive routine to pack the commands for a unit}
- var
- I : Word;
- begin
- I := PackKeys(PK, MaxCommands, MaxBytes, UK);
- end;
-
- procedure Pack;
- {-Pack all of the key arrays}
- begin
- PackPrim(EditKeySet, EditUK, EditKeyMax);
- PackPrim(EntryKeySet, EntryUK, EntryKeyMax);
- PackPrim(MenuKeySet2, MenuUK, MenuKeyMax);
- PackPrim(HelpKeySet, HelpUK, HelpKeyMax);
- PackPrim(PickKeySet, PickUK, PickKeyMax);
- end;
-
- procedure StorePrim(var CP : ClonePack; FPos : LongInt;
- var Defaults; DefSize : Word);
- {-Primitive routine to store the packed commands for a unit}
- begin
- {store modified defaults}
- StoreDefaults(CP, FPos, Defaults, DefSize);
-
- {check for errors}
- CheckCloneError(1, '');
-
- {close clone file}
- CloseForCloning(CP);
-
- {check for errors}
- CheckCloneError(1, '');
- end;
-
- function CheckModifiedFlags(var UnpackedKeys; NumCmds : Word) : Boolean;
- {-Check to see if any of the Modified flags are set in UnpackedKeys}
- var
- I : Word;
- UK : UnpackedKeyArray absolute UnpackedKeys;
- begin
- {assume success}
- CheckModifiedFlags := False;
-
- {turn off all Conflict flags}
- for I := 1 to NumCmds do
- if UK[I].Modified then begin
- CheckModifiedFlags := True;
- Exit;
- end;
- end;
-
- procedure Store;
- {-Store the new default settings}
- begin
- StatMessage('Storing new defaults....');
- if CheckModifiedFlags(EditUK, MaxCommands) then
- StorePrim(EditCP, EditPos, EditKeySet, SizeOf(EditKeySet));
- if CheckModifiedFlags(EntryUK, MaxCommands) then
- StorePrim(EntryCP, EntryPos, EntryKeySet, SizeOf(EntryKeySet));
- if CheckModifiedFlags(MenuUK, MaxCommands) then
- StorePrim(MenuCP, MenuPos, MenuKeySet2, SizeOf(MenuKeySet2));
- if CheckModifiedFlags(HelpUK, MaxCommands) then
- StorePrim(HelpCP, HelpPos, HelpKeySet, SizeOf(HelpKeySet));
- if CheckModifiedFlags(PickUK, MaxCommands) then
- StorePrim(PickCP, PickPos, PickKeySet, SizeOf(PickKeySet));
- end;
-
- {$L PREF.OBJ}
-
- {$F+}
- function EscapeSequence(B : Byte) : StringPointer; external;
- {-Return a pointer to a text string representing extended scan code B}
- {$F-}
-
- procedure KeyToString(Key : Word; var S : string; SingleKey : Boolean);
- {-Returns a string (S) representing a Key. Special is set to False if
- a simple character is being returned.}
- begin
- if (Lo(Key) = 0) or (Lo(Key) = $E0) then
- S := '<'+EscapeSequence(Hi(Key))^+'>'
- else begin
- if (Lo(Key) <= 31) and not SingleKey then
- S := '<^'+Chr(Lo(Key)+64)+'>'
- else
- case Lo(Key) of
- 008 : S := '<BkSp>'; {Backspace}
- 009 : S := '<Tab>'; {Tab}
- 010 : S := '<^Enter>'; {^Enter}
- 013 : S := '<Enter>'; {Enter}
- 027 : S := '<Esc>'; {Escape}
- 1..31 : {Control characters}
- S := '<^'+Chr(Lo(Key)+64)+'>';
- 032 : S := '<Space>';
- 127 : S := '<^BkSp>'; {ASCII DEL}
- 255 : S := '<#255>'; {#255}
- else
- {Normal character}
- S := '<'+Char(Lo(Key))+'>';
- end;
- end;
- end;
-
- procedure DrawKeys(Keys : KeyString; Row, Col : Integer; Attr : Byte;
- MoveCursor : Boolean; CmdWidth : Byte);
- {-Draw the keystrokes in specified attribute}
- var
- KLen : Byte absolute Keys;
- I : Integer;
- KW : Word;
- KeyStr : string[20];
- CurCol : Integer;
- Special : Boolean;
- S : String80;
- SLen : Byte absolute S;
- begin
- I := 1;
- SLen := 0;
- while I <= KLen do begin
- if Keys[I] = #0 then begin
- if I = KLen then
- KW := 0
- else begin
- Inc(I);
- KW := Swap(Byte(Keys[I]));
- end;
- end
- else
- KW := Byte(Keys[I]);
- KeyToString(KW, KeyStr, KLen = 1);
- S := S+KeyStr;
- Inc(I);
- end;
- if SLen >= CmdWidth then begin
- CurCol := CmdWidth;
- SLen := CmdWidth;
- end
- else begin
- CurCol := SLen;
- S := Pad(S, CmdWidth);
- end;
-
- FastWrite(S, Row, Col, Attr);
- if MoveCursor then
- GoToXY(Col+CurCol, Row);
- end;
-
- procedure DrawCmd(Cmd, Row : Integer);
- {-Write a single command, Cmd, at screen Row}
- var
- Attr : Byte;
- St : String80;
- Index : Word;
- begin
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- if Cmd = 0 then begin
- {Separator bar}
- St := CharStr(SingBarChar, 80);
- FastWrite(St, Row, 1, TiColor);
- end
- else begin
- Index := ((Cmd-1)*3)+1;
-
- {Name of command}
- St := Pad(N^[Cmd], PriCmdCol-1);
- St := St+'1:';
- FastWrite(Pad(St, 80), Row, 1, TiColor);
-
- {Primary keys}
- with P^[Index] do begin
- if Length(Keys) = 0 then
- Attr := LoColor
- else if Conflict then
- Attr := CfColor
- else if Modified then
- Attr := ChColor
- else
- Attr := LoColor;
- DrawKeys(Keys, Row, PriMinCol, Attr, False, CmdWid);
- end;
-
- {Secondary keys}
- FastWrite('2:', Row, SecCmdCol, TiColor);
- with P^[Index+1] do begin
- if Length(Keys) = 0 then
- Attr := LoColor
- else if Conflict then
- Attr := CfColor
- else if Modified then
- Attr := ChColor
- else
- Attr := LoColor;
- DrawKeys(Keys, Row, SecMinCol, Attr, False, CmdWid);
- end;
-
- {Tertiary keys}
- FastWrite('3:', Row, TerCmdCol, TiColor);
- with P^[Index+2] do begin
- if Length(Keys) = 0 then
- Attr := LoColor
- else if Conflict then
- Attr := CfColor
- else if Modified then
- Attr := ChColor
- else
- Attr := LoColor;
- DrawKeys(Keys, Row, TerMinCol, Attr, False, CmdWid);
- end;
- end;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- end;
-
- procedure EditCmd(Cmd : Word; var Key : KeyRec);
- {-Edit one keystroke sequence}
- const
- SMask = $10; {Scroll lock bit mask}
- ComStr : string[9] = ' Command ';
- LitStr : string[9] = ' Literal ';
- var
- KFlag : Byte absolute $0040 : $0017;
- SLock : Byte;
- LLock : Byte;
- KW : Word;
- K : KeyString;
- KLen : Byte absolute K;
- B : KeyString;
- Done : Boolean;
- Attr : Byte;
-
- function AddKey(B : Byte) : Char;
- {-Map alpha characters to control key equivalents}
- begin
- Char(B) := System.Upcase(Char(B));
- case Char(B) of
- 'A'..'Z' :
- AddKey := Char(B-64);
- else
- AddKey := Char(B);
- end;
- end;
-
- begin
- StatMessage(EditPrompt);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- FrameWindow(EditWinLeft, EditWinTop, EditWinRight, EditWinBot,
- EdColor, EdColor, ' '+N^[Cmd]+' ');
-
- LLock := $FF;
- K := Key.Keys;
- B := K;
-
- Done := False;
- repeat
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- DrawKeys(K, EditWinTop+1, EditWinLeft+1, EdColor, True, EditCmdWid);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
-
- repeat
- SLock := KFlag and SMask;
- if SLock <> LLock then begin
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- if SLock = 0 then
- FastWrite(ComStr, EditWinBot, EditCmdCol, EdColor)
- else
- FastWrite(LitStr, EditWinBot, EditCmdCol, EdColor);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
-
- LLock := SLock;
- end;
- until KeyPressed;
-
- {$IFDEF UseMouse}
- KW := ReadKeyOrButton;
- {$ELSE}
- KW := ReadKeyWord;
- {$ENDIF}
-
- if SLock <> 0 then begin
- {Literal mode}
- if Lo(KW) = 0 then begin
- if KLen+1 < KeyLength then
- K := K+#0+Char(Hi(KW));
- end
- else
- K := K+AddKey(KW);
-
- end
- {Command mode}
- else begin
- {$IFDEF UseMouse}
- {remap mouse commands}
- case Hi(KW) of
- $ED : {ClickBoth - toggle scroll lock}
- KFlag := KFlag xor SMask;
- $E9..$EF : {remap other mouse buttons}
- KW := ButtonCodes[Hi(KW)];
- end;
- {$ENDIF}
-
- if (KW <> $ED00) then
- case Lo(KW) of
- 00 : {Extended key}
- if KLen+1 < KeyLength then
- K := K+#0+Char(Hi(KW));
- 08 : {Backspace}
- if KLen > 0 then begin
- Dec(KLen);
- if (KLen > 0) and (K[KLen] = #0) then
- Dec(KLen);
- end;
- 13 : {Enter}
- Done := True;
- 27 : {Esc}
- begin
- K := B;
- Done := True;
- end;
- 67, 99 : {C - clear}
- KLen := 0;
- 82, 114 : {R - restore}
- K := B;
-
- 65..90, 97..122 : {alpha keys-map to control chars}
- K := K+AddKey(KW);
-
- else
- K := K+Char(KW);
- end;
- end;
- until Done;
-
- {restore previous prompt}
- StatMessage(BrowsePrompt);
-
- with Key do begin
- Keys := K;
- Modified := (K <> B);
- if Modified or (KLen = 0) then
- Conflict := False;
- end;
- end;
-
- procedure DrawPage(FirstCmd : Integer);
- {-Write a full page of commands, starting at FirstC}
- var
- Row : Integer;
- Cmd : Integer;
- begin
- Row := FirstRow;
- Cmd := FirstCmd;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- while (Row <= LastRow) and (Cmd <= NMaps) do begin
- DrawCmd(M^[Cmd], Row);
- Inc(Row);
- Inc(Cmd);
- end;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- end;
-
- procedure EditKeys(Msg : String80; var TopCmd, CurCmd, ColNum : Integer);
- {-Edit the keys in P^}
- var
- MapCmd : Integer;
- MapIndex : Integer;
- OldTopCmd : Integer;
- Row : Integer;
- Col : Integer;
- R : Integer;
- KW : Word;
- K : KeyRec;
- {$IFDEF UseMouse}
- MRow, MCol : Byte;
- NewRow, NewColNum : Byte;
- {$ENDIF}
- begin
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- Window(1, FirstRow, 80, LastRow);
-
- {$IFDEF UseMouse}
- MouseWindow(1, FirstRow, 80, LastRow);
- {$ENDIF}
-
- ClrScr;
- Window(1, 1, 80, LastRow);
- StatMessage(BrowsePrompt);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
-
- {Initialize pick state}
- DrawPage(TopCmd);
- Row := FirstRow+(CurCmd-TopCmd);
- repeat
- {Perform display mapping}
- MapCmd := M^[CurCmd];
- if MapCmd <> 0 then begin
- MapIndex := (MapCmd-1)*3+1+ColNum;
- K := P^[MapIndex];
- end;
- case ColNum of
- 0 : Col := PriMinCol;
- 1 : Col := SecMinCol;
- 2 : Col := TerMinCol;
- end;
- GoToXY(Col, Row);
-
- {$IFDEF UseMouse}
- MapLeftButton := False;
- {$ENDIF}
-
- {Get a command}
- KW := ReadKeyWord;
-
- {$IFDEF UseMouse}
- MapLeftButton := True;
- {$ENDIF}
-
- case KW of
- $1C0D : {Enter}
- if MapCmd <> 0 then begin
- EditCmd(MapCmd, K);
- P^[MapIndex] := K;
- DrawPage(TopCmd);
- end;
-
- $4800 : {Up arrow}
- if CurCmd > 1 then begin
- Dec(CurCmd);
- if Row = FirstRow then begin
- TopCmd := CurCmd;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- InsLine;
- DrawCmd(M^[CurCmd], Row);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- end
- else
- Dec(Row);
- end;
-
- $5000 : {Down arrow}
- if CurCmd < NMaps then begin
- Inc(CurCmd);
- if Row = LastRow then begin
- Inc(TopCmd);
- GoToXY(1, FirstRow);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- DelLine;
- DrawCmd(M^[CurCmd], LastRow);
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- end
- else
- Inc(Row);
- end;
-
- $4B00 : {Left Arrow}
- if ColNum > 0 then
- Dec(ColNum);
-
- $4D00 : {Right Arrow}
- if ColNum < 2 then
- Inc(ColNum);
-
- $4900 : {PgUp}
- begin
- OldTopCmd := TopCmd;
- R := FirstRow;
- while (CurCmd > 1) and (R < LastRow) do begin
- Dec(CurCmd);
- if Row = FirstRow then
- TopCmd := CurCmd
- else
- Dec(Row);
- Inc(R);
- end;
- if OldTopCmd <> TopCmd then
- DrawPage(TopCmd);
- end;
-
- $5100 : {PgDn}
- begin
- OldTopCmd := TopCmd;
- R := FirstRow;
- while (CurCmd < NMaps) and (R < LastRow) do begin
- Inc(CurCmd);
- if Row = LastRow then
- Inc(TopCmd)
- else
- Inc(Row);
- Inc(R);
- end;
- if TopCmd <> OldTopCmd then
- DrawPage(TopCmd);
- end;
-
- $4700 : {Home}
- if CurCmd > 1 then begin
- CurCmd := 1;
- TopCmd := 1;
- Row := FirstRow;
- ColNum := 0;
- DrawPage(TopCmd);
- end;
-
- $4F00 : {End}
- if CurCmd < NMaps then begin
- if LastRow-FirstRow+1 > NMaps then
- Row := FirstRow+NMaps-1
- else
- Row := LastRow;
- CurCmd := NMaps;
- TopCmd := NMaps-(Row-FirstRow);
- ColNum := 2;
- DrawPage(TopCmd);
- end;
-
- $1372, $1352 : {r, R}
- begin
- P^ := OUK;
- DrawPage(TopCmd);
- end;
-
- {$IFDEF UseMouse}
- Integer($EF00) : {left mouse button}
- if MouseInstalled then begin
- MRow := MouseKeyWordY;
- MCol := MouseKeyWordX+MouseXLo;
-
- if MRow <= NMaps then begin
- {find the new row and column}
- NewRow := MRow+MouseYLo;
- if (MCol <= PriMaxCol) then
- NewColNum := 0
- else if (MCol <= SecMaxCol) then
- NewColNum := 1
- else
- NewColNum := 2;
-
- if (Row = NewRow) and (ColNum = NewColNum) then begin
- {cursor already in right place--same as <Enter>}
- if MapCmd <> 0 then begin
- EditCmd(MapCmd, K);
- P^[MapIndex] := K;
- DrawPage(TopCmd);
- end;
- end
- else begin
- {move to new row/column}
- Row := NewRow;
- ColNum := NewColNum;
- CurCmd := TopCmd+Pred(MRow);
- end;
- end;
- end;
- {$ENDIF}
-
- $011B : {Esc}
- Exit;
- end;
- until False;
- end;
-
- procedure InstallKeys(Msg : String80;
- var UK : UnpackedKeyArray;
- var Names; NumNames : Word;
- var Map; NumMaps : Word;
- MaxBytes : Word);
- {-Install specified keylist}
- var
- ChangesMade : Boolean;
- I, J, ColNum : Integer;
- CurCmd, TopCmd : Integer;
- Code : Byte;
- begin
- {Put parameters into globals for easier access}
- P := @UK;
- N := @Names;
- NNames := NumNames;
- M := @Map;
- NMaps := NumMaps;
-
- {start with first command}
- CurCmd := 1;
- TopCmd := 1;
- ColNum := 0;
-
- {Save backup copy of keys}
- OUK := UK;
-
- repeat
- {Random access editing}
- EditKeys(Msg, TopCmd, CurCmd, ColNum);
-
- {$IFDEF UseMouse}
- FullMouseWindow;
- {$ENDIF}
-
- ChangesMade := CheckModifiedFlags(UK, MaxCommands);
- if ChangesMade then
- StatMessage('Checking for conflicts...');
- if ChangesMade and ConflictsFound(UK, MaxCommands) then begin
- {display error message}
- PressEsc('Conflicts found');
-
- {find first conflict}
- I := 1;
- while not UK[I].Conflict do
- Inc(I);
- Code := UK[I].CommandCode;
- CurCmd := 1;
- while M^[CurCmd] <> Code do
- Inc(CurCmd);
-
- {calculate new TopCmd based on CurCmd}
- J := LastRow-FirstRow;
- if (CurCmd < TopCmd) or (CurCmd > TopCmd+J) then begin
- TopCmd := CurCmd;
- if (TopCmd+J > NumMaps) then
- TopCmd := NumMaps-J;
- if TopCmd < 1 then
- TopCmd := 1;
- end;
-
- {calculate new ColNum}
- ColNum := Pred(I) mod 3;
- end
- else begin
- {calculate size of packed key array}
- if ChangesMade and (SizeKeys(UK, MaxCommands) > MaxBytes) then
- {Keys too big to fit}
- PressEsc('Keys won''t fit in installation area')
- else begin
- Modified := Modified or ChangesMade;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- Window(1, FirstRow, 80, LastRow);
- ClrScr;
- Window(1, 1, 80, 25);
- ClrStatLine;
-
- {$IFDEF UseMouse}
- if MouseInstalled then
- ShowMouse;
- {$ENDIF}
- Exit;
- end;
- end;
- until False;
- end;
-
- procedure Stop(Installed : Boolean);
- {-Clean up at end}
- begin
- {$IFDEF UseMouse}
- if MouseInstalled then
- HideMouse;
- {$ENDIF}
-
- if LastMode <> OrigMode then begin
- TextMode(OrigMode);
- TextAttr := OrigAttr;
- end
- else begin
- TextAttr := OrigAttr;
- ClrScr;
- end;
-
- if Installed then
- WriteLn('Changes saved')
- else
- WriteLn('Files not changed');
- Halt;
- end;
-
- procedure SaveAndExit;
- {-If modified, prompt to install changes}
- begin
- if Modified and PromptYesNo('Install changes permanently? (Y/N) ') then begin
- {pack the key arrays}
- Pack;
-
- {store the packed key arrays}
- Store;
-
- {done}
- Stop(True);
- end
- else
- {done}
- Stop(False);
- end;
-
- begin
- {open TPU files and find installation areas}
- Open;
-
- {load the installation areas}
- Load;
-
- {unpack the keystroke arrays}
- Unpack;
-
- {set up display, colors, etc}
- Init;
-
- {Initialize the main menu}
- InitMenu(MainMenu);
-
- repeat
- {get menu choice}
- StatMessage('Select unit to install, or press <Esc> to quit');
- Key := MenuChoice(MainMenu, Ch);
-
- if MenuCmdNum = MKSSelect then begin
- case Key of
- 1 : {TPEDIT}
- InstallKeys(EditFileName, EditUK, EditNames, RSuser9-2,
- EditMap, EditDisplay, EditKeyMax);
- 2 : {TPENTRY}
- InstallKeys(EntryFileName, EntryUK, EntryNames, ESmouse-2,
- EntryMap, EntryDisplay, EntryKeyMax);
- 3 : {TPHELP}
- InstallKeys(HelpFileName, HelpUK, HelpNames, HKSUser3-2,
- HelpMap, HelpDisplay, HelpKeyMax);
- 4 : {TPMENU}
- InstallKeys(MenuFileName, MenuUK, MenuNames, MKSuser3-2,
- MenuMap, MenuDisplay, MenuKeyMax);
- 5 : {TPPICK}
- InstallKeys(PickFileName, PickUK, PickNames, PKSUser3-2,
- PickMap, PickDisplay, PickKeyMax);
- end;
- end;
- until MenuCmdNum = MKSExit;
-
- {clean up}
- SaveAndExit;
- end.