home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff256.lzh / Stevie / amiga.c < prev    next >
C/C++ Source or Header  |  1989-10-19  |  12KB  |  556 lines

  1. /*
  2.  * Amiga system-dependent routines. 
  3.  */
  4.  
  5. #include <proto/exec.h>
  6. #include <proto/dos.h>
  7. #include <exec/memory.h>
  8. #include <devices/conunit.h>
  9. #include <stdio.h>
  10. #include <ios1.h>
  11. #include <error.h>
  12.  
  13. #include "stevie.h"
  14.  
  15. /* Globals initialized by get_ConUnit() */
  16. struct Window  *conWindow;
  17. struct ConUnit *conUnit;
  18.  
  19. extern int      errno;        /* The error variable */
  20.  
  21. long            raw_in = 0;
  22. long            raw_out = 0;
  23.  
  24. #define BSIZE   2048
  25. static char     outbuf[BSIZE];
  26. static int      bpos = 0;
  27.  
  28. void
  29. flushbuf()
  30. {
  31.     if (bpos != 0)
  32.     Write(raw_out, outbuf, bpos);
  33.     bpos = 0;
  34. }
  35.  
  36. void
  37. outchar(c)
  38.     char            c;
  39. {
  40.     outbuf[bpos++] = c;
  41.     if (bpos >= BSIZE)
  42.     flushbuf();
  43. }
  44.  
  45. void
  46. outstr(s)
  47.     char           *s;
  48. {
  49.     while (*s) {
  50.     outbuf[bpos++] = *s++;
  51.     if (bpos >= BSIZE)
  52.         flushbuf();
  53.     }
  54. }
  55.  
  56. int
  57. get_Rows_and_Columns()
  58. {
  59.     if (get_ConUnit(raw_in) != 0)
  60.     return (FALSE);
  61.     Rows = conUnit->cu_YMax + 1;
  62.     Columns = conUnit->cu_XMax + 1;
  63.     if (Rows < 0 || Rows > 200) {    /* AUX: device (I hope) */
  64.     Columns = 80;
  65.     Rows = 24;
  66.     Aux_Device = TRUE;
  67.     }
  68.     if (Columns < 5)
  69.     Columns = 5;
  70.     if (Columns > MAX_COLUMNS)
  71.     Columns = MAX_COLUMNS;
  72.     if (Rows < 2)
  73.     Rows = 2;
  74.     P(P_LI) = Rows;
  75.  
  76.     return (TRUE);
  77. }
  78.  
  79. int
  80. GetCharacter()
  81. {
  82.     char            c;
  83.  
  84.     Read(raw_in, &c, sizeof(c));
  85.     return ((int) c);
  86. }
  87.  
  88. /*
  89.  * getCSIsequence - get a CSI sequence
  90.  *                - either cursor keys, help, or function keys
  91.  */
  92.  
  93. int
  94. getCSIsequence()
  95. {
  96.     int             c;
  97.     int             tmp;
  98.  
  99.  
  100.     c = GetCharacter();
  101.     if (isdigit(c)) {
  102.     tmp = 0;
  103.     while (isdigit(c)) {
  104.         tmp = tmp * 10 + c - '0';
  105.         c = GetCharacter();
  106.     }
  107.     if (c == '~')        /* function key */
  108.         return ((char) (K_F1 + tmp));
  109.     }
  110.     switch (c) {
  111.       case 'A':        /* cursor up */
  112.     return K_UARROW;
  113.       case 'B':        /* cursor down */
  114.     return K_DARROW;
  115.       case 'C':        /* cursor right */
  116.     return K_RARROW;
  117.       case 'D':        /* cursor left */
  118.     return K_LARROW;
  119.       case 'T':        /* shift cursor up */
  120.     return K_SUARROW;
  121.       case 'S':        /* shift cursor down */
  122.     return K_SDARROW;
  123.       case ' ':        /* shift cursor left or right */
  124.     c = GetCharacter();
  125.     if (c == 'A')        /* shift cursor left */
  126.         return K_SLARROW;
  127.     if (c == '@')        /* shift cursor right */
  128.         return K_SRARROW;
  129.     break;
  130.       case '?':        /* help */
  131.     c = GetCharacter();
  132.     if (c == '~')
  133.         return K_HELP;
  134.     break;
  135.     }
  136.     while ((c != '|') && (c != '~')) {
  137.     if (WaitForChar(raw_in, 500L) == 0)
  138.         break;
  139.     c = GetCharacter();
  140.     }
  141.  
  142.     /* must have been screen resize event */
  143.     s_clear();
  144.     flushbuf();
  145.     if (get_Rows_and_Columns() == FALSE) {    /* hopefully never exit .... */
  146.     emsg("STEVIE: can't get ConUnit info ?!?!?!?\n");
  147.     sleep(5);
  148.     return 0;
  149.     }
  150.     screenalloc();
  151.     tmp = RedrawingDisabled;
  152.     RedrawingDisabled = TRUE;
  153.     S_NOT_VALID;
  154.     cursupdate(UPDATE_ALL);    /* make sure not below Botchar */
  155.     RedrawingDisabled = FALSE;
  156.     s_refresh(NOT_VALID);    /* draw it */
  157.     RedrawingDisabled = tmp;
  158.     windgoto(Cursrow, Curscol);
  159.     flushbuf();
  160.  
  161.     return 0;
  162. }
  163.  
  164. /*
  165.  * inchar() - get a character from the keyboard 
  166.  */
  167. int
  168. inchar()
  169. {
  170.     int             c;
  171.  
  172.     flushbuf();
  173.  
  174.     for (;;) {
  175.     c = GetCharacter();
  176.     if (c == 0x9b)
  177.         c = getCSIsequence();
  178.     if (c != 0)
  179.         break;
  180.     }
  181.  
  182.     return c;
  183. }
  184.  
  185. void
  186. beep()
  187. {
  188.     if (RedrawingDisabled)
  189.     return;
  190.  
  191.     outbuf[bpos++] = '\007';
  192.     if (bpos >= BSIZE)
  193.     flushbuf();
  194. }
  195.  
  196. void
  197. sleep(n)
  198.     int             n;
  199. {
  200.     void            Delay();
  201.  
  202.     if (n > 0)
  203.     Delay(50L * n);
  204. }
  205.  
  206. void
  207. delay()
  208. {
  209.     void            Delay();
  210.  
  211.     Delay(25L);
  212. }
  213.  
  214. void
  215. windinit()
  216. {
  217.     raw_in = Input();
  218.     if (!IsInteractive(raw_in)) {
  219.     raw_in = Open("RAW:0/0/640/200/STEVIE", MODE_NEWFILE);
  220.     if (raw_in == NULL) {
  221.         raw_in = Open("RAW:0/0/480/200/STEVIE", MODE_NEWFILE);
  222.         if (raw_in == NULL) {
  223.         fprintf(stderr, "STEVIE: Can't open window ?!?!?!?\n");
  224.         exit(2);
  225.         }
  226.     }
  227.     raw_out = raw_in;
  228.     } else {
  229.     raw_out = Output();
  230.     if (raw(raw_in) != 0) {
  231.         perror("STEVIE: Can't change to raw mode ?!?!?!?");
  232.         exit(2);
  233.     }
  234.     }
  235.  
  236.     if (get_Rows_and_Columns() == FALSE) {
  237.     fprintf(stderr, "STEVIE: can't get ConUnit info ?!?!?!?\n");
  238.     windexit(3);
  239.     }
  240.     if (!Aux_Device)
  241.     outstr("\033[12{");    /* window resize events activated */
  242.     flushbuf();
  243. }
  244.  
  245. void
  246. windexit(r)
  247.     int             r;
  248. {
  249.     if (!Aux_Device)
  250.     outstr("\033[12}");    /* window resize events de-activated */
  251.     flushbuf();
  252.  
  253.     if (raw_in != raw_out) {
  254.     if (cooked(raw_in) != 0)
  255.         perror("STEVIE: Can't change to cooked mode ?!?!?!?");
  256.     } else {
  257.     Close(raw_in);
  258.     }
  259.  
  260.     exit(r);
  261. }
  262.  
  263. void
  264. windgoto(r, c)
  265.     int             c;
  266.     int             r;
  267. {
  268.     r++;
  269.     c++;
  270.  
  271.     outstr("\033[");
  272.     if (r >= 10)
  273.     outchar((char) (r / 10 + '0'));
  274.     outchar((char) (r % 10 + '0'));
  275.     outchar(';');
  276.     if (c >= 10)
  277.     outchar((char) (c / 10 + '0'));
  278.     outchar((char) (c % 10 + '0'));
  279.     outchar('H');
  280. }
  281.  
  282. FILE           *
  283. fopenb(fname, mode)
  284.     char           *fname;
  285.     char           *mode;
  286. {
  287.     FILE           *fopen();
  288.     char            modestr[16];
  289.  
  290.     sprintf(modestr, "%sb", mode);
  291.     return fopen(fname, modestr);
  292. }
  293.  
  294. /*
  295.  * raw() & cooked()
  296.  *
  297.  * These are routines for setting a given stream to raw or cooked mode on the
  298.  * Amiga. This is useful when you are using Lattice C to produce programs
  299.  * that want to read single characters with the "getch()" or "fgetc" call. 
  300.  *
  301.  * Written : 18-Jun-87 By Chuck McManis.
  302.  */
  303.  
  304. /*
  305.  * Function raw() - Convert the specified File Handle to 'raw' mode. This
  306.  * only works on TTY's and essentially keeps DOS from translating keys for
  307.  * you.
  308.  */
  309.  
  310. long
  311. raw(afh)
  312.     struct FileHandle *afh;
  313. {
  314.     struct MsgPort *mp;        /* The File Handle message port */
  315.     long            Arg[1], res;
  316.  
  317.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  318.     Arg[0] = -1L;
  319.     res = send_packet(mp, ACTION_SCREEN_MODE, Arg, 1);
  320.     if (res == 0) {
  321.     errno = ENXIO;
  322.     return (-1);
  323.     }
  324.     return (0);
  325. }
  326.  
  327. /*
  328.  * Function - cooked() this function returns the designate file pointer to
  329.  * it's normal, wait for a <CR> mode. This is exactly like raw() except that
  330.  * it sends a 0 to the console to make it back into a CON: from a RAW: 
  331.  */
  332.  
  333. long
  334. cooked(afh)
  335.     struct FileHandle *afh;
  336. {
  337.     struct MsgPort *mp;        /* The File Handle message port */
  338.     long            Arg[1], res;
  339.  
  340.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  341.     Arg[0] = 0L;
  342.     res = send_packet(mp, ACTION_SCREEN_MODE, Arg, 1);
  343.     if (res == 0) {
  344.     errno = ENXIO;
  345.     return (-1);
  346.     }
  347.     return (0);
  348. }
  349.  
  350. /*
  351.  * Code for this routine came from the following :
  352.  *
  353.  * ConPackets.c -  C. Scheppner, A. Finkel, P. Lindsay  CBM
  354.  *   DOS packet example
  355.  *   Requires 1.2
  356.  *
  357.  * which I found on Fish Disk 56.
  358.  */
  359.  
  360. /* initializes conWindow and conUnit (global vars) */
  361. long
  362. get_ConUnit(afh)
  363.     struct FileHandle *afh;
  364. {
  365.     struct MsgPort *mp;        /* The File Handle message port */
  366.     struct InfoData *id;
  367.     long            Arg[8], res;
  368.  
  369.     if (!IsInteractive((BPTR) afh)) {
  370.     errno = ENOTTY;
  371.     return (-1);
  372.     }
  373.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  374.  
  375.     /* Alloc to insure longword alignment */
  376.     id = (struct InfoData *) AllocMem(sizeof(struct InfoData),
  377.                       MEMF_PUBLIC | MEMF_CLEAR);
  378.     if (!id) {
  379.     errno = ENOMEM;
  380.     return (-1);
  381.     }
  382.     Arg[0] = ((ULONG) id) >> 2;
  383.     res = send_packet(mp, ACTION_DISK_INFO, Arg, 1);
  384.     conWindow = (struct Window *) id->id_VolumeNode;
  385.     conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
  386.     FreeMem(id, sizeof(struct InfoData));
  387.     if (res == 0) {
  388.     errno = ENXIO;
  389.     return (-1);
  390.     }
  391.     return (0);
  392. }
  393.  
  394. /*
  395.  * send_packet() - written by Phil Lindsay, Carolyn Scheppner, and Andy
  396.  * Finkel. This function will send a packet of the given type to the Message
  397.  * Port supplied. 
  398.  */
  399.  
  400. long
  401. send_packet(pid, action, args, nargs)
  402.     struct MsgPort *pid;    /* process indentifier ... (handlers message
  403.                  * port ) */
  404.     long            action,    /* packet type ... (what you want handler to
  405.                  * do )   */
  406.                     args[],    /* a pointer to a argument list */
  407.                     nargs;    /* number of arguments in list  */
  408. {
  409.     struct MsgPort *replyport;
  410.     struct StandardPacket *packet;
  411.  
  412.     long            count, *pargs, res1;
  413.  
  414.     replyport = (struct MsgPort *) CreatePort(NULL, 0);
  415.     if (!replyport)
  416.     return (0);
  417.  
  418.     /* Allocate space for a packet, make it public and clear it */
  419.     packet = (struct StandardPacket *)
  420.     AllocMem((long) sizeof(struct StandardPacket),
  421.          MEMF_PUBLIC | MEMF_CLEAR);
  422.     if (!packet) {
  423.     DeletePort(replyport);
  424.     return (0);
  425.     }
  426.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  427.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  428.     packet->sp_Pkt.dp_Port = replyport;
  429.     packet->sp_Pkt.dp_Type = action;
  430.  
  431.     /* copy the args into the packet */
  432.     pargs = &(packet->sp_Pkt.dp_Arg1);    /* address of first argument */
  433.     for (count = 0; count < nargs; count++)
  434.     pargs[count] = args[count];
  435.  
  436.     PutMsg(pid, packet);    /* send packet */
  437.  
  438.     WaitPort(replyport);
  439.     GetMsg(replyport);
  440.  
  441.     res1 = packet->sp_Pkt.dp_Res1;
  442.  
  443.     FreeMem(packet, (long) sizeof(struct StandardPacket));
  444.     DeletePort(replyport);
  445.  
  446.     return (res1);
  447. }
  448.  
  449. #ifdef WILD_CARDS
  450. /*
  451.  * ExpandWildCard() - this code does wild-card pattern matching using the arp
  452.  *                    routines. This is based on WildDemo2.c (found in arp1.1
  453.  *                    distribution). That code's copyright follows :
  454.  *-------------------------------------------------------------------------
  455.  * WildDemo2.c - Search filesystem for patterns, and separate into directories
  456.  *         and files, sorting each separately using DA lists.
  457.  *
  458.  * -+=SDB=+-
  459.  *
  460.  * Copyright (c) 1987, Scott Ballantyne
  461.  * Use and abuse as you please.
  462.  *-------------------------------------------------------------------------
  463.  */
  464.  
  465. #include <libraries/arpbase.h>
  466. #include <arpfunctions.h>
  467.  
  468. #define ANCHOR_BUF_SIZE (512)
  469. #define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE)
  470.  
  471. struct ArpBase *ArpBase;
  472.  
  473. void
  474. ExpandWildCards(num_pat, pat, num_file, file)
  475.     int             num_pat;
  476.     char          **pat;
  477.     int            *num_file;
  478.     char         ***file;
  479. {
  480.     int             i;
  481.  
  482.     struct DirectoryEntry *FileList = NULL;
  483.     struct DirectoryEntry *de;
  484.     struct AnchorPath *Anchor;
  485.     LONG            Result;
  486.  
  487.     *num_file = 0;
  488.     ***file = NULL;
  489.  
  490.     if (!(ArpBase = (struct ArpBase *) OpenLibrary(ArpName, ArpVersion))) {
  491.     *num_file = num_pat;
  492.     *file = pat;
  493.     return;
  494.     }
  495.     /* Get our AnchorBase */
  496.     Anchor = (struct AnchorPath *) calloc(1, ANCHOR_SIZE);
  497.     if (!Anchor) {
  498. OUT_OF_MEMORY:
  499.     fprintf(stderr, "Out of memory!\n");
  500.     exit(20);
  501.     }
  502.     Anchor->ap_Length = ANCHOR_BUF_SIZE;
  503.  
  504.     if (num_pat > 0) {
  505.     for (i = 0; i < num_pat; i++) {
  506.         Result = FindFirst(pat[i], Anchor);
  507.         while (Result == 0 || Result == ERROR_OBJECT_NOT_FOUND) {
  508.         if (Anchor->ap_Info.fib_DirEntryType < 0) {
  509.             (*num_file)++;
  510.             if (!AddDANode(Anchor->ap_Buf, &FileList, 0L, i)) {
  511.             FreeAnchorChain(Anchor);
  512.             FreeDAList(FileList);
  513.             goto OUT_OF_MEMORY;
  514.             }
  515.         } else if (Result == ERROR_OBJECT_NOT_FOUND) {
  516.             (*num_file)++;
  517.             if (!AddDANode(pat[i], &FileList, 0L, i)) {
  518.             FreeAnchorChain(Anchor);
  519.             FreeDAList(FileList);
  520.             goto OUT_OF_MEMORY;
  521.             }
  522.         }
  523.         Result = FindNext(Anchor);
  524.         }
  525.         if (Result == ERROR_BUFFER_OVERFLOW) {
  526.         fprintf(stderr, "ANCHOR_BUF_SIZE too small.\n");
  527.         FreeAnchorChain(Anchor);
  528.         FreeDAList(FileList);
  529.         exit(20);
  530.         } else if (Result != ERROR_NO_MORE_ENTRIES) {
  531.         fprintf(stderr, "With %s: I/O ERROR #%ld\n", pat[i], Result);
  532.         FreeAnchorChain(Anchor);
  533.         FreeDAList(FileList);
  534.         exit(20);
  535.         }
  536.     }
  537.     FreeAnchorChain(Anchor);
  538.  
  539.     de = FileList;
  540.     if (de) {
  541.         *file = (char **) malloc(sizeof(char *) * (*num_file));
  542.         if (*file == NULL)
  543.         goto OUT_OF_MEMORY;
  544.         for (i = 0; de; de = de->de_Next, i++) {
  545.         (*file)[i] = (char *) malloc(strlen(de->de_Name) + 1);
  546.         if ((*file)[i] == NULL)
  547.             goto OUT_OF_MEMORY;
  548.         strcpy((*file)[i], de->de_Name);
  549.         }
  550.     }
  551.     FreeDAList(FileList);
  552.     }
  553.     CloseLibrary((struct Library *) ArpBase);
  554. }
  555. #endif
  556.