home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / e / elv17src.zip / AMITTY.C < prev    next >
C/C++ Source or Header  |  1992-12-30  |  8KB  |  335 lines

  1. /* amitty.c */
  2.  
  3. /*-
  4.  *    Mike Rieser                 Dale Rahn
  5.  *    2410 Happy Hollow Rd. Apt D-10        540 Vine St.
  6.  *    West Lafayette, IN 47906         West Lafayette, IN 47906
  7.  *    riesermc@mentor.cc.purdue.edu        rahn@sage.cc.purdue.edu
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <exec/memory.h>
  14. #include <devices/conunit.h>
  15. #include <dos/dos.h>
  16. #include <clib/macros.h>
  17. #include <clib/exec_protos.h>
  18. #include <clib/dos_protos.h>
  19.  
  20. #if AZTEC_C
  21. #include <pragmas/exec_lib.h>
  22. #include <pragmas/dos_lib.h>
  23. #else
  24. #include <pragmas/exec.h>
  25. #include <pragmas/dos.h>
  26. #endif
  27.  
  28. #include "config.h"
  29.  
  30. /*-
  31.  * Defines for amigatty.
  32.  *
  33.  * Note: Amiga <CSI> Control Sequence Introducer is either:
  34.  * 0x9b or <ESC>[ == 0x1b 0x5b.
  35.  *
  36.  * The Amiga always responds with 0x9b.
  37.  *
  38.  * For you octal fans: 0x9b == \233, 0x1b == \033.
  39.  */
  40. #define CSI        '\233'
  41. #define TIME_FACTOR    (100000)/* convert 1/10 sec to microsecs */
  42.  
  43. /* Amiga Console Control Sequences */
  44. #define ENABLE_SCROLL    ((UBYTE *) "\233>1h")    /* Amiga default */
  45. #define DISABLE_SCROLL    ((UBYTE *) "\233>1l")
  46. #define AUTOWRAP_ON    ((UBYTE *) "\233?7h")    /* Amiga default */
  47. #define AUTOWRAP_OFF    ((UBYTE *) "\233?7l")
  48. #define CURSOR_ON    ((UBYTE *) "\233 p")    /* Amiga default */
  49. #define CURSOR_OFF    ((UBYTE *) "\2330 p")
  50.  
  51. #define RAW_EVENTS_ON    ((UBYTE *) "\23312{")    /* Set Window Resize Reports */
  52. #define RAW_EVENTS_OFF    ((UBYTE *) "\23312}")    /* Reset Window Resize Reports */
  53.  
  54. /* take out for compiling with elvis */
  55.  
  56. #ifndef ctrl
  57. #define    ctrl(ch)        ((ch)&037)
  58. #endif
  59.  
  60. /* Variables */
  61. static BPTR  fh = 0, inputFH, outputFH, oldinputFH, oldoutputFH;
  62. static UBYTE title[]= "RAW:0/0/999/999/Amiga Elvis 1.5/SIMPLE";
  63. static int   amigaterm = 0;
  64.  
  65. /* Function prototypes for amitty.c */
  66. void         amiopenwin(char *termtype);
  67. void         amiclosewin(void);
  68. void         ttysetup(void);
  69. void         ttyshutdown(void);
  70. int          ttywrite(char *buf, int len);
  71. int          ttyread(char *buf, int len, int time);
  72. int          CheckforSpecial(char *buf, long len);
  73. LONG         setRawCon(LONG toggle);
  74. LONG         sendpkt(struct MsgPort *pid, LONG action, LONG args[], LONG nargs);
  75.  
  76. /*
  77.  * amiopenwin - opens a window if we don't already have one.
  78.  */
  79. void
  80. amiopenwin(char *termtype)
  81. {
  82.     if (!IsInteractive(Input()))
  83.     {
  84.     /* open our own window in RAW mode */
  85.     if (isOldDOS() || (BPTR) 0 == (fh = Open(title, MODE_READWRITE)))
  86.     {
  87.         PutStr((UBYTE *) "Couldn't open RAW: window");
  88.         clean_exit(2);
  89.     } else
  90.     {
  91.         oldinputFH = SelectInput(fh);
  92.         oldoutputFH = SelectOutput(fh);
  93.     }
  94.     }
  95.     inputFH = Input();
  96.     outputFH = Output();
  97.  
  98.     if (!strcmp(termtype, TERMTYPE))
  99.     {
  100.     amigaterm = 1;
  101.     Write(outputFH, AUTOWRAP_OFF, sizeof(AUTOWRAP_OFF));
  102.     }
  103.     return;
  104. }
  105.  
  106.  
  107. /*
  108.  * amiclosewin - closes a window if we opened one.
  109.  */
  110. void
  111. amiclosewin()
  112. {
  113.     if (amigaterm)
  114.     {
  115.     Write(outputFH, AUTOWRAP_ON, sizeof(AUTOWRAP_ON));    /* Amiga default */
  116.     }
  117.     if (fh)
  118.     {                    /* Close down the window */
  119.     SelectInput(oldinputFH);
  120.     SelectOutput(oldoutputFH);
  121.     Close(fh);
  122.     }
  123.     return;
  124. }
  125.  
  126.  
  127. /*
  128.  * ttysetup - console initalization routine for Amiga Computers.
  129.  * 
  130.  * Sets raw mode and enables resize notifications.
  131.  */
  132. void
  133. ttysetup()
  134. {
  135.     if (isOldDOS())
  136.     {
  137.     setRawCon(DOSTRUE);
  138.     } else
  139.     {
  140.     SetMode(inputFH, 1);        /* Enter RAW mode */
  141.     }
  142.  
  143.     if (amigaterm)
  144.     {
  145.     Write(outputFH, RAW_EVENTS_ON, sizeof(RAW_EVENTS_ON));
  146.     }
  147.     return;
  148. }
  149.  
  150.  
  151. /*
  152.  * ttyshutdown - console shutdown routine for Amiga Computers.
  153.  * 
  154.  * Resets raw mode and disables resize notifications.
  155.  */
  156. void
  157. ttyshutdown()
  158. {
  159.     if (amigaterm)
  160.     {
  161.     Write(outputFH, RAW_EVENTS_OFF, sizeof(RAW_EVENTS_OFF));
  162.     }
  163.     if (isOldDOS())
  164.     {
  165.     setRawCon(DOSFALSE);
  166.     } else
  167.     {
  168.     SetMode(inputFH, 0);        /* Leave RAW mode */
  169.     }
  170.  
  171.     return;
  172. }
  173.  
  174.  
  175. /*
  176.  * ttywrite - amiga version of ttywrite.
  177.  * 
  178.  * This version makes small writes to the console as suggested in the RKM.
  179.  * Also turns off the cursor to speed output to the screen.
  180.  */
  181. int
  182. ttywrite(buf, len)
  183.     char        *buf;
  184.     int          len;
  185. {
  186.     int            cursor_off;
  187.     register int    bytes;
  188.     register UBYTE *pc = (UBYTE *) buf;
  189.  
  190.     /* See if turning off the cursor is worthwhile */
  191.     if (cursor_off = amigaterm && len > 2 * sizeof(CURSOR_OFF))
  192.     {
  193.     Write(outputFH, CURSOR_OFF, sizeof(CURSOR_OFF));    /* Turn Cursor OFF */
  194.     }
  195.  
  196.     /* The console.device doesn't like large writes */
  197.     for (bytes = 0; len; pc += bytes, len -= bytes)
  198.     {
  199.     bytes = Write(outputFH, pc, MIN((LONG) len, 256L));
  200.     }
  201.  
  202.     if (cursor_off)
  203.     {
  204.     Write(outputFH, CURSOR_ON, sizeof(CURSOR_ON));    /* Turn Cursor ON */
  205.     }
  206.     return pc - buf;
  207. }
  208.  
  209.  
  210. /*
  211.  * ttyread - amiga version of ttyread.
  212.  */
  213. int
  214. ttyread(buf, len, time)
  215.     char        *buf;        /* where to store the gotten characters */
  216.     int          len;        /* maximum number of characters to read */
  217.     int          time;        /* maximum time in 1/10 sec for reading */
  218. {
  219.     LONG         bytes = 0;    /* number of bytes actually read */
  220.  
  221.     if (!time || WaitForChar(inputFH, time * TIME_FACTOR))
  222.     {                    /* Read() if time == 0 or chars waiting */
  223.     bytes = Read(inputFH, (UBYTE *) buf, (LONG) len);
  224.     bytes = CheckforSpecial(buf, bytes);
  225.     }
  226.     return bytes;            /* the number of bytes read in buf */
  227. }
  228.  
  229.  
  230. /*
  231.  * CheckforSpecial - crude parser for raw console events.
  232.  */
  233. int
  234. CheckforSpecial(buf, len)
  235.     char        *buf;
  236.     long         len;
  237. {
  238.     int          isnewsize = 0;
  239.     char        *pb, *peor, *pend;
  240.  
  241.     pb = buf;
  242.     pend = &buf[len];
  243.     do
  244.     {
  245.     if (CSI != *pb)
  246.         continue;
  247.  
  248.     if (WaitForChar(inputFH, 1))
  249.     {
  250.         pend += Read(inputFH, pend, 72);
  251.     }
  252.     if (peor = strchr((char *) pb, '|'))    /* Window Resize Event */
  253.     {                /* bug == <CSI> seq <CSI> event '|' */
  254.         *pb = ctrl('L');        /* force redraw */
  255.         isnewsize = 1;
  256.         memmove(pb + 1, peor + 1, pend - peor);
  257.         pend -= peor - pb;
  258.     }
  259.     }
  260.     while (*pb++);
  261.  
  262.     if (isnewsize)
  263.     getsize(0);
  264.  
  265.     return pend - buf;
  266. }
  267.  
  268.  
  269. /* INDENT OFF */
  270. /* sendpkt code - A. Finkel, P. Lindsay, C. Scheppner  CBM */
  271.  
  272. LONG setRawCon(toggle)
  273. LONG toggle;     /* DOSTRUE (-1L)  or  DOSFALSE (0L) */
  274.    {
  275.    struct MsgPort *conid;
  276.    struct Process *me;
  277.    LONG myargs[8] ,nargs, res1;
  278.  
  279.    me = (struct Process *) FindTask(NULL);
  280.    conid = (struct MsgPort *) me->pr_ConsoleTask;
  281.  
  282.    myargs[0]= toggle;
  283.    nargs = 1;
  284.    res1 = (LONG)sendpkt(conid,ACTION_SCREEN_MODE,myargs,nargs);
  285.    return(res1);
  286.    }
  287.  
  288.  
  289.  
  290. LONG sendpkt(pid,action,args,nargs)
  291. struct MsgPort *pid;  /* process indentifier ... (handlers message port ) */
  292. LONG action,          /* packet type ... (what you want handler to do )   */
  293.      args[],          /* a pointer to a argument list */
  294.      nargs;           /* number of arguments in list  */
  295.    {
  296.    struct MsgPort        *replyport;
  297.    struct StandardPacket *packet;
  298.  
  299.    LONG  count, *pargs, res1;
  300.  
  301.    replyport = (struct MsgPort *) CreatePort(NULL,0);
  302.    if(!replyport) return((LONG)NULL);
  303.  
  304.    packet = (struct StandardPacket *) 
  305.       AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
  306.    if(!packet) 
  307.       {
  308.       DeletePort(replyport);
  309.       return((LONG)NULL);
  310.       }
  311.  
  312.    packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
  313.    packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
  314.    packet->sp_Pkt.dp_Port         = replyport;
  315.    packet->sp_Pkt.dp_Type         = action;
  316.  
  317.    /* copy the args into the packet */
  318.    pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
  319.    for(count=0;count < nargs;count++) 
  320.       pargs[count]=args[count];
  321.  
  322.    PutMsg(pid,(struct Message *)packet); /* send packet */
  323.  
  324.    WaitPort(replyport);
  325.    GetMsg(replyport); 
  326.  
  327.    res1 = packet->sp_Pkt.dp_Res1;
  328.  
  329.    FreeMem(packet,(long)sizeof(struct StandardPacket));
  330.    DeletePort(replyport); 
  331.  
  332.    return(res1);
  333.    }
  334.  
  335.