home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / tos.c < prev    next >
Text File  |  1996-04-25  |  11KB  |  486 lines

  1. /*    TOS.C:        Operating specific I/O and Spawning functions
  2.             for the ATARI ST operating system (GEMDOS)
  3.             for MicroEMACS 4.00
  4.             (C)Copyright 1995 by Daniel M. Lawrence
  5. */
  6.  
  7. #include        <stdio.h>
  8. #include    "estruct.h"
  9. #include    "eproto.h"
  10. #if    TOS
  11. #include        "edef.h"
  12. #include    "elang.h"
  13. #include    "osbind.h"
  14. #include    "stat.h"    /* DMABUFFER is here */
  15. #include    "errno.h"
  16.  
  17. /****    ST Internals definitions        *****/
  18.  
  19. /*    BIOS calls */
  20.  
  21. #define    BCONSTAT    1    /* return input device status */
  22. #define    CONIN        2    /* read character from device */
  23. #define    BCONOUT        3    /* write character to device */
  24.  
  25. /*    XBIOS calls */
  26.  
  27. #define    INITMOUS    0    /* initialize the mouse */
  28. #define    GETREZ        4    /* get current resolution */
  29. #define    SETSCREEN    5    /* set screen resolution */
  30. #define    SETPALETTE    6    /* set the color pallette */
  31. #define    SETCOLOR    7    /* set or read a color */
  32. #define    CURSCONF    21    /* set cursor configuration */
  33. #define    IKBDWS        25    /* intelligent keyboard send command */
  34. #define    KBDVBASE    34    /* get keyboard table base */
  35.  
  36. /*    GEMDOS calls */
  37.  
  38. #define    EXEC        0x4b    /* Exec off a process */
  39.  
  40. #define    CON        2    /* CON: Keyboard and screen device */
  41.  
  42. /*
  43.  * This function is called once to set up the terminal device streams.
  44.  * On VMS, it translates TT until it finds the terminal, then assigns
  45.  * a channel to it and sets it raw. On CPM it is a no-op.
  46.  */
  47. ttopen()
  48. {
  49.     /* on all screens we are not sure of the initial position
  50.        of the cursor                    */
  51.     ttrow = 999;
  52.     ttcol = 999;
  53. }
  54.  
  55. /*
  56.  * This function gets called just before we go back home to the command
  57.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  58.  * Another no-operation on CPM.
  59.  */
  60. ttclose()
  61. {
  62. }
  63.  
  64. /*
  65.  * Write a character to the display. On VMS, terminal output is buffered, and
  66.  * we just put the characters in the big array, after checking for overflow.
  67.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  68.  * MS-DOS (use the very very raw console output routine).
  69.  */
  70. ttputc(c)
  71.  
  72. char c;
  73.  
  74. {
  75. }
  76.  
  77. /*
  78.  * Flush terminal buffer. Does real work where the terminal output is buffered
  79.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  80.  */
  81. ttflush()
  82. {
  83. }
  84.  
  85. /*
  86.  * Read a character from the terminal, performing no editing and doing no echo
  87.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  88.  * simple on CPM, because the system can do exactly what you want.
  89.  */
  90. ttgetc()
  91. {
  92. }
  93.  
  94. #if    TYPEAH
  95. typahead()
  96.  
  97. {
  98.     int rv;    /* return value from BIOS call */
  99.  
  100.     /* get the status of the console */
  101.     rv = bios(BCONSTAT, CON);
  102.  
  103.     /* end return the results */
  104.     if (rv == 0)
  105.         return(FALSE);
  106.     else
  107.         return(TRUE);
  108. }
  109. #endif
  110.  
  111. /*
  112.  * Create a subjob with a copy of the command intrepreter in it. When the
  113.  * command interpreter exits, mark the screen as garbage so that you do a full
  114.  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  115.  * Under some (unknown) condition, you don't get one free when DCL starts up.
  116.  */
  117. spawncli(f, n)
  118.  
  119. {
  120. #if    ENVFUNC
  121.     char *shell;    /* ptr to the name of the shell to execute */
  122. #endif
  123.  
  124.     /* don't allow this command if restricted */
  125.     if (restflag)
  126.         return(resterr());
  127.  
  128. #if    ENVFUNC
  129.     shell = getenv("SHELL");
  130.     if (shell == (char *)NULL)
  131.         return(FALSE);
  132.  
  133.     /* Prepare to Jump.... */
  134.     mlerase();
  135.         TTflush();
  136.     TTkclose();
  137.  
  138.     /* Execute the shell */
  139.     system(shell);
  140.  
  141.     /* Re-enable EMACS's environment, flag junked screen */
  142.     TTkopen();
  143.         sgarbf = TRUE;
  144.         return(TRUE);
  145. #else
  146.     return(FALSE);
  147. #endif
  148. }
  149.  
  150. /*
  151.  * Run a one-liner in a subjob. When the command returns, wait for a single
  152.  * character to be typed, then mark the screen as garbage so a full repaint is
  153.  * done. Bound to "C-X !".
  154.  */
  155. spawn(f, n)
  156. {
  157.         register int    s;
  158.         char            line[NLINE];
  159.  
  160.     /* don't allow this command if restricted */
  161.     if (restflag)
  162.         return(resterr());
  163.  
  164.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  165.                 return(s);
  166.     mlerase();
  167.     TTkclose();
  168.         system(line);
  169.     TTkopen();
  170.     /* if we are interactive, pause here */
  171.     if (clexec == FALSE) {
  172.             mlputs(TEXT6);
  173. /*                     "\r\n\n[End]" */
  174.             tgetc();
  175.         }
  176.         sgarbf = TRUE;
  177.         return (TRUE);
  178. }
  179.  
  180. /*
  181.  * Run an external program with arguments. When it returns, wait for a single
  182.  * character to be typed, then mark the screen as garbage so a full repaint is
  183.  * done. Bound to "C-X $".
  184.  */
  185.  
  186. execprg(f, n)
  187.  
  188. {
  189.         register int    s;
  190.         char            line[NLINE];
  191.  
  192.     /* don't allow this command if restricted */
  193.     if (restflag)
  194.         return(resterr());
  195.  
  196.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  197.                 return(s);
  198.     mlerase();
  199.     TTkclose();
  200.         system(line);
  201.     TTkopen();
  202.     /* if we are interactive, pause here */
  203.     if (clexec == FALSE) {
  204.             mlputs(TEXT6);
  205. /*                     "\r\n\n[End]" */
  206.             tgetc();
  207.         }
  208.         sgarbf = TRUE;
  209.         return (TRUE);
  210. }
  211.  
  212. /*
  213.  * Pipe a one line command into a window
  214.  * Bound to ^X @
  215.  */
  216. pipecmd(f, n)
  217. {
  218.         register int    s;    /* return status from CLI */
  219.     register EWINDOW *wp;    /* pointer to new window */
  220.     register BUFFER *bp;    /* pointer to buffer to zot */
  221.         char    line[NLINE];    /* command line send to shell */
  222.     static char bname[] = "command";
  223.     FILE *fp;
  224.  
  225.     static char filnam[NSTRING] = "command";
  226.  
  227.     /* don't allow this command if restricted */
  228.     if (restflag)
  229.         return(resterr());
  230.  
  231.     /* get the command to pipe in */
  232.         if ((s=mlreply("@", line, NLINE)) != TRUE)
  233.                 return(s);
  234.  
  235.     /* get rid of the command output buffer if it exists */
  236.         if ((bp=bfind(bname, FALSE, 0)) != (BUFFER *)NULL) {
  237.         /* try to make sure we are off screen */
  238.         wp = wheadp;
  239.         while (wp != NULL) {
  240.             if (wp->w_bufp == bp) {
  241.                 onlywind(FALSE, 1);
  242.                 break;
  243.             }
  244.             wp = wp->w_wndp;
  245.         }
  246.         if (zotbuf(bp) != TRUE)
  247.  
  248.             return(FALSE);
  249.     }
  250.  
  251.     strcat(line," >>");
  252.     strcat(line,filnam);
  253.     movecursor(term.t_nrow - 1, 0);
  254.     TTkclose();
  255.     system(line);
  256.     TTkopen();
  257.         sgarbf = TRUE;
  258.     if ((fp = fopen(filnam, "r")) == NULL) {
  259.         s = FALSE;
  260.     } else {
  261.         fclose(fp);
  262.         s = TRUE;
  263.     }
  264.  
  265.     if (s != TRUE)
  266.         return(s);
  267.  
  268.     /* split the current window to make room for the command output */
  269.     if (splitwind(FALSE, 1) == FALSE)
  270.             return(FALSE);
  271.  
  272.     /* and read the stuff in */
  273.     if (getfile(filnam, FALSE) == FALSE)
  274.         return(FALSE);
  275.  
  276.     /* make this window in VIEW mode, update all mode lines */
  277.     curwp->w_bufp->b_mode |= MDVIEW;
  278.     upmode();
  279.  
  280.     /* and get rid of the temporary file */
  281.     unlink(filnam);
  282.     return(TRUE);
  283. }
  284.  
  285. /*
  286.  * filter a buffer through an external DOS program
  287.  * Bound to ^X #
  288.  */
  289. filter(f, n)
  290.  
  291. {
  292.         register int    s;    /* return status from CLI */
  293.     register BUFFER *bp;    /* pointer to buffer to zot */
  294.         char line[NLINE];    /* command line send to shell */
  295.     char tmpnam[NFILEN];    /* place to store real file name */
  296.     static char bname1[] = "fltinp";
  297.  
  298.     static char filnam1[] = "fltinp";
  299.     static char filnam2[] = "fltout";
  300.  
  301.     /* don't allow this command if restricted */
  302.     if (restflag)
  303.         return(resterr());
  304.  
  305.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  306.         return(rdonly());    /* we are in read only mode    */
  307.  
  308.     /* get the filter name and its args */
  309.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  310.                 return(s);
  311.  
  312.     /* setup the proper file names */
  313.     bp = curbp;
  314.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  315.     strcpy(bp->b_fname, bname1);    /* set it to our new one */
  316.  
  317.     /* write it out, checking for errors */
  318.     if (writeout(filnam1, "w") != TRUE) {
  319.         mlwrite(TEXT2);
  320. /*                      "[Cannot write filter file]" */
  321.         strcpy(bp->b_fname, tmpnam);
  322.         return(FALSE);
  323.     }
  324.  
  325.     strcat(line," <fltinp >fltout");
  326.     movecursor(term.t_nrow, 0);
  327.     TTkclose();
  328.     system(line);
  329.     TTkopen();
  330.         sgarbf = TRUE;
  331.     s = TRUE;
  332.  
  333.     /* on failure, escape gracefully */
  334.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  335.         mlwrite(TEXT3);
  336. /*                      "[Execution failed]" */
  337.         strcpy(bp->b_fname, tmpnam);
  338.         unlink(filnam1);
  339.         unlink(filnam2);
  340.         return(s);
  341.     }
  342.  
  343.     /* reset file name */
  344.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  345.     bp->b_flag |= BFCHG;        /* flag it as changed */
  346.     upmode();
  347.  
  348.     /* and get rid of the temporary file */
  349.     unlink(filnam1);
  350.     unlink(filnam2);
  351.     return(TRUE);
  352. }
  353.  
  354. rename(oldname, newname)    /* rename a file */
  355.  
  356. char *oldname;        /* original file name */
  357. char *newname;        /* new file name */
  358.  
  359. {
  360.     Frename(0, oldname, newname);
  361. }
  362.  
  363. /* return a system dependant string with the current time */
  364.  
  365. char *PASCAL NEAR timeset()
  366.  
  367. {
  368.     register char *sp;    /* temp string pointer */
  369.     char buf[16];        /* time data buffer */
  370.  
  371.     time(buf);
  372.     sp = ctime(buf);
  373.     sp[strlen(sp)-1] = 0;
  374.     return(sp);
  375. }
  376.  
  377. /*    FILE Directory routines        */
  378.  
  379. static DMABUFFER info;        /* Info about the file */
  380. char xpath[NFILEN];        /* path of file to find */
  381. char rbuf[NFILEN];        /* return file buffer */
  382.  
  383. /*    do a wild card directory search (for file name completion) */
  384.  
  385. char *PASCAL NEAR getffile(fspec)
  386.  
  387. char *fspec;    /* file to match */
  388.  
  389. {
  390.     register int index;        /* index into various strings */
  391.     register int point;        /* index into other strings */
  392.     register int extflag;        /* does the file have an extention? */
  393.     char fname[NFILEN];        /* file/path for DOS call */
  394.  
  395.     /* first parse the file path off the file spec */
  396.     strcpy(xpath, fspec);
  397.     index = strlen(xpath) - 1;
  398.     while (index >= 0 && (xpath[index] != '/' &&
  399.                 xpath[index] != '\\' && xpath[index] != ':'))
  400.         --index;
  401.     xpath[index+1] = 0;
  402.  
  403.     /* check for an extension */
  404.     point = strlen(fspec) - 1;
  405.     extflag = FALSE;
  406.     while (point >= index) {
  407.         if (fspec[point] == '.') {
  408.             extflag = TRUE;
  409.             break;
  410.         }
  411.         point--;
  412.     }
  413.  
  414.     /* construct the composite wild card spec */
  415.     strcpy(fname, xpath);
  416.     strcat(fname, &fspec[index+1]);
  417.     strcat(fname, "*");
  418.     if (extflag == FALSE)
  419.         strcat(fname, ".*");
  420.  
  421.     /* and call for the first file */
  422.     Fsetdta(&info);        /* Initialize buffer for our search */
  423.     if (Fsfirst(fname, 0xF7) != AE_OK)
  424.         return(NULL);
  425.  
  426.     /* return the first file name! */
  427.     strcpy(rbuf, xpath);
  428.     strcat(rbuf, info.d_fname);
  429.     mklower(rbuf);
  430.     if (info.d_fattr & 0x10)
  431.         strcat(rbuf, DIRSEPSTR);
  432.     return(rbuf);
  433. }
  434.  
  435. char *PASCAL NEAR getnfile()
  436.  
  437. {
  438.  
  439.     /* and call for the first file */
  440.     if (Fsnext() != AE_OK)
  441.         return(NULL);
  442.  
  443.     /* return the first file name! */
  444.     strcpy(rbuf, xpath);
  445.     strcat(rbuf, info.d_fname);
  446.     mklower(rbuf);
  447.     if (info.d_fattr & 0x10)
  448.         strcat(rbuf, DIRSEPSTR);
  449.     return(rbuf);
  450. }
  451.  
  452. #if    LATTICE
  453. system(cmd)    /* call the system to execute a new program */
  454.  
  455. char *cmd;    /* command to execute */
  456.  
  457. {
  458.     char *pptr;            /* pointer into program name */
  459.     char pname[NSTRING];        /* name of program to execute */
  460.     char tail[NSTRING];        /* command tail */
  461.  
  462.     /* scan off program name.... */
  463.     pptr = pname;
  464.     while (*cmd && (*cmd != ' ' && *cmd != '\t'))
  465.         *pptr++ = *cmd++;
  466.     *pptr = 0;
  467.  
  468.     /* create program name length/string */
  469.     tail[0] = strlen(cmd);
  470.     strcpy(&tail[1], cmd);
  471.  
  472.     /* go do it! */
  473.     return(gemdos(        (int)EXEC,
  474.                 (int)0,
  475.                 (char *)pname,
  476.                 (char *)tail,
  477.                 (char *)NULL));
  478. }
  479. #endif
  480.  
  481. #else
  482. TOShello()
  483. {
  484. }
  485. #endif
  486.