home *** CD-ROM | disk | FTP | other *** search
- #include "pt.h"
- #include "direct.h"
- #include "malloc.h"
- #include "string.h"
- #include "conio.h"
- #include "io.h"
- #include "process.h"
- #include "stdlib.h"
- #include "time.h"
-
- extern void criterr(void);
- extern void overlay(int);
-
- void
- /* XTAG:main */
- main(argc, argv)
- unsigned char *argv[];
- {
-
- /**************************************************************************/
- /* Declare the external variables */
- /**************************************************************************/
-
- extern struct window *windows, *windowList;
- extern unsigned char msgBuffer[];
- extern unsigned char startDirectory[];
- extern unsigned char currentDirectory[];
- extern unsigned char startDrive;
- extern unsigned char currentDrive;
- extern unsigned char scrMapReset;
- extern unsigned int dispMemory;
- extern int debug;
- extern union REGS rin, rout;
- extern struct window *selWindow;
- extern long selBegin, selEnd;
- extern int selMode;
- extern int undoSize;
- extern int nextChange;
- extern int addHandle;
- extern unsigned char addFile[];
- extern long addPosition;
- extern int brIntCom[];
- extern int initialWindows;
- extern struct changeItem scrapBuffer;
- extern struct SREGS segRegs;
- extern unsigned char saveVideoMode;
- extern int scrRows, scrCols;
- extern unsigned char filePattern[];
- extern unsigned char tagPattern[];
- extern unsigned char tagMarker[];
- extern struct window *activeWindow;
- extern int menuLine;
- extern int descrFileId;
- extern jmp_buf breakEnv;
- #ifdef OVERLAYS
- extern int overlayVector;
- #endif
- extern int readOnly;
- extern int supressFileMsgs;
- extern struct menuBlock far *menus[];
- extern unsigned char *copyRightMsg;
- extern unsigned char *userMessages[];
- extern unsigned char far * fileHandleTable;
- extern int maxFiles;
- extern struct openFile *files;
- extern time_t timeOfLastSave;
- extern unsigned char far *menuSpace;
-
- /**************************************************************************/
- /* Declare the local variables */
- /**************************************************************************/
-
- int i, j, k, row, col, where;
- int deltaRow, deltaCol, nWindows, topMode;
- unsigned char *p;
- unsigned int far * fp;
- unsigned char far * oldTable;
- struct window *w;
- int lastState = 0; /* restore the last state of the editor */
- int hideFiles;
-
- /**************************************************************************/
- /* Save the old video mode and set a compatible video mode to use */
- /**************************************************************************/
-
- /* determine the current display mode */
- rin.h.ah = 15;
- int86(0x10, &rin, &rout);
- saveVideoMode = rout.h.al;
-
- switch( saveVideoMode ) {
- case 7: /* monochrome display */
- dispMemory = 0xB000;
- break;
- case 4: /* 320x200 color */
- rin.h.al = 3; /* 80x25 color */
- goto setMode;
- case 5: /* 320x200 b&w */
- case 6: /* 640x200 b&w */
- rin.h.al = 2; /* 80x25 b&w */
- setMode:
- rin.h.ah = 0; /* set video mode */
- int86(0x10, &rin, &rout);
- default:
- dispMemory = 0xB800;
- break;
- }
-
- /* get the segment registers */
- segread(&segRegs);
-
- /**************************************************************************/
- /* Get the current directory and drive so we can restore then on exit */
- /**************************************************************************/
- (void)getcwd(&startDirectory[0], FILENAMESIZE);
- strcpy(currentDirectory, startDirectory);
- startDrive = getDefaultDrive();
- currentDrive = startDrive;
-
- /**************************************************************************/
- /* Read in the initialization file but first */
- /* set the variables it might change from their default values */
- /**************************************************************************/
-
- /* set up the menu blocks */
-
- /* This one is for dynamic menus (OPTIONS and TOPLIST and HELP) */
- menus[0] = (struct menuBlock far *)_fmalloc(sizeof(struct menuBlock));
-
- /* initialize the other menus to not yet allocated */
- for(i = 1; i < NMENUS; ++i)
- menus[i] = (struct menuBlock far *)NULL;
-
- /* set up space for the menu characters */
- menuSpace = (unsigned char far *)_fmalloc(MENUSPACE);
-
- /* set up variables */
- addFile[0] = '\0';
- strcpy(filePattern, "*.*");
- strcpy(tagPattern, "*.c|*.h|*.asm");
- strcpy(tagMarker, "XTAG:");
-
- /* set up the default asciiMap so that setup can alter it */
- initKeymaps();
-
- /* read the setup file */
- if( setup() ) {
- cprintf(
- "Cannot find \"pt.ini\" in this directory or the PATH.\r\nExiting.\r\n");
- exit(1);
- }
-
- /**************************************************************************/
- /* Allocate a new file handle table to allow more than 20 open files */
- /* then allocate the open file table and the window structures */
- /**************************************************************************/
- if( _osmajor == 3 ) { /* only works for DOS 3.x */
- if( 0 <= _osminor && _osminor <= 20 ) {
- /* version 3.00, 3.10, and 3.20 only */
- /* allocate space for the file handles */
- fileHandleTable = (unsigned char far *)_fmalloc(maxFiles);
- /* find the current file handle table in the PSP */
- FP_OFF(fp) = 0x32; /* at 0x32 in PSP */
- FP_SEG(fp) = _psp;
- row = *fp; /* get the size of the current table */
- FP_OFF(oldTable) = *(fp+1); /* addr of current table */
- FP_SEG(oldTable) = *(fp+2);
- /* copy current table to new table */
- for(i = 0; i < row; ++i )
- fileHandleTable[i] = oldTable[i];
- /* mark the rest of the handles in the new table */
- /* as unopened (0xFF) */
- for(i = row; i < maxFiles; ++i)
- fileHandleTable[i] = 0xFF;
- /* install the new table by changing the PSP fields */
- *fp = (unsigned int)maxFiles;
- *(fp+1) = FP_OFF(fileHandleTable);
- *(fp+2) = FP_SEG(fileHandleTable);
- } else if( _osminor >= 30 ) {
- /* we can do the same thing wiht a simple DOS call! */
- rin.h.ah = 0x67; /* set handle count */
- /* Steve Gibson's TSR example added the +1 so I am too */
- /* just to be sure that I get enough handles */
- rin.x.bx = maxFiles + 1;
- intdos(&rin, &rout);
- } else
- maxFiles = 20;
- } else
- maxFiles = 20;
-
- /* allocate an extra file structure for use in copymove.c (insScrap) */
- files = (struct openFile *)malloc((maxFiles+1) * sizeof(struct openFile));
- windows = (struct window *)malloc(maxFiles * sizeof(struct window));
- if( files == NULL || windows == NULL) {
- cprintf("Too many files (out of memory). Reduce maxFiles\r\n");
- exit(1);
- }
-
- /**************************************************************************/
- /* call various initialization routines */
- /**************************************************************************/
-
- initWindows();
- initFileio();
- initChanges();
-
- /**************************************************************************/
- /* Process the command line options and arguments */
- /**************************************************************************/
-
- for(i = 1; i < argc; i++) {
- if( argv[i][0] == '/' || argv[i][0] == '-' ) {
- for(j = 1; argv[i][j] != '\0'; j++) {
- switch( argv[i][j] ) {
-
- case 'l': /* restore last state */
- lastState = 1;
- break;
-
- case 'o': /* overlaid windows */
- initialWindows = 0;
- break;
-
- case 'h': /* horizontal split */
- initialWindows = 1;
- break;
-
- case 'v': /* vertical split */
- initialWindows = 2;
- break;
-
- case 'r': /* read only mode */
- readOnly = 1;
- break;
-
- case 'd': /* debug flag initial value */
- debug = argv[i][++j] - '0';
- break;
-
- default:
- cprintf("usage: pt [/hlov] [file1] [file2] ...\r\n");
- break;
- }
- }
- } else /* we have reached the end of the comamnd line options */
- break;
- }
-
- initMouse(5, 10, 1);
-
- /* clear the screen */
- scrollUp(0, 0, 0, scrRows-1, scrCols-1, 0x7);
-
- /**************************************************************************/
- /* create the menu line */
- /**************************************************************************/
-
- row = (menuLine < 0 ? (scrRows-1) : 0);
- redrawBox(row, 0, row, scrCols-1);
- updateScreen(row, row);
-
- /**************************************************************************/
- /* See if "pt.msg" (the command descriptions file) is present. */
- /**************************************************************************/
-
- p = findFile("pt.msg");
- if( p == NULL )
- descrFileId = -1;
- else
- descrFileId = getFileId(p);
-
- /**************************************************************************/
- /* create the additions file */
- /**************************************************************************/
-
- strcat(addFile, "pttemp.add");
- makeName(addFile);
- addPosition = 0;
- addHandle = creatls(addFile, 0);
- if( addHandle < 0 ) {
- cprintf(addHandle==-4 ? userMessages[HANDLEMSG] :
- "Create of 'pttemp.add' failed", 0);
- exit(1);
- }
-
- /**************************************************************************/
- /* create the initial windows */
- /**************************************************************************/
-
- nWindows = argc - i; /* number of initial windows */
- if( nWindows == 0 )
- nWindows = 1; /* avoid zero-divide */
- topMode = CRBOTTOM;
- where = (menuLine > 0 ? 1 : 0);
- switch( initialWindows ) {
- default:
- case 0: /* overlaid windows */
- deltaCol = 0;
- deltaRow = 0;
- row = where;
- col = 0;
- break;
- case 1: /* horizontal split */
- deltaCol = 0;
- deltaRow = (scrRows-1)/nWindows;
- row = where;
- col = 0;
- topMode = CRTOP;
- break;
- case 2: /* vertical split */
- deltaCol = (scrCols-3)/nWindows;
- deltaRow = 0;
- row = where;
- col = 0;
- topMode = CRTOP;
- break;
- }
-
- selWindow = NULL;
- where = scrRows - 1;
- if( menuLine < 0 ) /* bottom line menu? */
- --where; /* make room for it */
- supressFileMsgs = 1;
- hideFiles = 0;
-
- for(k = i; k < argc; k++) {
- if( strcmp( argv[k], "/H" ) == 0 ) {
- hideFiles = !hideFiles;
- continue;
- }
- sprintf(msgBuffer, "Opening file %s", argv[k]);
- msg(msgBuffer, 1);
- if( access(argv[k], 0) == -1) {
- sprintf(msgBuffer, "y to create «%s»: ", argv[k]);
- p = getInput(msgBuffer, "y", 1);
- if( p == NULL || tolower(*p) != 'y' ) {
- msg("Window not created", 1);
- continue;
- }
- closels(creatls(argv[k], 0));
- }
- w = createWindow(argv[k], row, col, where, scrCols-1, topMode, 0);
- if( hideFiles )
- hideWindow(w);
- row += deltaRow;
- col += deltaCol;
- }
- supressFileMsgs = 0;
-
- /**************************************************************************/
- /* set up the software interrupt and other things */
- /**************************************************************************/
-
- #ifdef OVERLAYS
- movedata(0, overlayVector * 4, segRegs.ds, (unsigned int)&saveOldVector, 4);
- overlay(overlayVector);
- #endif
-
- /* set up the critical error handler */
- criterr();
-
- /* if lastState then read the restore file that records the last state */
- /* the editor was in and restore that state */
- if( lastState ) {
- restoreLastState();
- }
-
- /* the top window is the first active window */
- activeWindow = windowList;
- if( windowList != NULL ) {
- redoBorders(0);
- updateScreen(0, scrRows-1);
- }
-
- /**************************************************************************/
- /* banner message */
- /**************************************************************************/
-
- msg(copyRightMsg, 1);
-
- /**************************************************************************/
- /* set up control break processing */
- /**************************************************************************/
-
- /* return here if a control-break is pressed */
- if( setjmp(breakEnv) != 0 ) {
- /***initMouse(5, 10, 1);***/
- redrawBox(0, 0, scrRows-1, scrCols-1);
- updateScreen(0, scrRows-1);
- msg("Ctrl-Break!", 2);
- }
-
- /* set up the control break interrupt handler */
- signal(SIGINT, ctrlBreak);
-
- /* initialize the timeOfLastSave variable */
- timeOfLastSave = time(NULL);
-
- /**************************************************************************/
- /* start the main processing loop */
- /**************************************************************************/
-
- /* starting reading user editing commands */
- /* look for keystrokes and mouse buttons */
-
- mainLoop();
-
- /* reset the video mode */
- rin.h.ah = 0; /* set video mode */
- rin.h.al = saveVideoMode;
- int86(0x10, &rin, &rout);
-
- /* reset the cursor */
- if( dispMemory == 0xB000 )
- setCType(12, 13);
- else
- setCType(6, 7);
- col = getDOScolor();
-
- /* clear the screen */
- scrollUp(0, 0, 0, scrRows-1, scrCols-1, col);
- setCPos(0, 0);
-
- /* restore the original current directory and delete the add file */
- setDefaultDrive(startDrive);
- chdir(startDirectory);
- closels(addHandle);
- delete(addFile);
-
- #ifdef OVERLAYS
- /* restore the interrupt vector */
- movedata(segRegs.ds, (unsigned int)&saveOldVector, 0, overlayVector * 4, 4);
- #endif
-
- exit(0); /* exit cleanly */
- } /* end of main */
-
- /* this loop is the main processing loop of Point */
- void pascal
- /* XTAG:mainLoop */
- mainLoop()
- {
- extern unsigned char msgBuffer[];
- extern struct window *activeWindow;
- extern time_t timeOfLastSave;
- extern int autoSaveInterval;
-
- unsigned char ch, scan;
- int where;
-
- while(1) {
-
- /* save if the time period has elapsed */
- if( autoSaveInterval > 0
- && (int)((time(NULL)-timeOfLastSave)/60)>=autoSaveInterval)
- command(FSAVEALL, '\0', activeWindow);
-
- /* get any typed characters */
- if( isKeystroke() != 0 ) {
- ch = getKeystroke(&scan);
- if( interp(ch, scan) != 0 ) {
- break;
- }
- }
-
- /* get mouse position and button press status */
- if( isMouseEvent(0) ) {
- where = getMouseEvent();
- if( mouseButton(where) != 0 )
- break;
- }
- }
- }
-
- int pascal
- /* XTAG:getDOScolor */
- getDOScolor()
- {
- extern union REGS rin, rout;
-
- setCPos(0, 0);
- cprintf(" ");
- setCPos(0, 0);
- rin.h.ah = 8; /* read char/attribute */
- rin.h.bh = 0; /* page number */
- int86(0x10, &rin, &rout);
- return (int)rout.h.ah;
- }
-
- int pascal
- /* XTAG:translateKey */
- translateKey(ch, scanCode)
- unsigned char ch, scanCode;
- {
- extern int keyMap[];
- extern int asciiMap[];
-
- register int fn;
-
- /* if extended code, find the function it maps to */
- if( ch == 0 )
- fn = keyMap[scanCode];
- else { /* return the ASCII mapped character */
- if( ch < 128 )
- fn = asciiMap[ch];
- else
- fn = FCHARACTER;
- if( ch == '+' && scanCode == 78 )
- fn = FLEFTMBUTTON;
- else if( ch == '-' && scanCode == 74 )
- fn = FRIGHTMBUTTON;
- }
- return fn;
- }
-
- int pascal
- /* XTAG:interp */
- interp(c, c2)
- unsigned char c, c2;
- {
- extern union REGS rin, rout;
- extern int menuRow, menuCol;
- extern struct window *activeWindow;
- extern unsigned char msgBuffer[];
-
- int fn;
-
- /* handle things that we need to do every command */
- handleTempItems();
-
- fn = translateKey(c, c2);
- /* if extended code, find the function it maps to */
- if( c == 0 )
- c = c2;
- menuRow = 7;
- menuCol = 30;
- return command(fn, c, activeWindow);
- }
-
- void pascal
- /* XTAG:msg */
- msg(s, type)
- unsigned char *s;
- int type;
- /* type = 0 --> erase even a sticky message */
- /* type = 1 --> type message, but if "" redo the sticky message */
- /* type = 2 --> a prompt message */
- /* type = 3 --> an error message */
- /* type = 4 --> a sticky message */
- /* type = 5 --> message on alternative message line */
- {
- extern int debug;
- extern unsigned char border2[];
- extern unsigned char borderColor;
- extern unsigned char msgColor, promptColor, errorColor;
- extern struct window *windowList;
- extern int menuLine;
- extern int lastOnTopline;
- extern int isMessage;
- extern int scrRows, scrCols;
-
- register int color;
- int i, row, col;
- static unsigned char stickyMessage[80] = {0};
-
- /* try to keep from erasing messages because of trying to erase */
- /* the top line (and popup menu) command descriptions */
- lastOnTopline = 0;
- row = scrRows - 1;
- if( menuLine < 0 )
- --row;
- if( type == 5 )
- --row;
- color = msgColor; /* the most common case */
- switch( type ) {
- default:
- case 0: /* erase all messages */
- stickyMessage[0] = '\0';
- case 1: /* type message -- or reinstate a sticky message */
- if( s[0] == '\0' ) { /* erase all but sticky */
- s = &stickyMessage[0];
- type = 4; /* revert to sticky msg type */
- }
- break;
- case 2: /* prompt message */
- color = promptColor;
- break;
- case 3: /* error message */
- color = errorColor;
- break;
- case 4: /* sticky messages */
- strncpy(stickyMessage, s, 79);
- break;
- case 5: /* alternative message line */
- color = promptColor;
- break;
- }
-
- /* first set up the bottom line of the screen correctly */
- redoBorders(1);
- i = strlen(s);
- if( type == 0 || i == 0 ) {
- updateScreen(row, row);
- return;
- }
-
- /* only set the screenMap for the length of the message */
- /* unless there are not windows and the previous message */
- /* will not have been erased */
- col = (windowList==NULL ? 78 : i);
- setMap(row, 1, row, i, 0, msgColor);
-
- /* remember that a message is there */
- /* message type==0 clears the message line */
- isMessage = type;
- col = 1;
- for(i = 0; s[i] != '\0' && col < (scrCols-1); i++)
- displayChar(row, col++, s[i], color);
- updateScreen(row, row);
-
- /* Pause for errors so the user is sure to see the message. */
- /* No need for instructions since anyone will try hitting */
- /* a key or two if things seem stuck. Regular user's are not */
- /* supposed to see these messages anyway (only me) */
- if( type == 3 ) {
- incon();
- msg("", 1); /* clear the error message */
- }
- }
-
- void
- /* XTAG:ctrlBreak */
- ctrlBreak()
- {
- extern jmp_buf breakEnv;
-
- longjmp(breakEnv, 1);
- }
-