home *** CD-ROM | disk | FTP | other *** search
- /* winstuff.c - Windows specific sources */
- /* for the Borland C 3.0 */
-
- #include "xlisp.h"
- #include "osdefs.h"
- #include "winstuff.h"
-
- #include <dos.h>
- #include <process.h>
- #include <math.h>
- #include <io.h>
- #include <float.h>
- #ifdef TIMES
- #include <time.h>
- #endif
-
- #define LBSIZE 200
-
- #ifdef __TURBOC__
- unsigned _Cdecl _stklen = 16384; /* set up reasonable stack */
- #ifdef MEDMEM
- unsigned _Cdecl _heaplen = 4096; /* compress the near heap */
- #endif
- #endif
-
- /* Server variables */
- int GotClientReq; /* TRUE , if the server DLL
- is ready to send a packet */
- int ServerReady; /* TRUE , if the server packet
- is ready to be processed */
- int ServerPacket; /* TRUE , if the server is
- executing a client packet */
- HANDLE ReplyBlock; /* Area to store the
- reply text */
- int ReplyIndex; /* Index in the reply area */
-
- /* external variables */
- extern LVAL s_unbound,s_dosinput,true;
- extern FILEP tfp;
-
- /* exported variables */
- int lposition;
-
- int ServerTask; /* TRUE , if the system runs in Lisp server mode */
- #define KB_FIFOSIZE 256
- char kFifo[ KB_FIFOSIZE ];
- int kFifoHead,kFifoTail;
- HWND MainWindow; /* Handle to the main window */
- HANDLE hInst; /* Instance handle */
- HANDLE hAccel; /* Accelerator handle */
- int CursorVisible; /* True , if the cursor is
- visible */
- int FontWidth; /* The width of the actual
- font */
- int FontHeight; /* The height of the actual
- font */
- int MenuEnabled; /* TRUE , if the popup command
- shortcuts are active */
- /* The MenuCommand variable belongs to the popup Lisp command
- logic. When a popup Lisp command is selected , a function
- code is written into this variable then the read loop is
- broken by placing an EOF into the keyboard buffer. The Lisp
- uplevel command loop then executes the command */
- int MenuCommand;
-
-
- #define SCREENBUFSIZE 8192
- HANDLE ScreenBuf; /* Screen buffer handle */
- int sTailIndex,sHeadIndex; /* Screen buffer indices */
- int sTPosIndex; /* The tail of the screen
- buffer */
- int ScreenXPos,ScreenYPos; /* X and Y output position */
-
- /* File dialog variables */
- static char szDefExt[5]; /* Default extension */
- char szFileName[96]; /* Name of the file */
- static char szFileSpec[16];
- static OFSTRUCT pof;
- static WORD wFileAttr;
-
- /* The size of the client area */
- static int cxSize,cySize;
-
- /* local variables */
- static char lbuf[LBSIZE];
- static int lpos[LBSIZE];
- static int lindex;
- static int lcount;
-
- /* forward declarations */
- void XNEAR xinfo(void);
- void XNEAR xflush(void);
- int XNEAR xgetc(void);
- void XNEAR xputc(int ch);
-
- /* Dialog template structure - missing from WINDOWS.H */
- typedef struct {
- long dtStyle;
- BYTE dtItemCount;
- int dtX;
- int dtY;
- int dtCX;
- int dtCY;
- char dtMenuName[];
- char dtClassName[];
- char dtCaptionText[];
- } DLGTEMPLATE;
- typedef DLGTEMPLATE FAR *LPDLGTEMPLATE;
-
- #define EXE_NAME_MAX_SIZE 128
- char helpfilename[ EXE_NAME_MAX_SIZE + 1 ];
-
- /* enables the popup commands */
- void EnableMenuCommands()
- {
- MenuEnabled = TRUE;
- }
-
- /* disables the popup commands */
- void DisableMenuCommands()
- {
- MenuEnabled = FALSE;
- }
-
- /* Windows message loop. Waits for a character to be typed or the closing
- of the application. Returns 0 if the application was closed */
- static int XNEAR MessageLoop()
- {
- MSG msg;
-
- while( !GotClientReq && ( kFifoHead == kFifoTail )
- && GetMessage( &msg , NULL , NULL , NULL ) )
- if( !TranslateAccelerator( MainWindow , hAccel , &msg ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- };
- return( kFifoHead - kFifoTail );
- }
-
- /* Shows the caret at the current position */
- static void XNEAR XShowCursor()
- {
- if( MainWindow == GetFocus() )
- {
- SetCaretPos( ScreenXPos , ScreenYPos );
- ShowCaret( MainWindow );
- }
- }
-
- /* Hides the caret */
- static void XNEAR XHideCursor()
- {
- HDC hdc;
- HBRUSH DelBrush;
- RECT DelRect;
-
- HideCaret( MainWindow );
- hdc = GetDC( MainWindow );
- SetRect( &DelRect , ScreenXPos , ScreenYPos ,
- ScreenXPos + 2 , ScreenYPos + FontHeight );
- DelBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
- FillRect( hdc , &DelRect , DelBrush );
- DeleteObject( DelBrush );
- ReleaseDC( MainWindow , hdc );
- }
-
- /* Returns the first occurence of the ch character in the str
- string. Searches from the beginning of the string */
- LPSTR lstrchr( LPSTR str , char ch )
- {
- while( *str )
- {
- if( ch == *str )
- return str;
- str = AnsiNext( str );
- }
- return NULL;
- }
-
- /* Returns the first occurence of the ch in the str string.
- Searches from the end of the string */
- LPSTR lstrrchr( LPSTR str , char ch )
- {
- LPSTR strl = str + lstrlen( str );
-
- do
- {
- if( ch == *strl )
- return strl;
- strl = AnsiPrev( str,strl );
- }
- while( strl > str );
-
- return NULL;
- }
-
- /* FileOpen dialog procedure */
- BOOL FAR PASCAL _export FileOpenDlgProc( HWND hDlg , WORD message ,
- WORD wParam , LONG lParam )
- {
- char cLastChar;
- short nEditLen;
-
- switch( message )
- {
- case WM_INITDIALOG:
- SendDlgItemMessage( hDlg,IDD_FNAME,EM_LIMITTEXT,80,0L );
- DlgDirList( hDlg,szFileSpec,IDD_FLIST,IDD_FPATH,
- wFileAttr );
- SetDlgItemText( hDlg,IDD_FNAME,szFileSpec );
- return TRUE;
-
- case WM_COMMAND:
- switch( wParam )
- {
- /* List box messages */
- case IDD_FLIST:
- switch( HIWORD( lParam ) )
- {
- case LBN_SELCHANGE:
- if( DlgDirSelect( hDlg,szFileName,
- IDD_FLIST ) )
- lstrcat( szFileName,szFileSpec );
- SetDlgItemText( hDlg,IDD_FNAME,szFileName );
- return TRUE;
-
- case LBN_DBLCLK:
- if( DlgDirSelect( hDlg,szFileName,
- IDD_FLIST ) )
- {
- lstrcat( szFileName,szFileSpec );
- DlgDirList( hDlg,szFileName,IDD_FLIST,
- IDD_FPATH,wFileAttr );
- SetDlgItemText( hDlg,IDD_FNAME,
- szFileSpec );
- }
- else
- {
- SetDlgItemText( hDlg,IDD_FNAME,
- szFileName );
- SendMessage( hDlg,WM_COMMAND,IDOK,0L );
- }
- return TRUE;
- }
- break;
-
- case IDD_FNAME:
- if( HIWORD(lParam) == EN_CHANGE )
- EnableWindow( GetDlgItem( hDlg,IDOK ),
- (BOOL)SendMessage(LOWORD(lParam),
- WM_GETTEXTLENGTH,0,0L) );
- return TRUE;
-
- case IDOK:
- GetDlgItemText( hDlg,IDD_FNAME,szFileName,80 );
- nEditLen = lstrlen( szFileName );
- cLastChar = *AnsiPrev( szFileName,szFileName +
- nEditLen );
- if( ( cLastChar == '\\' ) || ( cLastChar == ':' ) )
- lstrcat( szFileName,szFileSpec );
- if( lstrchr( szFileName,'*' ) ||
- lstrchr( szFileName,'?' ) )
- {
- if( DlgDirList( hDlg,szFileName,IDD_FLIST,
- IDD_FPATH,wFileAttr ) )
- {
- lstrcpy( szFileSpec,szFileName );
- SetDlgItemText( hDlg,IDD_FNAME,szFileSpec );
- }
- else
- MessageBeep( 0 );
- return TRUE;
- }
- lstrcat( lstrcat( szFileName,"\\" ),szFileSpec );
- if( DlgDirList( hDlg,szFileName,IDD_FLIST,
- IDD_FPATH,wFileAttr ) )
- {
- lstrcpy( szFileSpec,szFileName );
- SetDlgItemText( hDlg,IDD_FNAME,szFileSpec );
- return TRUE;
- }
- szFileName[ nEditLen ] = '\0';
- if( -1 == OpenFile( szFileName,(LPOFSTRUCT)&pof,
- OF_READ | OF_EXIST ) )
- {
- lstrcat( szFileName,szDefExt );
- if( -1 == OpenFile( szFileName,(LPOFSTRUCT)&pof,
- OF_READ | OF_EXIST ) )
- {
- MessageBeep( 0 );
- return TRUE;
- }
- }
- lstrcpy( szFileName,AnsiNext(
- lstrrchr( pof.szPathName,'\\') ) );
- OemToAnsi( szFileName,szFileName );
- EndDialog( hDlg,TRUE );
- return TRUE;
-
- case IDCANCEL:
- EndDialog( hDlg,FALSE );
- return TRUE;
-
- } /* switch( wParam ) */
- } /* switch( message ) */
- return FALSE;
- }
-
- /* About dialog procedure */
- BOOL FAR PASCAL _export AboutDlgProc( HWND hDlg , WORD message ,
- WORD wParam , LONG lParam )
- {
- switch( message )
- {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- switch( wParam )
- {
- case IDOK:
- case IDCANCEL:
- EndDialog( hDlg,0 );
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-
- /* Executes a file dialog */
- int DoFileDialog( char Extension[] )
- {
- int ErrorCode;
- FARPROC lpfnDlgProc;
-
- wFileAttr = 0x4010;
-
- strcpy( szFileSpec,"*" );
- strcat( szFileSpec,Extension );
- strcpy( szDefExt,Extension );
- lpfnDlgProc = MakeProcInstance( FileOpenDlgProc,hInst );
- ErrorCode = DialogBox( hInst,"FileOpen",MainWindow,lpfnDlgProc );
- FreeProcInstance( lpfnDlgProc );
- return ErrorCode;
- }
-
- /* Puts its parameter into the keyboard FIFO */
- void PutFifo( int keycode )
- {
- kFifo[ kFifoHead ] = keycode;
- kFifoHead = ++kFifoHead % KB_FIFOSIZE;
- }
-
- /* Executes a dialog box - aligns the box to the center
- of the client area. Gets the name of the box and
- the address of its callback function */
- void CenterDialogBox( char BoxName[] , FARPROC CBFunc )
- {
- FARPROC lpfnDlgProc;
- LPDLGTEMPLATE lpDlgTempl;
- HANDLE hDialog;
- long lpDlgBaseUnits;
- WORD wXDlg,wYDlg,wT;
-
- lpfnDlgProc = MakeProcInstance( CBFunc,hInst );
- hDialog = LoadResource( hInst,FindResource( hInst, BoxName ,
- RT_DIALOG ));
- lpDlgTempl = (LPDLGTEMPLATE)LockResource( hDialog );
- lpDlgBaseUnits = GetDialogBaseUnits();
- wXDlg = LOWORD( lpDlgBaseUnits );
- wYDlg = HIWORD( lpDlgBaseUnits );
- wT = ( 4*cxSize )/( 2*wXDlg );
- wT -= lpDlgTempl->dtCX/2;
- lpDlgTempl->dtX = wT;
- wT = ( 8*cySize )/( 2*wYDlg );
- wT -= lpDlgTempl->dtCY/2;
- lpDlgTempl->dtY = wT;
- UnlockResource( hDialog );
- DialogBoxIndirect( hInst,hDialog,MainWindow,lpfnDlgProc );
- FreeResource( hDialog );
- FreeProcInstance( lpfnDlgProc );
- }
-
- /* Window procedure of the main window */
- long FAR PASCAL _export WndProc( HWND hWnd , WORD message , WORD wParam ,
- LONG lParam )
- {
-
- HDC hdc;
- PAINTSTRUCT ps;
- RECT rect;
- int xpos,ypos,chwidth,idx,i;
- int sw,sh,lines,ctr;
- int ErrorCode;
- int sctr;
- char far *DispBuf;
- char string[200];
-
- switch( message )
- {
- /* XServer DLL request message */
- case XL_REQ:
- GotClientReq = TRUE;
- return 0;
- /* XServer DLL trigger message */
- case XL_TRIG:
- return 0;
-
- case WM_SIZE:
- cxSize = LOWORD( lParam );
- cySize = HIWORD( lParam );
- if( ( ( wParam == SIZEFULLSCREEN ) ||
- ( wParam == SIZENORMAL ) ) &&
- ( sHeadIndex != sTPosIndex ) )
- {
- DispBuf = GlobalLock( ScreenBuf );
- lines = cySize / FontHeight;
- idx = sHeadIndex;
- ctr = 0;
- i = 0;
- do
- {
- idx = ( idx == 0 ? SCREENBUFSIZE-1 : --idx );
- ctr += FontWidth;
- if( DispBuf[ idx ] == '\n' )
- ++i,ctr = 0;
- else
- if( ctr >= cxSize )
- ++i,ctr = FontWidth;
- }
- while( ( i < lines ) && ( idx != sTPosIndex ) );
- sTailIndex = idx;
- if( idx != sTPosIndex )
- sTailIndex = ++sTailIndex % SCREENBUFSIZE;
- GlobalUnlock( ScreenBuf );
- }
- return 0;
-
- case WM_PAINT:
- XHideCursor();
- DispBuf = GlobalLock( ScreenBuf );
- hdc = BeginPaint( hWnd , &ps );
- SetBkColor( hdc , GetSysColor( COLOR_WINDOW ) );
- SetTextColor( hdc , GetSysColor( COLOR_WINDOWTEXT ) );
- SelectObject( hdc , GetStockObject( SYSTEM_FIXED_FONT )
- );
- idx = sTailIndex;
- xpos = ypos = 0;
- sctr = 0;
- while( idx != sHeadIndex )
- {
- if( DispBuf[ idx ] == '\n' )
- {
- if( sctr )
- TextOut( hdc , 0 , ypos , string , sctr );
- sctr = 0;
- ypos += FontHeight;
- xpos = 0;
- }
- else
- {
- if( ( xpos + FontWidth ) >= cxSize )
- {
- if( sctr )
- TextOut( hdc , 0 , ypos , string , sctr );
- sctr = 0;
- ypos += FontHeight;
- xpos = 0;
- }
- string[ sctr++ ] = DispBuf[ idx ];
- xpos += FontWidth;
- }
- idx = ++idx % SCREENBUFSIZE;
- }
- if( sctr )
- TextOut( hdc , 0 , ypos , string , sctr );
- ScreenXPos = xpos;
- ScreenYPos = ypos;
- EndPaint( hWnd , &ps );
- GlobalUnlock( ScreenBuf );
- XShowCursor();
- return 0;
-
- case WM_DESTROY:
- WinHelp( MainWindow , helpfilename , HELP_QUIT , 0L );
- PostQuitMessage( 0 );
- return 0;
-
- case WM_CHAR:
- PutFifo( wParam );
- return 0;
-
- case WM_SETFOCUS:
- CreateCaret( MainWindow , NULL , 2 , FontHeight );
- if( CursorVisible )
- XShowCursor();
- return 0;
-
- case WM_KILLFOCUS:
- XHideCursor();
- DestroyCaret();
- return 0;
-
- /* Popup menu initialization message */
- case WM_INITMENUPOPUP:
- if( lParam == 0L ) /* If the File Menu */
- if( MenuEnabled )
- {
- EnableMenuItem( wParam , IDM_LISPOPEN , MF_ENABLED );
- EnableMenuItem( wParam , IDM_WSOPEN , MF_ENABLED );
- }
- else
- {
- EnableMenuItem( wParam , IDM_LISPOPEN , MF_GRAYED );
- EnableMenuItem( wParam , IDM_WSOPEN , MF_GRAYED );
- }
- return 0;
-
- /* Menu command messages */
- case WM_COMMAND:
- switch( wParam )
- {
- case IDM_LISPOPEN: /* Load Lisp source */
- /* cannot execute if the interpreter is running */
- if( !MenuEnabled )
- return 0;
- ErrorCode = DoFileDialog( ".lsp" );
- if( ErrorCode ) /* if file was selected */
- {
- PutFifo( EOF );
- MenuCommand = FUNC_LLSP;
- }
- return 0;
-
- case IDM_WSOPEN:
- if( !MenuEnabled )
- return 0;
- ErrorCode = DoFileDialog( ".wks" );
- if( ErrorCode )
- {
- PutFifo( EOF );
- MenuCommand = FUNC_LWKS;
- }
- return 0;
-
- case IDM_INFO: /* Memory info */
- xinfo();
- return 0;
-
- case IDM_EXIT: /* Exit */
- SendMessage( hWnd , WM_CLOSE , 0 , 0L );
- return 0;
-
- case IDM_INDEX:
- WinHelp( MainWindow , helpfilename , HELP_INDEX ,
- 0L );
- return 0;
- case IDM_HELPONHELP:
- WinHelp( MainWindow , helpfilename , HELP_HELPONHELP ,
- 0L );
- return 0;
-
- case IDM_ABOUT:
- CenterDialogBox( "About" , AboutDlgProc );
- return 0;
- }
- break;
-
- }
- return DefWindowProc( hWnd , message , wParam , lParam );
- }
-
- /* Math error handler */
- int CDECL matherr(struct exception *er)
- {
- char *emsg;
-
- switch (er->type) {
- case DOMAIN: emsg="domain"; break;
- case OVERFLOW: emsg="overflow"; break;
- case PLOSS: case TLOSS: emsg="inaccurate"; break;
- case UNDERFLOW: return 1;
- default: emsg="????"; break;
- }
- xlerror(emsg,cvflonum(er->arg1));
- return 0; /* never happens */
- }
-
- /* Creates the full help file path */
- void MakeHelpPathName(char *szFileName)
- {
- char * pcFileName;
- int nFileNameLen;
-
- nFileNameLen = GetModuleFileName(hInst,szFileName,EXE_NAME_MAX_SIZE);
- pcFileName = szFileName + nFileNameLen;
-
- while (pcFileName > szFileName) {
- if (*pcFileName == '\\' || *pcFileName == ':') {
- *(++pcFileName) = '\0';
- break;
- }
- nFileNameLen--;
- pcFileName--;
- }
-
- if ((nFileNameLen+12) < EXE_NAME_MAX_SIZE) {
- lstrcat(szFileName, "xlisp.hlp");
- }
-
- else {
- lstrcat(szFileName, "?");
- }
-
- return;
- }
-
- /* osinit - initialize */
- VOID osinit()
- {
- HDC hdc;
- char c;
- DWORD fm;
-
- hdc = GetDC( MainWindow );
- SelectObject( hdc , GetStockObject( SYSTEM_FIXED_FONT ) );
- c = 'M';
- fm = GetTextExtent( hdc , (LPSTR)&c , 1 );
- FontWidth = LOWORD( fm );
- FontHeight = HIWORD( fm );
-
- CursorVisible = FALSE;
- kFifoHead = kFifoTail = 0;
-
- GotClientReq = FALSE;
- ServerReady = FALSE;
- ServerPacket = FALSE;
-
- sHeadIndex = sTailIndex = sTPosIndex = 0;
- ScreenXPos = ScreenYPos = 0;
- if( ( ScreenBuf = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT ,
- (DWORD)SCREENBUFSIZE ) ) == NULL )
- {
- MessageBox( MainWindow , "Cannot allocate screen buffer" , "XLISP" ,
- MB_OK | MB_ICONSTOP );
- exit( 1 );
- }
- ReleaseDC( MainWindow , hdc );
- DisableMenuCommands();
- MakeHelpPathName( helpfilename );
- }
-
- /* osfinish - clean up before returning to the operating system */
- VOID osfinish()
- {
- }
-
- /* xoserror - print an error message */
- VOID xoserror(char msg[])
- {
- char w[100];
-
- sprintf( w ,"error: %s\n" , msg);
- stdputstr( msg );
- }
-
- /* osrand - return next random number in sequence */
- long osrand(long rseed)
- {
- long k1;
-
- /* make sure we don't get stuck at zero */
- if (rseed == 0L) rseed = 1L;
-
- /* algorithm taken from Dr. Dobbs Journal, November 1985, page 91 */
- k1 = rseed / 127773L;
- if ((rseed = 16807L * (rseed - k1 * 127773L) - k1 * 2836L) < 0L)
- rseed += 2147483647L;
-
- /* return a random number between 0 and MAXFIX */
- return rseed;
- }
-
- #ifdef FILETABLE
-
- int truename(char *name, char *rname)
- {
- union REGS regs;
- #ifndef MEDMEM
- struct SREGS sregs;
- #endif
- int i;
- char *cp;
- int drive; /* drive letter */
- char pathbuf[FNAMEMAX+1]; /* copy of path part of name */
- char curdir[FNAMEMAX+1]; /* current directory of drive */
- char *fname; /* pointer to file name part of name */
-
- /* use backslashes consistantly */
-
- for (cp = name; (cp = strchr(cp, '/')) != NULL; *cp = '\\') ;
-
- /* parse any drive specifier */
-
- if ((cp = strrchr(name, ':')) != NULL) {
- if (cp != name+1 || !isalpha(*name)) return FALSE;
- drive = toupper(*name);
- name = cp+1; /* name now excludes drivespec */
- }
- else {
- regs.h.ah = 0x19; /* get current disk */
- intdos(®s, ®s);
- drive = regs.h.al + 'A';
- }
-
- /* check for absolute path (good news!) */
-
- if (*name == '\\') {
- sprintf(rname,"%c:%s",drive,name);
- }
- else {
- strcpy(pathbuf, name);
- if ((cp = strrchr(pathbuf, '\\')) != NULL) { /* path present */
- cp[1] = 0;
- fname = strrchr(name, '\\') + 1;
- }
- else {
- pathbuf[0] = 0;
- fname = name;
- }
-
- /* get the current directory of the selected drive */
-
- regs.h.ah = 0x47;
- regs.h.dl = drive + 1 - 'A';
- #ifdef MEDMEM
- regs.x.si = (unsigned) curdir;
- intdos(®s, ®s);
- #else
- regs.x.si = (unsigned) FP_OFF(curdir);
- sregs.ds = (unsigned) FP_SEG(curdir);
- intdosx(®s, ®s, &sregs);
- #endif
-
- if (regs.x.cflag != 0) return FALSE; /* invalid drive */
-
- /* peel off "..\"s */
- while (strncmp(pathbuf, "..\\", 3) == 0) {
- if (*curdir == 0) return FALSE; /* already at root */
- strcpy(pathbuf, pathbuf+3);
- if ((cp=strrchr(curdir, '\\')) != NULL)
- *cp = 0; /* peel one depth of directories */
- else
- *curdir = 0; /* peeled back to root */
- }
-
- /* allow for a ".\" */
- if (strncmp(pathbuf, ".\\", 2) == 0)
- strcpy(pathbuf, pathbuf+2);
-
- /* final name is drive:\curdir\pathbuf\fname */
-
- if (strlen(pathbuf)+strlen(curdir)+strlen(fname)+4 > FNAMEMAX)
- return FALSE;
-
- if (*curdir)
- sprintf(rname, "%c:\\%s\\%s%s", drive, curdir, pathbuf, fname);
- else
- sprintf(rname, "%c:\\%s%s", drive, pathbuf, fname);
- }
-
- /* lowercase the whole string */
-
- for (cp = rname; (i = *cp) != 0; cp++) {
- if (isupper(i)) *cp = tolower(i);
- }
-
- return TRUE;
- }
-
- extern void gc(void);
-
- LOCAL int XNEAR getslot(VOID)
- {
- int i=0;
-
- for (; i < FTABSIZE; i++) /* look for available slot */
- if (filetab[i].fp == NULL) return i;
-
- gc(); /* is this safe??????? */
-
- for (i=0; i < FTABSIZE; i++) /* try again -- maybe one has been freed */
- if (filetab[i].fp == NULL) return i;
-
- xlfail("too many open files");
-
- return 0; /* never returns */
- }
-
-
- FILEP osaopen(const char *name, const char *mode)
- {
- int i=getslot();
- char namebuf[FNAMEMAX+1];
- FILE *fp;
-
- if (!truename((char *)name, namebuf))
- strcpy(namebuf, name); /* should not happen */
-
- if ((filetab[i].tname = malloc(strlen(namebuf)+1)) == NULL) {
- free(filetab[i].tname);
- xlfail("insufficient memory");
- }
-
-
- if ((fp = fopen(name,mode)) == NULL) {
- free(filetab[i].tname);
- return CLOSED;
- }
-
- filetab[i].fp = fp;
-
- strcpy(filetab[i].tname, namebuf);
-
- return i;
- }
-
-
- FILEP osbopen(const char *name, const char *mode)
- {
- char bmode[10];
-
- strcpy(bmode,mode); strcat(bmode,"b");
-
- return osaopen(name, bmode);
- }
-
- VOID osclose(FILEP f)
- {
- fclose(filetab[f].fp);
- free(filetab[f].tname);
- filetab[f].tname = NULL;
- filetab[f].fp = NULL;
- }
-
- #else
- /* osbopen - open a binary file */
- FILE * CDECL osbopen(const char *name, const char *mode)
- {
- char bmode[10];
- strcpy(bmode,mode); strcat(bmode,"b");
- return (fopen(name,bmode));
- }
- #endif
-
- #ifdef PATHNAMES
- /* ospopen - open for reading using a search path */
- FILEP ospopen(char *name, int ascii)
- {
- FILEP fp;
- char *path = getenv(PATHNAMES);
- char *newnamep;
- char ch;
- char newname[256];
-
- /* don't do a thing if user specifies explicit path */
- if (strchr(name,'/') != NULL && strchr(name, '\\') != NULL)
- #ifdef FILETABLE
- return (ascii? osaopen: osbopen)(name,"r");
- #else
- return fopen(name,(ascii? "r": "rb"));
- #endif
-
- do {
- if (*path == '\0') /* no more paths to check */
- /* check current directory just in case */
- #ifdef FILETABLE
- return (ascii? osaopen: osbopen)(name,"r");
- #else
- return fopen(name,(ascii? "r": "rb"));
- #endif
-
- newnamep = newname;
- while ((ch=*path++) != '\0' && ch != ';' && ch != ' ')
- *newnamep++ = ch;
-
- if (ch == '\0') path--;
-
- if (newnamep != newname &&
- *(newnamep-1) != '/' && *(newnamep-1) != '\\')
- *newnamep++ = '/'; /* final path separator needed */
- *newnamep = '\0';
-
- strcat(newname, name);
- #ifdef FILETABLE
- fp = (ascii? osaopen: osbopen)(newname,"r");
- #else
- fp = fopen(newname, ascii? "r": "rb");
- #endif
- } while (fp == CLOSED); /* not yet found */
-
- return fp;
- }
- #endif
-
- /* rename argument file as backup, return success name */
- /* For new systems -- if cannot do it, just return TRUE! */
-
- int renamebackup(char *filename) {
- char *bufp, ch=0;
-
- strcpy(buf, filename); /* make copy with .bak extension */
-
- bufp = &buf[strlen(buf)]; /* point to terminator */
- while (bufp > buf && (ch = *--bufp) != '.' && ch != '/' && ch != '\\') ;
-
-
- if (ch == '.') strcpy(bufp, ".bak");
- else strcat(buf, ".bak");
-
- remove(buf);
-
- return !rename(filename, buf);
- }
-
-
- /* ostgetc - get a character from the terminal */
- int ostgetc()
- {
- int ch;
-
- /* check for a buffered character */
- if (lcount-- > 0)
- return (lbuf[lindex++]);
-
- /* get an input line */
-
- for (lcount = 0; ; )
- switch (ch = xgetc()) {
- case '\r':
- case '\n':
- lbuf[lcount++] = '\n';
- xputc('\r'); xputc('\n'); lposition = 0;
- if (tfp!=CLOSED) OSWRITE(lbuf,1,lcount,tfp);
- lindex = 0; lcount--;
- return (lbuf[lindex++]);
- case '\010':
- case '\177':
- if (lcount) {
- lcount--;
- while (lposition > lpos[lcount]) {
- xputc('\b');
- lposition--;
- }
- }
- break;
- case '\032':
- xflush();
- return (EOF);
- default:
- if (ch == '\t' || (ch >= 0x20 && ch < 0x7F)) {
- lbuf[lcount] = ch;
- lpos[lcount] = lposition;
- if (ch == '\t')
- do {
- xputc(' ');
- } while (++lposition & 7);
- else {
- xputc(ch); lposition++;
- }
- lcount++;
- }
- else {
- xflush();
- switch (ch) {
- case '\003': xltoplevel(); /* control-c */
- case '\007': xlcleanup(); /* control-g */
- case '\020': xlcontinue(); /* control-p */
- case '\032': return (EOF); /* control-z */
- default: return (ch);
- } /* switch */
- } /* else */
- } /* switch */
- }
-
- /* ostputc - put a character to the terminal */
- VOID ostputc(ch)
- int ch;
- {
- /* check for control characters */
-
- oscheck();
-
- /* output the character */
- if (ch == '\n') {
- xputc('\r'); xputc('\n');
- lposition = 0;
- }
- else if (ch == '\t')
- do { xputc(' '); } while (++lposition & 7);
- else {
- xputc(ch);
- lposition++;
- }
-
- /* output the character to the transcript file */
- if (tfp!=CLOSED)
- OSPUTC(ch,tfp);
- }
-
- /* osflush - flush the terminal input buffer */
- VOID osflush()
- {
- kFifoTail = kFifoHead;
- }
-
- /* oscheck - check for control characters during execution */
- VOID oscheck()
- {
- MSG msg;
- int ch;
-
- if( PeekMessage( &msg , MainWindow , 0 , 0xFFFF ,
- PM_REMOVE ) )
- {
- if( !TranslateAccelerator( MainWindow , hAccel , &msg ) )
- {
- TranslateMessage( &msg );
-
- if( msg.message == WM_CHAR )
- {
- ch = msg.wParam;
- switch (ch)
- {
- case '\002': /* control-b */
- xflush();
- xlbreak("BREAK",s_unbound);
- break;
-
- case '\003': /* control-c */
- xflush();
- xltoplevel();
- break;
-
- case '\023': /* control-s */
- xgetc(); /* paused -- get character and toss */
- break;
- }
- }
- else
- DispatchMessage( &msg );
- }
- }
- }
-
- /* xinfo - show information on control-t */
- static VOID XNEAR xinfo()
- {
- extern long nfree;
- extern int gccalls;
- extern long total;
-
- sprintf(buf,"Free: %ld, GC calls: %d, Total: %ld",
- nfree,gccalls,total);
- MessageBox( MainWindow , buf , "XLisp - Memory info",
- MB_OK | MB_ICONINFORMATION );
-
- }
-
- /* xflush - flush the input line buffer and start a new line */
- static VOID XNEAR xflush()
- {
- osflush();
- ostputc('\n');
- }
-
- /* xgetc - get a character from the terminal without echo */
- static int XNEAR xgetc()
- {
- int ch;
- LPSTR p;
- char c;
-
- CursorVisible = TRUE;
- XShowCursor();
- while( 1 )
- {
- /* check for a buffered character */
- if( kFifoHead != kFifoTail )
- {
- ch = kFifo[ kFifoTail ];
- kFifoTail = ++kFifoTail % KB_FIFOSIZE;
- CursorVisible = FALSE;
- XHideCursor();
- return ch;
- }
- if( !MessageLoop() )
- if( GotClientReq ) /* If the message loop was broken
- by a client request */
- {
- p = XDGetRequest();
- while( c = *( p++ ) )
- PutFifo( c );
- GotClientReq = FALSE;
- ServerReady = TRUE;
- }
- else
- {
- CursorVisible = FALSE;
- XHideCursor();
- MenuCommand = FUNC_EOF;
- return EOF;
- }
- }
- }
-
- /* Moves sHeadIndex backward */
- static void XNEAR BackScreenHead()
- {
- --sHeadIndex;
- if( sHeadIndex < 0 )
- sHeadIndex = SCREENBUFSIZE - 1;
- }
-
- /* Moves sHeadIndex forward */
- static void XNEAR ForwardScreenHead()
- {
- sHeadIndex = ++sHeadIndex % SCREENBUFSIZE;
- if( sHeadIndex == sTPosIndex )
- sTPosIndex = ++sTPosIndex % SCREENBUFSIZE;
- }
-
- /* Pushes forward the screen tail pointer by one line. Used when scrolling
- the screen up */
- static void XNEAR ForwardScreenTail( char far *Buf , int xsize )
- {
- int xpos = 0;
-
- while( xpos < xsize )
- {
- if( Buf[ sTailIndex ] == '\n' )
- {
- sTailIndex = ++sTailIndex % SCREENBUFSIZE;
- break;
- }
- xpos += FontWidth;
- sTailIndex = ++sTailIndex % SCREENBUFSIZE;
- }
- }
-
-
- /* Scrolls the screen by one line */
- void ScrollScreen()
- {
- HDC hdc;
- RECT rect,DelRect;
- HBRUSH DelBrush;
-
- ScrollWindow( MainWindow , 0 , -FontHeight , NULL , NULL );
- ValidateRect( MainWindow , NULL );
- hdc = GetDC( MainWindow );
- GetClientRect( MainWindow , &rect );
- SetRect( &DelRect , 0 , ScreenYPos , rect.right ,
- ScreenYPos + FontHeight + 1 );
- DelBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
- FillRect( hdc , &DelRect , DelBrush );
- DeleteObject( DelBrush );
- ReleaseDC( MainWindow , hdc );
- }
-
- /* xputc - put a character to the terminal */
- static void XNEAR xputc( int ch )
- {
- HDC hdc;
- char string[2];
- char far *DispBuf,far *ReplyBuf;
- int i,chwidth;
- HBRUSH DelBrush;
- RECT rect,DelRect;
-
- /* if the reply is passed to the XServer DLL */
- if( ServerPacket )
- {
- ReplyBuf = GlobalLock( ReplyBlock );
- ReplyBuf[ ReplyIndex ] = ch;
- ReplyIndex = ++ReplyIndex % RBLOCK_SIZE;
- GlobalUnlock( ReplyBlock );
- }
-
- string[1] = 0;
- DispBuf = GlobalLock( ScreenBuf );
-
- hdc = GetDC( MainWindow ); /* Get display context for the
- main window */
- SelectObject( hdc , GetStockObject( SYSTEM_FIXED_FONT ) );
- GetClientRect( MainWindow , &rect );
- SetBkColor( hdc , GetSysColor( COLOR_WINDOW ) );
- SetTextColor( hdc , GetSysColor( COLOR_WINDOWTEXT ) );
-
- switch( ch )
- {
- case '\b': /* Backspace */
- if( !ScreenXPos ) /* if the first char */
- {
- if( !ScreenYPos ) /* if at the top of the
- screen */
- break;
- ScreenYPos -= FontHeight;
- i = rect.right / FontWidth;
- ScreenXPos = ( rect.right / FontWidth )*FontWidth;
- }
- BackScreenHead();
- if( DispBuf[ sHeadIndex ] == '\n' )
- BackScreenHead();
- string[0] = DispBuf[ sHeadIndex ];
- chwidth = GetTextExtent( hdc , string , 1 );
- SetRect( &DelRect , ScreenXPos-FontWidth , ScreenYPos ,
- ScreenXPos , ScreenYPos + FontHeight );
- DelBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
- FillRect( hdc , &DelRect , DelBrush );
- DeleteObject( DelBrush );
- ScreenXPos -= FontWidth;
- break;
-
- case '\r': /* CR */
- ScreenXPos = 0;
- break;
-
- case '\n': /* LF */
- DispBuf[ sHeadIndex ] = ch; /* Store LF */
- ForwardScreenHead();
- if( ( ScreenYPos + 2*FontHeight ) > rect.bottom )
- {
- ForwardScreenTail( DispBuf , rect.right );
- ScrollScreen();
- }
- else
- ScreenYPos += FontHeight;
- break;
-
- default:
- string[0] = ch; /* Makes string of the character */
- chwidth = GetTextExtent( hdc , string , 1 );
- if( ( ScreenXPos + FontWidth) >= rect.right )
- {
- if( ( ScreenYPos + 2*FontHeight ) > rect.bottom )
- {
- ForwardScreenTail( DispBuf , rect.right );
- ScrollScreen();
- }
- else
- ScreenYPos += FontHeight;
- ScreenXPos = 0;
- }
- i = ( FontWidth - chwidth )/2;
- TextOut( hdc,ScreenXPos+i,ScreenYPos,string,1 );
- DispBuf[ sHeadIndex ] = ch;
- ForwardScreenHead();
- ScreenXPos += FontWidth;
- break;
-
- }
- ReleaseDC( MainWindow , hdc );
- GlobalUnlock( ScreenBuf );
- }
-
- /* xsystem - execute a system command */
- LVAL xsystem()
- {
- char cmd[STRMAX];
- WORD ok;
-
- MEMCPY( cmd , getstring(xlgastring()) , STRMAX );
- xllastarg();
- ok = WinExec( cmd , SW_SHOW );
- return (ok > 32 ? true : cvfixnum((FIXTYPE)ok));
- }
-
- /* xgetkey - get a key from the keyboard */
- LVAL xgetkey()
- {
- xllastarg();
- return (cvfixnum((FIXTYPE)xgetc()));
- }
-
- /* ossymbols - enter os specific symbols */
- VOID ossymbols()
- {
- }
-
- #ifdef GRAPHICS
-
- static int GrXPos = 0,GrYPos = 0;
- static DWORD DrawColor = 0;
-
- /* function goto-xy which set/obtains cursor position */
- LVAL xgotoxy()
- {
- FIXTYPE x, y;
- LVAL oldpos;
-
- oldpos = cons(cvfixnum((FIXTYPE)GrXPos ),
- cons(cvfixnum((FIXTYPE)GrYPos ),NIL));
-
- if (moreargs()) {
- x = getfixnum(xlgafixnum());
- y = getfixnum(xlgafixnum());
- xllastarg();
- if (x < 0) x = 0; /* check for in bounds */
- if (y < 0) y = 0;
-
- GrXPos = x;
- GrYPos = y;
- lposition = (int)x;
- }
-
- return oldpos;
- }
-
- LVAL xcls() /* clear the screen */
- {
- lposition = 0;
- sHeadIndex = sTailIndex;
- InvalidateRect( MainWindow , NULL , TRUE );
- return NIL;
- }
-
- LVAL xcleol() /* clear to end of line */
- {
- HDC hdc;
- RECT rect,DelRect;
- HBRUSH DelBrush;
-
- hdc = GetDC( MainWindow );
- GetClientRect( MainWindow , &rect );
- SetRect( &DelRect , ScreenXPos , ScreenYPos , rect.right ,
- ScreenYPos + FontHeight + 1 );
- DelBrush = CreateSolidBrush( GetSysColor( COLOR_WINDOW ) );
- FillRect( hdc , &DelRect , DelBrush );
- DeleteObject( DelBrush );
- ReleaseDC( MainWindow , hdc );
- return NIL;
- }
-
- static LVAL XNEAR draw(int x, int y, int x2, int y2)
- {
- HDC hdc;
- HPEN pen;
-
- hdc = GetDC( MainWindow );
- pen = CreatePen( PS_SOLID , 1 , DrawColor );
- SelectObject( hdc , pen );
- MoveTo( hdc , x , y );
- LineTo( hdc , x2 , y2 );
- GrXPos = x2;
- GrYPos = y2;
- ReleaseDC( MainWindow , hdc );
- DeleteObject( pen );
-
- return( true );
- }
-
-
- /* xmode -- set display mode */
- LVAL xmode()
- {
- xoserror( "xmode : not implemented under Windows" );
- return NIL;
- }
-
- /* xcolor -- set color */
-
- LVAL xcolor()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- xllastarg();
-
- DrawColor = getfixnum(arg);
-
- return (arg);
- }
-
- /* xdraw -- absolute draw */
-
- LVAL xdraw()
- {
- LVAL arg = true;
- int newx, newy;
-
- while (moreargs()) {
- arg = xlgafixnum();
- newx = (int) getfixnum(arg);
-
- arg = xlgafixnum();
- newy = (int) getfixnum(arg);
-
- arg = draw(GrXPos,GrYPos,newx,newy);
-
- }
- return (arg);
- }
-
- /* xdrawrel -- absolute draw */
-
- LVAL xdrawrel()
- {
- LVAL arg = true;
- int newx, newy;
-
- while (moreargs()) {
- arg = xlgafixnum();
- newx = GrXPos + (int) getfixnum(arg);
-
- arg = xlgafixnum();
- newy = GrYPos + (int) getfixnum(arg);
-
- arg = draw(GrXPos,GrYPos,newx,newy);
-
- }
- return (arg);
- }
-
- /* xmove -- absolute move, then draw */
-
- LVAL xmove()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- GrXPos = (int) getfixnum(arg);
-
- arg = xlgafixnum();
- GrYPos = (int) getfixnum(arg);
-
- return (xdraw());
- }
-
- /* xmoverel -- relative move */
-
- LVAL xmoverel()
- {
- LVAL arg;
-
- arg = xlgafixnum();
- GrXPos += (int) getfixnum(arg);
-
- arg = xlgafixnum();
- GrYPos += (int) getfixnum(arg);
-
- return (xdrawrel());
- }
-
- #endif /* Graphics */
-
- #ifdef TIMES
- unsigned long ticks_per_second() { return((unsigned long) CLK_TCK); }
-
- unsigned long run_tick_count()
- {
- return((unsigned long) clock()); /* Real time in MSDOS */
- }
-
- unsigned long real_tick_count()
- { /* Real time */
- return((unsigned long) clock());
- }
-
-
- LVAL xtime()
- {
- LVAL expr,result;
- unsigned long tm;
-
- /* get the expression to evaluate */
- expr = xlgetarg();
- xllastarg();
-
- tm = run_tick_count();
- result = xleval(expr);
- tm = run_tick_count() - tm;
- sprintf(buf, "The evaluation took %.2f seconds.\n",
- ((double)tm) / ticks_per_second());
- trcputstr(buf);
-
-
- return(result);
- }
-
- LVAL xruntime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) run_tick_count()));
- }
-
- LVAL xrealtime() {
- xllastarg();
- return(cvfixnum((FIXTYPE) real_tick_count()));
- }
-
-
- #endif
-