home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume1 / 8711 / microemacs-3.9 / 11 < prev    next >
Text File  |  1987-11-20  |  37KB  |  1,500 lines

  1. Article 88 of comp.sources.misc:
  2. Path: tut!osu-cis!cbosgd!mandrill!hal!ncoast!allbery
  3. From: nwd@j.cc.purdue.edu (Daniel Lawrence)
  4. Newsgroups: comp.sources.misc
  5. Subject: MicroEmacs 3.9 (Part 11 of 16)
  6. Message-ID: <5687@ncoast.UUCP>
  7. Date: 17 Nov 87 02:34:04 GMT
  8. Sender: allbery@ncoast.UUCP
  9. Lines: 1485
  10. Approved: allbery@ncoast.UUCP
  11. X-Archive: comp.sources.misc/microemacs-3.9/10
  12.  
  13. # This is a shar archive.
  14. # Remove everything above this line.
  15. # Run the file through sh, not csh.
  16. # (type `sh mes.11')
  17. # If you do not see the message
  18. #    `mes.11 completed!'
  19. # then the file was incomplete.
  20. echo extracting - spawn.c
  21. sed 's/^X//' > spawn.c << 'FRIDAY_NIGHT'
  22. X/*    Spawn:    various DOS access commands
  23. X        for MicroEMACS
  24. X*/
  25. X
  26. X#include        <stdio.h>
  27. X#include    "estruct.h"
  28. X#include        "edef.h"
  29. X
  30. X#if     AMIGA
  31. X#define  NEW   1006L
  32. X#endif
  33. X
  34. X#if     VMS
  35. X#define EFN     0                               /* Event flag.          */
  36. X
  37. X#include        <ssdef.h>                       /* Random headers.      */
  38. X#include        <stsdef.h>
  39. X#include        <descrip.h>
  40. X#include        <iodef.h>
  41. X
  42. Xextern  int     oldmode[3];                     /* In "termio.c"        */
  43. Xextern  int     newmode[3];                     /* In "termio.c"        */
  44. Xextern  short   iochan;                         /* In "termio.c"        */
  45. X#endif
  46. X
  47. X#if     V7 | USG | BSD
  48. X#include        <signal.h>
  49. Xextern int vttidy();
  50. X#endif
  51. X
  52. X#if    MSDOS & (MSC | TURBO)
  53. X#include    <process.h>
  54. X#endif
  55. X
  56. X/*
  57. X * Create a subjob with a copy of the command intrepreter in it. When the
  58. X * command interpreter exits, mark the screen as garbage so that you do a full
  59. X * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  60. X * Under some (unknown) condition, you don't get one free when DCL starts up.
  61. X */
  62. Xspawncli(f, n)
  63. X{
  64. X#if     AMIGA
  65. X        long newcli;
  66. X
  67. X#endif
  68. X
  69. X#if     V7 | USG | BSD
  70. X        register char *cp;
  71. X        char    *getenv();
  72. X#endif
  73. X
  74. X    /* don't allow this command if restricted */
  75. X    if (restflag)
  76. X        return(resterr());
  77. X
  78. X#if    AMIGA
  79. X        mlwrite("[Starting new CLI]");
  80. X        sgarbf = TRUE;
  81. X        Execute("NEWCLI \"CON:0/0/640/200/MicroEMACS Subprocess\"", 0L, 0L);
  82. X        return(TRUE);
  83. X#endif
  84. X
  85. X#if     VMS
  86. X        movecursor(term.t_nrow, 0);             /* In last line.        */
  87. X        mlputs("[Starting DCL]\r\n");
  88. X        TTflush();                          /* Ignore "ttcol".      */
  89. X        sgarbf = TRUE;
  90. X        return (sys(NULL));                     /* NULL => DCL.         */
  91. X#endif
  92. X#if     CPM
  93. X        mlwrite("Not in CP/M-86");
  94. X#endif
  95. X#if     MSDOS & (AZTEC | MSC | TURBO)
  96. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  97. X        TTflush();
  98. X    TTkclose();
  99. X    shellprog("");
  100. X    TTkopen();
  101. X        sgarbf = TRUE;
  102. X        return(TRUE);
  103. X#endif
  104. X#if     ST520 & MWC
  105. X    mlerase();    /* clear the message line */
  106. X        TTflush();
  107. X    TTkclose();
  108. X    system("msh.prg");
  109. X    TTkopen();
  110. X        sgarbf = TRUE;
  111. X        return(TRUE);
  112. X#endif
  113. X#if     MSDOS & LATTICE
  114. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  115. X        TTflush();
  116. X    TTkclose();
  117. X        sys("\\command.com", "");               /* Run CLI.             */
  118. X    TTkopen();
  119. X        sgarbf = TRUE;
  120. X        return(TRUE);
  121. X#endif
  122. X#if     V7 | USG | BSD
  123. X        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  124. X        TTflush();
  125. X        TTclose();                              /* stty to old settings */
  126. X        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
  127. X                system(cp);
  128. X        else
  129. X#if    BSD
  130. X                system("exec /bin/csh");
  131. X#else
  132. X                system("exec /bin/sh");
  133. X#endif
  134. X        sgarbf = TRUE;
  135. X    sleep(2);
  136. X        TTopen();
  137. X        return(TRUE);
  138. X#endif
  139. X}
  140. X
  141. X#if    BSD
  142. X
  143. Xbktoshell()        /* suspend MicroEMACS and wait to wake up */
  144. X{
  145. X    int pid;
  146. X
  147. X    vttidy();
  148. X    pid = getpid();
  149. X    kill(pid,SIGTSTP);
  150. X}
  151. X
  152. Xrtfrmshell()
  153. X{
  154. X    TTopen();
  155. X    curwp->w_flag = WFHARD;
  156. X    sgarbf = TRUE;
  157. X}
  158. X#endif
  159. X
  160. X/*
  161. X * Run a one-liner in a subjob. When the command returns, wait for a single
  162. X * character to be typed, then mark the screen as garbage so a full repaint is
  163. X * done. Bound to "C-X !".
  164. X */
  165. Xspawn(f, n)
  166. X{
  167. X        register int    s;
  168. X        char            line[NLINE];
  169. X
  170. X#if     AMIGA
  171. X        long newcli;
  172. X#endif
  173. X
  174. X    /* don't allow this command if restricted */
  175. X    if (restflag)
  176. X        return(resterr());
  177. X
  178. X#if    AMIGA
  179. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  180. X                return (s);
  181. X        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  182. X        Execute(line, 0L, newcli);
  183. X        Close(newcli);
  184. X        tgetc();     /* Pause.               */
  185. X        sgarbf = TRUE;
  186. X        return(TRUE);
  187. X#endif
  188. X
  189. X#if     VMS
  190. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  191. X                return (s);
  192. X        TTputc('\n');                /* Already have '\r'    */
  193. X        TTflush();
  194. X        s = sys(line);                          /* Run the command.     */
  195. X        mlputs("\r\n\n[End]");                  /* Pause.               */
  196. X        TTflush();
  197. X        tgetc();
  198. X        sgarbf = TRUE;
  199. X        return (s);
  200. X#endif
  201. X#if     CPM
  202. X        mlwrite("Not in CP/M-86");
  203. X        return (FALSE);
  204. X#endif
  205. X#if     MSDOS
  206. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  207. X                return(s);
  208. X    movecursor(term.t_nrow - 1, 0);
  209. X    TTkclose();
  210. X        shellprog(line);
  211. X    TTkopen();
  212. X    /* if we are interactive, pause here */
  213. X    if (clexec == FALSE) {
  214. X            mlputs("\r\n\n[End]");
  215. X            tgetc();
  216. X        }
  217. X        sgarbf = TRUE;
  218. X        return (TRUE);
  219. X#endif
  220. X#if     ST520 & MWC
  221. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  222. X                return(s);
  223. X    mlerase();
  224. X    TTkclose();
  225. X        system(line);
  226. X    TTkopen();
  227. X    /* if we are interactive, pause here */
  228. X    if (clexec == FALSE) {
  229. X            mlputs("\r\n\n[End]");
  230. X            tgetc();
  231. X        }
  232. X        sgarbf = TRUE;
  233. X        return (TRUE);
  234. X#endif
  235. X#if     V7 | USG | BSD
  236. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  237. X                return (s);
  238. X        TTputc('\n');                /* Already have '\r'    */
  239. X        TTflush();
  240. X        TTclose();                              /* stty to old modes    */
  241. X        system(line);
  242. X        TTopen();
  243. X        mlputs("[End]");                        /* Pause.               */
  244. X        TTflush();
  245. X        while ((s = tgetc()) != '\r' && s != ' ')
  246. X                ;
  247. X        sgarbf = TRUE;
  248. X        return (TRUE);
  249. X#endif
  250. X}
  251. X
  252. X/*
  253. X * Run an external program with arguments. When it returns, wait for a single
  254. X * character to be typed, then mark the screen as garbage so a full repaint is
  255. X * done. Bound to "C-X $".
  256. X */
  257. X
  258. Xexecprg(f, n)
  259. X
  260. X{
  261. X        register int    s;
  262. X        char            line[NLINE];
  263. X
  264. X#if     AMIGA
  265. X        long newcli;
  266. X#endif
  267. X
  268. X    /* don't allow this command if restricted */
  269. X    if (restflag)
  270. X        return(resterr());
  271. X
  272. X#if    AMIGA
  273. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  274. X                return (s);
  275. X        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  276. X        Execute(line, 0L, newcli);
  277. X        Close(newcli);
  278. X        tgetc();     /* Pause.               */
  279. X        sgarbf = TRUE;
  280. X        return(TRUE);
  281. X#endif
  282. X
  283. X#if     VMS
  284. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  285. X                return (s);
  286. X        TTputc('\n');                /* Already have '\r'    */
  287. X        TTflush();
  288. X        s = sys(line);                          /* Run the command.     */
  289. X        mlputs("\r\n\n[End]");                  /* Pause.               */
  290. X        TTflush();
  291. X        tgetc();
  292. X        sgarbf = TRUE;
  293. X        return (s);
  294. X#endif
  295. X#if     CPM
  296. X        mlwrite("Not in CP/M-86");
  297. X        return (FALSE);
  298. X#endif
  299. X#if     MSDOS
  300. X        if ((s=mlreply("$", line, NLINE)) != TRUE)
  301. X                return(s);
  302. X    movecursor(term.t_nrow - 1, 0);
  303. X    TTkclose();
  304. X        execprog(line);
  305. X    TTkopen();
  306. X    /* if we are interactive, pause here */
  307. X    if (clexec == FALSE) {
  308. X            mlputs("\r\n\n[End]");
  309. X            tgetc();
  310. X        }
  311. X        sgarbf = TRUE;
  312. X        return (TRUE);
  313. X#endif
  314. X#if     ST520 & MWC
  315. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  316. X                return(s);
  317. X    mlerase();
  318. X    TTkclose();
  319. X        system(line);
  320. X    TTkopen();
  321. X    /* if we are interactive, pause here */
  322. X    if (clexec == FALSE) {
  323. X            mlputs("\r\n\n[End]");
  324. X            tgetc();
  325. X        }
  326. X        sgarbf = TRUE;
  327. X        return (TRUE);
  328. X#endif
  329. X#if     V7 | USG | BSD
  330. X        if ((s=mlreply("!", line, NLINE)) != TRUE)
  331. X                return (s);
  332. X        TTputc('\n');                /* Already have '\r'    */
  333. X        TTflush();
  334. X        TTclose();                              /* stty to old modes    */
  335. X        system(line);
  336. X        TTopen();
  337. X        mlputs("[End]");                        /* Pause.               */
  338. X        TTflush();
  339. X        while ((s = tgetc()) != '\r' && s != ' ')
  340. X                ;
  341. X        sgarbf = TRUE;
  342. X        return (TRUE);
  343. X#endif
  344. X}
  345. X
  346. X/*
  347. X * Pipe a one line command into a window
  348. X * Bound to ^X @
  349. X */
  350. Xpipecmd(f, n)
  351. X{
  352. X        register int    s;    /* return status from CLI */
  353. X    register WINDOW *wp;    /* pointer to new window */
  354. X    register BUFFER *bp;    /* pointer to buffer to zot */
  355. X        char    line[NLINE];    /* command line send to shell */
  356. X    static char bname[] = "command";
  357. X
  358. X#if    AMIGA
  359. X    static char filnam[] = "ram:command";
  360. X        long newcli;
  361. X#else
  362. X    static char filnam[NSTRING] = "command";
  363. X#endif
  364. X
  365. X#if     MSDOS | (ST520 & MWC)
  366. X    char *tmp;
  367. X    char *getenv();
  368. X    FILE *fp;
  369. X    FILE *fopen();
  370. X#endif
  371. X
  372. X    /* don't allow this command if restricted */
  373. X    if (restflag)
  374. X        return(resterr());
  375. X
  376. X#if    MSDOS
  377. X    if ((tmp = getenv("TMP")) == NULL)
  378. X        strcpy(filnam, "command");
  379. X    else {
  380. X        strcpy(filnam, tmp);
  381. X                strcat(filnam,"\\command");
  382. X        }
  383. X#endif
  384. X
  385. X#if     VMS
  386. X    mlwrite("Not availible under VMS");
  387. X    return(FALSE);
  388. X#endif
  389. X#if     CPM
  390. X        mlwrite("Not availible under CP/M-86");
  391. X        return(FALSE);
  392. X#endif
  393. X
  394. X    /* get the command to pipe in */
  395. X        if ((s=mlreply("@", line, NLINE)) != TRUE)
  396. X                return(s);
  397. X
  398. X    /* get rid of the command output buffer if it exists */
  399. X        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  400. X        /* try to make sure we are off screen */
  401. X        wp = wheadp;
  402. X        while (wp != NULL) {
  403. X            if (wp->w_bufp == bp) {
  404. X                onlywind(FALSE, 1);
  405. X                break;
  406. X            }
  407. X            wp = wp->w_wndp;
  408. X        }
  409. X        if (zotbuf(bp) != TRUE)
  410. X
  411. X            return(FALSE);
  412. X    }
  413. X
  414. X#if     AMIGA
  415. X        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  416. X    strcat(line, " >");
  417. X    strcat(line, filnam);
  418. X        Execute(line, 0L, newcli);
  419. X    s = TRUE;
  420. X        Close(newcli);
  421. X        sgarbf = TRUE;
  422. X#endif
  423. X#if     MSDOS | (ST520 & MWC)
  424. X    strcat(line," >>");
  425. X    strcat(line,filnam);
  426. X    movecursor(term.t_nrow - 1, 0);
  427. X    TTkclose();
  428. X#if    MSDOS
  429. X        shellprog(line);
  430. X#else
  431. X    system(line);
  432. X#endif
  433. X    TTkopen();
  434. X        sgarbf = TRUE;
  435. X    if ((fp = fopen(filnam, "r")) == NULL) {
  436. X        s = FALSE;
  437. X    } else {
  438. X        fclose(fp);
  439. X        s = TRUE;
  440. X    }
  441. X#endif
  442. X#if     V7 | USG | BSD
  443. X        TTputc('\n');                /* Already have '\r'    */
  444. X        TTflush();
  445. X        TTclose();                              /* stty to old modes    */
  446. X    strcat(line,">");
  447. X    strcat(line,filnam);
  448. X        system(line);
  449. X        TTopen();
  450. X        TTflush();
  451. X        sgarbf = TRUE;
  452. X        s = TRUE;
  453. X#endif
  454. X
  455. X    if (s != TRUE)
  456. X        return(s);
  457. X
  458. X    /* split the current window to make room for the command output */
  459. X    if (splitwind(FALSE, 1) == FALSE)
  460. X            return(FALSE);
  461. X
  462. X    /* and read the stuff in */
  463. X    if (getfile(filnam, FALSE) == FALSE)
  464. X        return(FALSE);
  465. X
  466. X    /* make this window in VIEW mode, update all mode lines */
  467. X    curwp->w_bufp->b_mode |= MDVIEW;
  468. X    wp = wheadp;
  469. X    while (wp != NULL) {
  470. X        wp->w_flag |= WFMODE;
  471. X        wp = wp->w_wndp;
  472. X    }
  473. X
  474. X    /* and get rid of the temporary file */
  475. X    unlink(filnam);
  476. X    return(TRUE);
  477. X}
  478. X
  479. X/*
  480. X * filter a buffer through an external DOS program
  481. X * Bound to ^X #
  482. X */
  483. Xfilter(f, n)
  484. X
  485. X{
  486. X        register int    s;    /* return status from CLI */
  487. X    register BUFFER *bp;    /* pointer to buffer to zot */
  488. X        char line[NLINE];    /* command line send to shell */
  489. X    char tmpnam[NFILEN];    /* place to store real file name */
  490. X    static char bname1[] = "fltinp";
  491. X
  492. X#if    AMIGA
  493. X    static char filnam1[] = "ram:fltinp";
  494. X    static char filnam2[] = "ram:fltout";
  495. X        long newcli;
  496. X#else
  497. X    static char filnam1[] = "fltinp";
  498. X    static char filnam2[] = "fltout";
  499. X#endif
  500. X
  501. X    /* don't allow this command if restricted */
  502. X    if (restflag)
  503. X        return(resterr());
  504. X
  505. X    if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  506. X        return(rdonly());    /* we are in read only mode    */
  507. X
  508. X#if     VMS
  509. X    mlwrite("Not availible under VMS");
  510. X    return(FALSE);
  511. X#endif
  512. X#if     CPM
  513. X        mlwrite("Not availible under CP/M-86");
  514. X        return(FALSE);
  515. X#endif
  516. X
  517. X    /* get the filter name and its args */
  518. X        if ((s=mlreply("#", line, NLINE)) != TRUE)
  519. X                return(s);
  520. X
  521. X    /* setup the proper file names */
  522. X    bp = curbp;
  523. X    strcpy(tmpnam, bp->b_fname);    /* save the original name */
  524. X    strcpy(bp->b_fname, bname1);    /* set it to our new one */
  525. X
  526. X    /* write it out, checking for errors */
  527. X    if (writeout(filnam1) != TRUE) {
  528. X        mlwrite("[Cannot write filter file]");
  529. X        strcpy(bp->b_fname, tmpnam);
  530. X        return(FALSE);
  531. X    }
  532. X
  533. X#if     AMIGA
  534. X        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  535. X    strcat(line, " <ram:fltinp >ram:fltout");
  536. X        Execute(line,0L,newcli);
  537. X    s = TRUE;
  538. X        Close(newcli);
  539. X        sgarbf = TRUE;
  540. X#endif
  541. X#if     MSDOS | (ST520 & MWC)
  542. X    strcat(line," <fltinp >fltout");
  543. X    movecursor(term.t_nrow - 1, 0);
  544. X    TTkclose();
  545. X#if    MSDOS
  546. X        shellprog(line);
  547. X#else
  548. X    system(line);
  549. X#endif
  550. X    TTkopen();
  551. X        sgarbf = TRUE;
  552. X    s = TRUE;
  553. X#endif
  554. X#if     V7 | USG | BSD
  555. X        TTputc('\n');                /* Already have '\r'    */
  556. X        TTflush();
  557. X        TTclose();                              /* stty to old modes    */
  558. X    strcat(line," <fltinp >fltout");
  559. X        system(line);
  560. X        TTopen();
  561. X        TTflush();
  562. X        sgarbf = TRUE;
  563. X        s = TRUE;
  564. X#endif
  565. X
  566. X    /* on failure, escape gracefully */
  567. X    if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  568. X        mlwrite("[Execution failed]");
  569. X        strcpy(bp->b_fname, tmpnam);
  570. X        unlink(filnam1);
  571. X        unlink(filnam2);
  572. X        return(s);
  573. X    }
  574. X
  575. X    /* reset file name */
  576. X    strcpy(bp->b_fname, tmpnam);    /* restore name */
  577. X    bp->b_flag |= BFCHG;        /* flag it as changed */
  578. X
  579. X    /* and get rid of the temporary file */
  580. X    unlink(filnam1);
  581. X    unlink(filnam2);
  582. X    return(TRUE);
  583. X}
  584. X
  585. X#if     VMS
  586. X/*
  587. X * Run a command. The "cmd" is a pointer to a command string, or NULL if you
  588. X * want to run a copy of DCL in the subjob (this is how the standard routine
  589. X * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
  590. X * and the way out, because DCL does not want the channel to be in raw mode.
  591. X */
  592. Xsys(cmd)
  593. Xregister char   *cmd;
  594. X{
  595. X        struct  dsc$descriptor  cdsc;
  596. X        struct  dsc$descriptor  *cdscp;
  597. X        long    status;
  598. X        long    substatus;
  599. X        long    iosb[2];
  600. X
  601. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  602. X                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
  603. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  604. X                return (FALSE);
  605. X        cdscp = NULL;                           /* Assume DCL.          */
  606. X        if (cmd != NULL) {                      /* Build descriptor.    */
  607. X                cdsc.dsc$a_pointer = cmd;
  608. X                cdsc.dsc$w_length  = strlen(cmd);
  609. X                cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  610. X                cdsc.dsc$b_class   = DSC$K_CLASS_S;
  611. X                cdscp = &cdsc;
  612. X        }
  613. X        status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
  614. X        if (status != SS$_NORMAL)
  615. X                substatus = status;
  616. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  617. X                          newmode, sizeof(newmode), 0, 0, 0, 0);
  618. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  619. X                return (FALSE);
  620. X        if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
  621. X                return (FALSE);
  622. X        return (TRUE);
  623. X}
  624. X#endif
  625. X
  626. X#if    ~AZTEC & ~MSC & ~TURBO & MSDOS
  627. X
  628. X/*
  629. X * This routine, once again by Bob McNamara, is a C translation of the "system"
  630. X * routine in the MWC-86 run time library. It differs from the "system" routine
  631. X * in that it does not unconditionally append the string ".exe" to the end of
  632. X * the command name. We needed to do this because we want to be able to spawn
  633. X * off "command.com". We really do not understand what it does, but if you don't
  634. X * do it exactly "malloc" starts doing very very strange things.
  635. X */
  636. Xsys(cmd, tail)
  637. Xchar    *cmd;
  638. Xchar    *tail;
  639. X{
  640. X#if MWC
  641. X        register unsigned n;
  642. X        extern   char     *__end;
  643. X
  644. X        n = __end + 15;
  645. X        n >>= 4;
  646. X        n = ((n + dsreg() + 16) & 0xFFF0) + 16;
  647. X        return(execall(cmd, tail, n));
  648. X#endif
  649. X
  650. X#if LATTICE
  651. X        return(forklp(cmd, tail, (char *)NULL));
  652. X#endif
  653. X}
  654. X#endif
  655. X
  656. X#if    MSDOS & LATTICE
  657. X/*    System: a modified version of lattice's system() function
  658. X        that detects the proper switchar and uses it
  659. X        written by Dana Hogget                */
  660. X
  661. Xsystem(cmd)
  662. X
  663. Xchar *cmd;    /*  Incoming command line to execute  */
  664. X
  665. X{
  666. X    char *getenv();
  667. X    static char *swchar = "/C";    /*  Execution switch  */
  668. X    union REGS inregs;    /*  parameters for dos call  */
  669. X    union REGS outregs;    /*  Return results from dos call  */
  670. X    char *shell;        /*  Name of system command processor  */
  671. X    char *p;        /*  Temporary pointer  */
  672. X    int ferr;        /*  Error condition if any  */
  673. X
  674. X    /*  get name of system shell  */
  675. X    if ((shell = getenv("COMSPEC")) == NULL) {
  676. X        return (-1);        /*  No shell located  */
  677. X    }
  678. X
  679. X    p = cmd;
  680. X    while (isspace(*p)) {        /*  find out if null command */
  681. X        p++;
  682. X    }
  683. X
  684. X    /**  If the command line is not empty, bring up the shell  **/
  685. X    /**  and execute the command.  Otherwise, bring up the     **/
  686. X    /**  shell in interactive mode.   **/
  687. X
  688. X    if (p && *p) {
  689. X        /**  detect current switch character and us it  **/
  690. X        inregs.h.ah = 0x37;    /*  get setting data  */
  691. X        inregs.h.al = 0x00;    /*  get switch character  */
  692. X        intdos(&inregs, &outregs);
  693. X        *swchar = outregs.h.dl;
  694. X        ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
  695. X    } else {
  696. X        ferr = forkl(shell, "command", (char *)NULL);
  697. X    }
  698. X
  699. X    return (ferr ? ferr : wait());
  700. X}
  701. X#endif
  702. X
  703. X#if    MSDOS & LATTICE
  704. Xextern int _oserr;
  705. X#endif
  706. X
  707. X#if    MSDOS & AZTEC
  708. Xextern int errno;
  709. X#endif
  710. X
  711. X#if    MSDOS & (TURBO | LATTICE | AZTEC)
  712. X/*    SHELLPROG: Execute a command in a subshell        */
  713. X
  714. Xshellprog(cmd)
  715. X
  716. Xchar *cmd;    /*  Incoming command line to execute  */
  717. X
  718. X{
  719. X    char *shell;        /* Name of system command processor */
  720. X    char *p;        /* Temporary pointer */
  721. X    char swchar;        /* switch character to use */
  722. X    union REGS regs;    /* parameters for dos call */
  723. X    char comline[NSTRING];    /* constructed command line */
  724. X    char *getenv();
  725. X
  726. X    /*  detect current switch character and set us up to use it */
  727. X    regs.h.ah = 0x37;    /*  get setting data  */
  728. X    regs.h.al = 0x00;    /*  get switch character  */
  729. X    intdos(®s, ®s);
  730. X    swchar = (char)regs.h.dl;
  731. X
  732. X    /*  get name of system shell  */
  733. X    if ((shell = getenv("COMSPEC")) == NULL) {
  734. X        return(FALSE);        /*  No shell located  */
  735. X    }
  736. X
  737. X    /* trim leading whitespace off the command */
  738. X    while (*cmd == ' ' || *cmd == '\t')    /*  find out if null command */
  739. X        cmd++;
  740. X
  741. X    /**  If the command line is not empty, bring up the shell  **/
  742. X    /**  and execute the command.  Otherwise, bring up the     **/
  743. X    /**  shell in interactive mode.   **/
  744. X
  745. X    if (*cmd) {
  746. X        strcpy(comline, shell);
  747. X        strcat(comline, " ");
  748. X        comline[strlen(comline) + 1] = 0;
  749. X        comline[strlen(comline)] = swchar;
  750. X        strcat(comline, "c ");
  751. X        strcat(comline, cmd);
  752. X        return(execprog(comline));
  753. X    } else
  754. X        return(execprog(shell));
  755. X}
  756. X
  757. X/*    EXECPROG:    A function to execute a named program
  758. X            with arguments
  759. X*/
  760. X
  761. Xexecprog(cmd)
  762. X
  763. Xchar *cmd;    /*  Incoming command line to execute  */
  764. X
  765. X{
  766. X    char *sp;        /* temporary string pointer */
  767. X    char f1[38];        /* FCB1 area (not initialized */
  768. X    char f2[38];        /* FCB2 area (not initialized */
  769. X    char prog[NSTRING];    /* program filespec */
  770. X    char tail[NSTRING];    /* command tail with length byte */
  771. X    union REGS regs;    /* parameters for dos call  */
  772. X    struct SREGS segreg;    /* segment registers for dis call */
  773. X    struct pblock {        /* EXEC parameter block */
  774. X        short envptr;    /* 2 byte pointer to environment string */
  775. X        char *cline;    /* 4 byte pointer to command line */
  776. X        char *fcb1;    /* 4 byte pointer to FCB at PSP+5Ch */
  777. X        char *fcb2;    /* 4 byte pointer to FCB at PSP+6Ch */
  778. X    } pblock;
  779. X    char *flook();
  780. X
  781. X    /* parse the command name from the command line */
  782. X    sp = prog;
  783. X    while (*cmd && (*cmd != ' ') && (*cmd != '\t'))
  784. X        *sp++ = *cmd++;
  785. X    *sp = 0;
  786. X
  787. X    /* and parse out the command tail */
  788. X    while (*cmd && ((*cmd == ' ') || (*cmd == '\t')))
  789. X        ++cmd;
  790. X    *tail = (char)(strlen(cmd)); /* record the byte length */
  791. X    strcpy(&tail[1], cmd);
  792. X    strcat(&tail[1], "\r");
  793. X
  794. X    /* look up the program on the path trying various extentions */
  795. X    if ((sp = flook(prog, TRUE)) == NULL)
  796. X        if ((sp = flook(strcat(prog, ".exe"), TRUE)) == NULL) {
  797. X            strcpy(&prog[strlen(prog)-4], ".com");
  798. X            if ((sp = flook(prog, TRUE)) == NULL)
  799. X                return(FALSE);
  800. X        }
  801. X    strcpy(prog, sp);
  802. X
  803. X    /* get a pointer to this PSPs environment segment number */
  804. X    segread(&segreg);
  805. X
  806. X    /* set up the EXEC parameter block */
  807. X    pblock.envptr = 0;    /* make the child inherit the parents env */
  808. X    pblock.fcb1 = f1;        /* point to a blank FCB */
  809. X    pblock.fcb2 = f2;        /* point to a blank FCB */
  810. X        pblock.cline = tail;        /* parameter line pointer */
  811. X
  812. X    /* and make the call */
  813. X    regs.h.ah = 0x4b;    /* EXEC Load or Execute a Program */
  814. X    regs.h.al = 0x00;    /* load end execute function subcode */
  815. X#if    AZTEC
  816. X    regs.x.ds = ((unsigned long)(prog) >> 16);    /* program name ptr */
  817. X#else
  818. X    segreg.ds = ((unsigned long)(prog) >> 16);    /* program name ptr */
  819. X#endif
  820. X    regs.x.dx = (unsigned int)(prog);
  821. X#if    AZTEC
  822. X    regs.x.es = regs.x.ds;
  823. X    /*regs.x.es = ((unsigned long)(&pblock) >> 16);    * set up param block ptr */
  824. X#else
  825. X    segreg.es = ((unsigned long)(&pblock) >> 16);    /* set up param block ptr */
  826. X#endif
  827. X    regs.x.bx = (unsigned int)(&pblock);
  828. X#if    LATTICE
  829. X#define    CFLAG    1
  830. X    if ((intdosx(®s, ®s, &segreg) & CFLAG) == 0) {
  831. X        regs.h.ah = 0x4d;    /* get child process return code */
  832. X        intdos(®s, ®s);    /* go do it */
  833. X        rval = regs.x.ax;    /* save child's return code */
  834. X    } else
  835. X        rval = -_oserr;        /* failed child call */
  836. X#endif
  837. X#if    AZTEC
  838. X#define    CFLAG    1
  839. X    if ((sysint(0x21, ®s, ®s) & CFLAG) == 0) {
  840. X        regs.h.ah = 0x4d;    /* get child process return code */
  841. X        sysint(0x21, ®s, ®s);    /* go do it */
  842. X        rval = regs.x.ax;    /* save child's return code */
  843. X    } else
  844. X        rval = -errno;        /* failed child call */
  845. X#endif
  846. X#if    TURBO
  847. X    intdosx(®s, ®s, &segreg);
  848. X    if (regs.x.cflag == 0) {
  849. X        regs.h.ah = 0x4d;    /* get child process return code */
  850. X        intdos(®s, ®s);    /* go do it */
  851. X        rval = regs.x.ax;    /* save child's return code */
  852. X    } else
  853. X        rval = -_doserrno;    /* failed child call */
  854. X#endif
  855. X    return((rval < 0) ? FALSE : TRUE);
  856. X}
  857. X#endif
  858. FRIDAY_NIGHT
  859. echo extracting - st520.c
  860. sed 's/^X//' > st520.c << 'FRIDAY_NIGHT'
  861. X/*
  862. X
  863. XThe routines in this file provide support for the Atari 520 or 1040ST
  864. Xusing VT52 emulation.  The I/O services are provided here as well.  It
  865. Xcompiles into nothing if not a 520ST style device. The only compiler
  866. Xsupported directly is Mark Williams C
  867. X
  868. XAdditional code and ideas from:
  869. X
  870. X        James Turner
  871. X        Jeff Lomicka
  872. X        J. C. Benoist
  873. X
  874. X*/
  875. X
  876. X#define    termdef    1            /* don't define "term" external */
  877. X
  878. X#include        <stdio.h>
  879. X#include        "estruct.h"
  880. X#include    "edef.h"
  881. X
  882. X#if    ATARI & ST520
  883. X
  884. X/*
  885. X    These routines provide support for the ATARI 1040ST and 520ST
  886. Xusing the virtual VT52 Emulator
  887. X
  888. X*/
  889. X
  890. X#include    <osbind.h>
  891. X#include    <aline.h>
  892. X#include    <linea.h>
  893. X
  894. X#define NROW    50    /* Screen size.         */
  895. X#define NCOL    80    /* Edit if you want to.     */
  896. X#define    MARGIN    8    /* size of minimim margin and    */
  897. X#define    SCRSIZ    64    /* scroll size for extended lines */
  898. X#define    NPAUSE    300    /* # times thru update to pause */
  899. X#define BIAS    0x20    /* Origin 0 coordinate bias.    */
  900. X#define ESC    0x1B    /* ESC character.        */
  901. X#define SCRFONT 2    /* index of 8x16 monochrome system default font */
  902. X#define DENSIZE    50    /* # of lines in a dense screen    */
  903. X
  904. X/****    ST Internals definitions        *****/
  905. X
  906. X/*    BIOS calls */
  907. X
  908. X#define    BCONSTAT    1    /* return input device status */
  909. X#define    CONIN        2    /* read character from device */
  910. X#define    BCONOUT        3    /* write character to device */
  911. X
  912. X/*    XBIOS calls */
  913. X
  914. X#define    INITMOUS    0    /* initialize the mouse */
  915. X#define    GETREZ        4    /* get current resolution */
  916. X#define    SETSCREEN    5    /* set screen resolution */
  917. X#define    SETPALETTE    6    /* set the color pallette */
  918. X#define    SETCOLOR    7    /* set or read a color */
  919. X#define    CURSCONF    21    /* set cursor configuration */
  920. X#define    IKBDWS        25    /* intelligent keyboard send command */
  921. X#define    KBDVBASE    34    /* get keyboard table base */
  922. X
  923. X/*    GEMDOS calls */
  924. X
  925. X#define    EXEC        0x4b    /* Exec off a process */
  926. X
  927. X#define    CON        2    /* CON: Keyboard and screen device */
  928. X
  929. X/*    Palette color definitions    */
  930. X
  931. X#define    LOWPAL    "000700070770007707077777"
  932. X#define    MEDPAL    "000700007777"
  933. X#define    HIGHPAL    "111000"
  934. X
  935. X/*    ST Global definitions        */
  936. X
  937. X/* keyboard vector table */
  938. Xstruct KVT {
  939. X    long midivec;        /* midi input */
  940. X    long vkbderr;        /* keyboard error */
  941. X    long vmiderr;        /* MIDI error */
  942. X    long statvec;        /* IKBD status */
  943. X    int (*mousevec)();    /* mouse vector */
  944. X    long clockvec;        /* clock vector */
  945. X    long joyvec;        /* joystict vector */
  946. X} *ktable;
  947. X
  948. Xint (*sysmint)();            /* system mouse interupt handler */
  949. X
  950. X/* mouse parameter table */
  951. Xstruct Param {
  952. X    char topmode;
  953. X    char buttons;
  954. X    char xparam;
  955. X    char yparam;
  956. X    int xmax,ymax;
  957. X    int xinitial,yinitial;
  958. X} mparam;
  959. X
  960. Xint initrez;            /* initial screen resolution */
  961. Xint currez;            /* current screen resolution */
  962. Xchar resname[][8] = {        /* screen resolution names */
  963. X    "LOW", "MEDIUM", "HIGH", "DENSE"
  964. X};
  965. Xshort spalette[16];        /* original color palette settings */
  966. Xshort palette[16];        /* current palette settings */
  967. X
  968. XLINEA *aline;    /* Pointer to line a parameter block returned by init */
  969. X
  970. XNLINEA *naline;    /* Pointer to line a parameters at negative offsets  */
  971. X
  972. XFONT  **fonts;    /* Array of pointers to the three system font headers */
  973. X        /* returned by init (in register A1)                  */
  974. X
  975. XWORD  (**foncs)();    /* Array of pointers to the 15 line a functions      */
  976. X                     /* returned by init (in register A2)                 */
  977. X                     /* only valid in ROM'ed TOS                          */
  978. X
  979. XFONT *system_font;    /* pointer to default system font */
  980. XFONT *small_font;    /* pointer to small font */
  981. X
  982. Xextern  int     ttopen();               /* Forward references.          */
  983. Xextern  int     ttgetc();
  984. Xextern  int     ttputc();
  985. Xextern  int     ttflush();
  986. Xextern  int     ttclose();
  987. Xextern  int     stmove();
  988. Xextern  int     steeol();
  989. Xextern  int     steeop();
  990. Xextern  int     stbeep();
  991. Xextern  int     stopen();
  992. Xextern    int    stclose();
  993. Xextern    int    stgetc();
  994. Xextern    int    stputc();
  995. Xextern    int    strev();
  996. Xextern    int    strez();
  997. Xextern    int    stkopen();
  998. Xextern    int    stkclose();
  999. X
  1000. X#if    COLOR
  1001. Xextern    int    stfcol();
  1002. Xextern    int    stbcol();
  1003. X#endif
  1004. X
  1005. X/*
  1006. X * Dispatch table. All the
  1007. X * hard fields just point into the
  1008. X * terminal I/O code.
  1009. X */
  1010. XTERM    term    = {
  1011. X    NROW-1,
  1012. X        NROW-1,
  1013. X        NCOL,
  1014. X        NCOL,
  1015. X    MARGIN,
  1016. X    SCRSIZ,
  1017. X    NPAUSE,
  1018. X        &stopen,
  1019. X        &stclose,
  1020. X    &stkopen,
  1021. X    &stkclose,
  1022. X        &stgetc,
  1023. X    &stputc,
  1024. X        &ttflush,
  1025. X        &stmove,
  1026. X        &steeol,
  1027. X        &steeop,
  1028. X        &stbeep,
  1029. X        &strev,
  1030. X    &strez
  1031. X#if    COLOR
  1032. X    , &stfcol,
  1033. X    &stbcol
  1034. X#endif
  1035. X};
  1036. X
  1037. Xvoid init_aline()
  1038. X{
  1039. X       linea0();
  1040. X       aline = (LINEA *)(la_init.li_a0);
  1041. X       fonts = (FONT **)(la_init.li_a1);
  1042. X       foncs = la_init.li_a2;
  1043. X       naline = ((NLINEA *)aline) - 1;
  1044. X}
  1045. X
  1046. Xinit()
  1047. X{
  1048. X       init_aline();
  1049. X       system_font = fonts[SCRFONT];        /* save it */
  1050. X    small_font = fonts[1];
  1051. X}
  1052. X
  1053. X
  1054. Xswitch_font(fp)
  1055. X
  1056. XFONT *fp;
  1057. X
  1058. X{
  1059. X       /* See aline.h for description of fields */
  1060. X    /* these definitions are temporary...too many cooks!!! */
  1061. X#undef    V_CEL_HT
  1062. X#undef    V_CEL_WR
  1063. X#undef    V_CEL_MY
  1064. X#undef    V_CEL_MX
  1065. X#undef    V_FNT_ST
  1066. X#undef    V_FNT_ND
  1067. X#undef    V_FNT_AD
  1068. X#undef    V_FNT_WR
  1069. X#undef    V_OFF_AD
  1070. X#undef    VWRAP
  1071. X#undef    V_Y_MAX
  1072. X#undef    V_X_MAX
  1073. X
  1074. X       naline->V_CEL_HT = fp->form_height;
  1075. X       naline->V_CEL_WR = aline->VWRAP * fp->form_height;
  1076. X       naline->V_CEL_MY = (naline->V_Y_MAX / fp->form_height) - 1;
  1077. X       naline->V_CEL_MX = (naline->V_X_MAX / fp->max_cell_width) - 1;
  1078. X       naline->V_FNT_WR = fp->form_width;
  1079. X       naline->V_FNT_ST = fp->first_ade;
  1080. X       naline->V_FNT_ND = fp->last_ade;
  1081. X       naline->V_OFF_AD = fp->off_table;
  1082. X       naline->V_FNT_AD =  fp->dat_table;
  1083. X}
  1084. X
  1085. Xstmove(row, col)
  1086. X{
  1087. X        stputc(ESC);
  1088. X        stputc('Y');
  1089. X        stputc(row+BIAS);
  1090. X        stputc(col+BIAS);
  1091. X}
  1092. X
  1093. Xsteeol()
  1094. X{
  1095. X        stputc(ESC);
  1096. X        stputc('K');
  1097. X}
  1098. X
  1099. Xsteeop()
  1100. X{
  1101. X#if    COLOR
  1102. X    stfcol(gfcolor);
  1103. X    stbcol(gbcolor);
  1104. X#endif
  1105. X        stputc(ESC);
  1106. X        stputc('J');
  1107. X}
  1108. X
  1109. Xstrev(status)    /* set the reverse video state */
  1110. X
  1111. Xint status;    /* TRUE = reverse video, FALSE = normal video */
  1112. X
  1113. X{
  1114. X    if (currez > 1) {
  1115. X        stputc(ESC);
  1116. X        stputc(status ? 'p' : 'q');
  1117. X    }
  1118. X}
  1119. X
  1120. X#if    COLOR
  1121. Xmapcol(clr)    /* medium rez color translation */
  1122. X
  1123. Xint clr;    /* emacs color number to translate */
  1124. X
  1125. X{
  1126. X    static int mctable[] = {0, 1, 2, 3, 2, 1, 2, 3};
  1127. X
  1128. X    if (currez != 1)
  1129. X        return(clr);
  1130. X    else
  1131. X        return(mctable[clr]);
  1132. X}
  1133. X
  1134. Xstfcol(color)    /* set the forground color */
  1135. X
  1136. Xint color;    /* color to set forground to */
  1137. X
  1138. X{
  1139. X    if (currez < 2) {
  1140. X        stputc(ESC);
  1141. X        stputc('b');
  1142. X        stputc(mapcol(color));
  1143. X    }
  1144. X}
  1145. X
  1146. Xstbcol(color)    /* set the background color */
  1147. X
  1148. Xint color;    /* color to set background to */
  1149. X
  1150. X
  1151. X{
  1152. X    if (currez < 2) {
  1153. X        stputc(ESC);
  1154. X        stputc('c');
  1155. X        stputc(mapcol(color));
  1156. X    }
  1157. X}
  1158. X#endif
  1159. X
  1160. Xstatic char beep[] = {
  1161. X    0x00, 0x00,
  1162. X    0x01, 0x01,
  1163. X    0x02, 0x01,
  1164. X    0x03, 0x01,
  1165. X    0x04, 0x02,
  1166. X    0x05, 0x01,
  1167. X    0x07, 0x38,
  1168. X    0x08, 0x10,
  1169. X    0x09, 0x10,
  1170. X    0x0A, 0x10,
  1171. X    0x0B, 0x00,
  1172. X    0x0C, 0x30,
  1173. X    0x0D, 0x03,
  1174. X    0xFF, 0x00
  1175. X};
  1176. X
  1177. Xstbeep()
  1178. X{
  1179. X    Dosound(beep);
  1180. X}
  1181. X
  1182. Xdomouse()    /* mouse interupt handler */
  1183. X
  1184. X{
  1185. X    return((*sysmint)());
  1186. X}
  1187. X
  1188. Xstkopen()    /* open the keyboard (and mouse) */
  1189. X
  1190. X{
  1191. X    /* grab the keyboard vector table */
  1192. X    ktable = (struct KVT *)xbios(KBDVBASE);
  1193. X    sysmint = ktable->mousevec;    /* save mouse vector */
  1194. X
  1195. X    /* initialize the mouse */
  1196. X    mparam.topmode = 0;
  1197. X    mparam.buttons = 4;
  1198. X    mparam.xparam = 8;
  1199. X    mparam.yparam = 10;
  1200. X    mparam.xmax = 79;
  1201. X    mparam.ymax = 23;
  1202. X    mparam.xinitial = 0;
  1203. X    mparam.yinitial = 0;
  1204. X    xbios(INITMOUS, 4, &mparam, &domouse);
  1205. X}
  1206. X
  1207. Xstopen()    /* open the screen */
  1208. X
  1209. X{
  1210. X    int i;
  1211. X
  1212. X        ttopen();
  1213. X    eolexist = TRUE;
  1214. X    init();
  1215. X
  1216. X    /* switch to a steady cursor */
  1217. X    xbios(CURSCONF, 3);
  1218. X
  1219. X    /* save the current color palette */
  1220. X    for (i=0; i<16; i++)
  1221. X        spalette[i] = xbios(SETCOLOR, i, -1);
  1222. X
  1223. X    /* and find the current resolution */
  1224. X    initrez = currez = xbios(GETREZ);
  1225. X    strcpy(sres, resname[currez]);
  1226. X
  1227. X    /* set up the screen size and palette */
  1228. X    switch (currez) {
  1229. X        case 0:    term.t_mrow = 25 - 1;
  1230. X            term.t_nrow = 25 - 1;
  1231. X            term.t_ncol = 40;
  1232. X            strcpy(palstr, LOWPAL);
  1233. X            break;
  1234. X
  1235. X        case 1: term.t_mrow = 25 - 1;
  1236. X            term.t_nrow = 25 - 1;
  1237. X            strcpy(palstr, MEDPAL);
  1238. X            break;
  1239. X
  1240. X        case 2: term.t_mrow = DENSIZE - 1;
  1241. X            term.t_nrow = 25 - 1;
  1242. X            strcpy(palstr, HIGHPAL);
  1243. X    }
  1244. X
  1245. X    /* and set up the default palette */
  1246. X    spal(palstr);
  1247. X
  1248. X    stputc(ESC);    /* automatic overflow off */
  1249. X    stputc('w');
  1250. X    stputc(ESC);    /* turn cursor on */
  1251. X    stputc('e');
  1252. X}
  1253. X
  1254. Xstkclose()    /* close the keyboard (and mouse) */
  1255. X
  1256. X{
  1257. X    static char resetcmd[] = {0x80, 0x01};    /* keyboard reset command */
  1258. X
  1259. X    /* restore the mouse interupt routines */
  1260. X    xbios(INITMOUS, 2, &mparam, (long)sysmint);
  1261. X
  1262. X    /* and reset the keyboard controller */
  1263. X    xbios(IKBDWS, 1, &resetcmd[0]);
  1264. X}
  1265. X
  1266. Xstclose()
  1267. X
  1268. X{
  1269. X    stputc(ESC);    /* auto overflow on */
  1270. X    stputc('v');
  1271. X
  1272. X    /* switch to a flashing cursor */
  1273. X    xbios(CURSCONF, 2);
  1274. X
  1275. X    /* restore the original screen resolution */
  1276. X    if (currez == 3)
  1277. X        switch_font(system_font);
  1278. X    strez(resname[initrez]);
  1279. X
  1280. X    /* restore the original palette settings */
  1281. X    xbios(SETPALETTE, spalette);
  1282. X
  1283. X    ttclose();
  1284. X}
  1285. X
  1286. X/*     spal(pstr):    reset the current palette according to a
  1287. X            "palette string" of the form
  1288. X
  1289. X    000111222333444555666777
  1290. X
  1291. X    which contains the octal values for the palette registers
  1292. X*/
  1293. X
  1294. Xspal(pstr)
  1295. X
  1296. Xchar *pstr;    /* palette string */
  1297. X
  1298. X{
  1299. X    int pal;    /* current palette position */
  1300. X    int clr;    /* current color value */
  1301. X    int i;
  1302. X
  1303. X    for (pal = 0; pal < 16; pal++) {
  1304. X        if (*pstr== 0)
  1305. X            break;
  1306. X
  1307. X        /* parse off a color */
  1308. X        clr = 0;
  1309. X        for (i = 0; i < 3; i++)
  1310. X            if (*pstr)
  1311. X                clr = clr * 16 + (*pstr++ - '0');
  1312. X        palette[pal] = clr;
  1313. X    };
  1314. X
  1315. X    /* and now set it */
  1316. X    xbios(SETPALETTE, palette);
  1317. X}
  1318. X
  1319. Xstgetc()    /* get a char from the keyboard */
  1320. X
  1321. X{
  1322. X    register long rval;    /* return value from BIOS call */
  1323. X    static int funkey = 0;    /* held fuction key scan code */
  1324. X    static long sh;        /* shift/alt key on held function? */
  1325. X    long bios();
  1326. X
  1327. X    /* if there is a pending function key, return it */
  1328. X    if (funkey) {
  1329. X        if (sh) {    /* alt or cntrl */
  1330. X            if (funkey >= 0x3B && funkey <= 0x44) {
  1331. X                rval = funkey + '^' - ';';
  1332. X                if (sh & 0x08)    /* alt */
  1333. X                    rval += 10;
  1334. X                funkey = 0;
  1335. X                return(rval & 255);
  1336. X            }
  1337. X        }
  1338. X        rval = funkey;
  1339. X        funkey = 0;
  1340. X    } else {
  1341. X        /* waiting... flash the cursor */
  1342. X        xbios(CURSCONF, 2);
  1343. X
  1344. X        /* get the character */
  1345. X        rval = bios(CONIN, CON);
  1346. X        sh = Getshift(-1) & 0x0cL; /* see if alt or cntrl depressed */
  1347. X        if ((rval & 255L) == 0L) {
  1348. X            funkey = (rval >> 16L) & 255;
  1349. X            rval = 0;
  1350. X        }
  1351. X
  1352. X    }
  1353. X
  1354. X    /* and switch to a steady cursor */
  1355. X    xbios(CURSCONF, 3);
  1356. X
  1357. X    return(rval & 255);
  1358. X}
  1359. X
  1360. Xstputc(c)    /* output char c to the screen */
  1361. X
  1362. Xchar c;        /* character to print out */
  1363. X
  1364. X{
  1365. X    bios(BCONOUT, CON, c);
  1366. X}
  1367. X
  1368. Xstrez(newrez)    /* change screen resolution */
  1369. X
  1370. Xchar *newrez;    /* requested resolution */
  1371. X
  1372. X{
  1373. X    int nrez;    /* requested new resolution */
  1374. X
  1375. X    /* first, decode the resolution name */
  1376. X    for (nrez = 0; nrez < 4; nrez++)
  1377. X        if (strcmp(newrez, resname[nrez]) == 0)
  1378. X            break;
  1379. X    if (nrez == 4) {
  1380. X        mlwrite("%%No such resolution");
  1381. X        return(FALSE);
  1382. X    }
  1383. X
  1384. X    /* next, make sure this resolution is legal for this monitor */
  1385. X    if ((currez < 2 && nrez > 1) || (currez > 1 && nrez < 2)) {
  1386. X        mlwrite("%%Resolution illegal for this monitor");
  1387. X        return(FALSE);
  1388. X    }
  1389. X
  1390. X    /* eliminate non-changes */
  1391. X    if (currez == nrez)
  1392. X        return(TRUE);
  1393. X
  1394. X    /* finally, make the change */
  1395. X    switch (nrez) {
  1396. X        case 0:    /* low resolution - 16 colors */
  1397. X            newwidth(TRUE, 40);
  1398. X            strcpy(palstr, LOWPAL);
  1399. X            xbios(SETSCREEN, -1L, -1L, 0);
  1400. X            break;
  1401. X
  1402. X        case 1:    /* medium resolution - 4 colors */
  1403. X            newwidth(TRUE, 80);
  1404. X            strcpy(palstr, MEDPAL);
  1405. X            xbios(SETSCREEN, -1L, -1L, 1);
  1406. X            break;
  1407. X
  1408. X        case 2:    /* High resolution - 2 colors - 25 lines */
  1409. X            newsize(TRUE, 25);
  1410. X            strcpy(palstr, HIGHPAL);
  1411. X            switch_font(system_font);
  1412. X            break;
  1413. X
  1414. X        case 3:    /* Dense resolution - 2 colors - 40 lines */
  1415. X            newsize(TRUE, DENSIZE);
  1416. X            strcpy(palstr, HIGHPAL);
  1417. X            switch_font(small_font);
  1418. X            break;
  1419. X    }
  1420. X
  1421. X    /* and set up the default palette */
  1422. X    spal(palstr);
  1423. X    currez = nrez;
  1424. X    strcpy(sres, resname[currez]);
  1425. X
  1426. X    stputc(ESC);    /* automatic overflow off */
  1427. X    stputc('w');
  1428. X    stputc(ESC);    /* turn cursor on */
  1429. X    stputc('e');
  1430. X
  1431. X    return(TRUE);
  1432. X}
  1433. X
  1434. X#if    LATTICE
  1435. Xsystem(cmd)    /* call the system to execute a new program */
  1436. X
  1437. Xchar *cmd;    /* command to execute */
  1438. X
  1439. X{
  1440. X    char *pptr;            /* pointer into program name */
  1441. X    char pname[NSTRING];        /* name of program to execute */
  1442. X    char tail[NSTRING];        /* command tail */
  1443. X
  1444. X    /* scan off program name.... */
  1445. X    pptr = pname;
  1446. X    while (*cmd && (*cmd != ' ' && *cmd != '\t'))
  1447. X        *pptr++ = *cmd++;
  1448. X    *pptr = 0;
  1449. X
  1450. X    /* create program name length/string */
  1451. X    tail[0] = strlen(cmd);
  1452. X    strcpy(&tail[1], cmd);
  1453. X
  1454. X    /* go do it! */
  1455. X    return(gemdos(        (int)EXEC,
  1456. X                (int)0,
  1457. X                (char *)pname,
  1458. X                (char *)tail,
  1459. X                (char *)NULL));
  1460. X}
  1461. X#endif
  1462. X
  1463. X#if    TYPEAH
  1464. Xtypahead()
  1465. X
  1466. X{
  1467. X    int rval;    /* return value from BIOS call */
  1468. X
  1469. X    /* get the status of the console */
  1470. X    rval = bios(BCONSTAT, CON);
  1471. X
  1472. X    /* end return the results */
  1473. X    if (rval == 0)
  1474. X        return(FALSE);
  1475. X    else
  1476. X        return(TRUE);
  1477. X}
  1478. X#endif
  1479. X
  1480. X#if    FLABEL
  1481. Xfnclabel(f, n)        /* label a function key */
  1482. X
  1483. Xint f,n;    /* default flag, numeric argument [unused] */
  1484. X
  1485. X{
  1486. X    /* on machines with no function keys...don't bother */
  1487. X    return(TRUE);
  1488. X}
  1489. X#endif
  1490. X#else
  1491. Xsthello()
  1492. X{
  1493. X}
  1494. X#endif
  1495. FRIDAY_NIGHT
  1496. echo mes.11 completed!
  1497. # That's all folks!
  1498.  
  1499.  
  1500.