home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term33so.lha / termHotkeys.c < prev    next >
C/C++ Source or Header  |  1993-04-30  |  7KB  |  401 lines

  1. /*
  2. **    termHotkeys.c
  3. **
  4. **    Hotkey support routines.
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. enum    {    CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
  13.  
  14.     /* Asynchronous hotkey task. */
  15.  
  16. STATIC struct Process *CxProcess;
  17.  
  18.     /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
  19.      *
  20.      *    A custom version of the amiga.lib supplied code.
  21.      */
  22.  
  23. STATIC CxObj * __regargs
  24. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  25. {
  26.     CxObj *Filter;
  27.  
  28.     if(Filter = CxFilter(Code))
  29.     {
  30.         CxObj *Sender;
  31.  
  32.         if(Sender = CxSender(Port,ID))
  33.         {
  34.             CxObj *Translator;
  35.  
  36.             AttachCxObj(Filter,Sender);
  37.  
  38.             if(Translator = CxTranslate(NULL))
  39.             {
  40.                 AttachCxObj(Filter,Translator);
  41.  
  42.                 if(!CxObjError(Filter))
  43.                     return(Filter);
  44.             }
  45.         }
  46.  
  47.         DeleteCxObjAll(Filter);
  48.     }
  49.  
  50.     return(NULL);
  51. }
  52.  
  53.     /* CreateBroker(struct MsgPort *CxPort):
  54.      *
  55.      *    Set up a CxObj commodity broker.
  56.      */
  57.  
  58. STATIC CxObj *
  59. CreateBroker(struct MsgPort *CxPort)
  60. {
  61.     CxObj *Broker;
  62.  
  63.         /* Set the commodity priority. */
  64.  
  65.     NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;
  66.  
  67.         /* Create the broker. */
  68.  
  69.     if(Broker = CxBroker(&NewTermBroker,NULL))
  70.     {
  71.             /* Add the hotkeys. */
  72.  
  73.         AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront,    CxPort,CX_TERMSCREENTOFRONT));
  74.         AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront,    CxPort,CX_BUFFERSCREENTOFRONT));
  75.         AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry,    CxPort,CX_SKIPDIALENTRY));
  76.         AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx,        CxPort,CX_ABORTAREXX));
  77.  
  78.             /* Did an error show up? */
  79.  
  80.         if(!CxObjError(Broker))
  81.         {
  82.                 /* Broker has been added, now activate it. */
  83.  
  84.             ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
  85.  
  86.             return(Broker);
  87.         }
  88.  
  89.         DeleteCxObjAll(Broker);
  90.     }
  91.  
  92.     return(NULL);
  93. }
  94.  
  95.     /* TermCxServer():
  96.      *
  97.      *    Asynchronous hotkey server.
  98.      */
  99.  
  100. STATIC VOID __saveds
  101. TermCxServer(VOID)
  102. {
  103.     CxObj        *Broker;
  104.     struct MsgPort    *CxPort;
  105.     CxMsg        *Message;
  106.  
  107.         /* Create a reply port. */
  108.  
  109.     if(CxPort = CreateMsgPort())
  110.     {
  111.             /* Add the port to the public list. */
  112.  
  113.         CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;
  114.  
  115.         AddPort(CxPort);
  116.  
  117.             /* Install the port. */
  118.  
  119.         NewTermBroker . nb_Port    = CxPort;
  120.  
  121.             /* Create the broker. */
  122.  
  123.         if(Broker = CreateBroker(CxPort))
  124.         {
  125.             ULONG    SignalSet;
  126.             BYTE    Terminated = FALSE;
  127.  
  128.                 /* Signal father task that we're done. */
  129.  
  130.             Signal(ThisProcess,SIG_HANDSHAKE);
  131.  
  132.                 /* Loop and loop... */
  133.  
  134.             while(!Terminated)
  135.             {
  136.                     /* Wait for some signal. */
  137.  
  138.                 SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
  139.  
  140.                     /* ^C aborts. */
  141.  
  142.                 if(SignalSet & SIG_KILL)
  143.                     Terminated = TRUE;
  144.  
  145.                     /* ^D removes the broker and
  146.                      * creates a new one.
  147.                      */
  148.  
  149.                 if(SignalSet & SIG_RESET)
  150.                 {
  151.                     DeleteCxObjAll(Broker);
  152.  
  153.                     Broker = CreateBroker(CxPort);
  154.                 }
  155.  
  156.                     /* A commodity message. */
  157.  
  158.                 if(SignalSet & PORTMASK(CxPort))
  159.                 {
  160.                     ULONG MessageType,MessageID;
  161.  
  162.                         /* Remove all messages. */
  163.  
  164.                     while(Message = (CxMsg *)GetMsg(CxPort))
  165.                     {
  166.                             /* Extract type and ID. */
  167.  
  168.                         MessageType    = CxMsgID(Message);
  169.                         MessageID    = CxMsgType(Message);
  170.  
  171.                         ReplyMsg((struct Message *)Message);
  172.  
  173.                             /* Take a look at the type... */
  174.  
  175.                         switch(MessageID)
  176.                         {
  177.                                 /* A hotkey was pressed. */
  178.  
  179.                             case CXM_IEVENT:
  180.  
  181.                                 switch(MessageType)
  182.                                 {
  183.                                     case CX_TERMSCREENTOFRONT:
  184.  
  185.                                         BumpWindow(TopWindow);
  186.                                         break;
  187.  
  188.                                     case CX_BUFFERSCREENTOFRONT:
  189.  
  190.                                         LaunchBuffer();
  191.                                         break;
  192.  
  193.                                     case CX_SKIPDIALENTRY:
  194.  
  195.                                         Signal(ThisProcess,SIG_SKIP);
  196.                                         break;
  197.  
  198.                                     case CX_ABORTAREXX:
  199.  
  200.                                         if(InRexx)
  201.                                             Signal(ThisProcess,SIG_BREAK);
  202.  
  203.                                         break;
  204.                                 }
  205.  
  206.                                 break;
  207.  
  208.                                 /* An internal commodity command. */
  209.  
  210.                             case CXM_COMMAND:
  211.  
  212.                                 switch(MessageType)
  213.                                 {
  214.                                     case CXCMD_DISABLE:
  215.  
  216.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
  217.                                         break;
  218.  
  219.                                     case CXCMD_ENABLE:
  220.  
  221.                                         ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
  222.                                         break;
  223.                                 }
  224.  
  225.                                 break;
  226.                         }
  227.                     }
  228.                 }
  229.             }
  230.  
  231.                 /* Remove the broker. */
  232.  
  233.             DeleteCxObjAll(Broker);
  234.         }
  235.  
  236.             /* Remove the port from the public list. */
  237.  
  238.         RemPort(CxPort);
  239.  
  240.             /* Remove all pendig messages. */
  241.  
  242.         while(Message = (CxMsg *)GetMsg(CxPort))
  243.             ReplyMsg((struct Message *)Message);
  244.  
  245.             /* Delete the reply port. */
  246.  
  247.         DeleteMsgPort(CxPort);
  248.     }
  249.  
  250.     Forbid();
  251.  
  252.         /* Clear the task ID. */
  253.  
  254.     CxProcess = NULL;
  255.  
  256.         /* Signal father process that we're done. */
  257.  
  258.     Signal(ThisProcess,SIG_HANDSHAKE);
  259. }
  260.  
  261.     /* ShutdownCx():
  262.      *
  263.      *    Remove the hotkey task.
  264.      */
  265.  
  266. VOID
  267. ShutdownCx()
  268. {
  269.     if(CxProcess)
  270.     {
  271.         Forbid();
  272.  
  273.         Signal(CxProcess,SIG_KILL);
  274.  
  275.         ClrSignal(SIG_HANDSHAKE);
  276.  
  277.         Wait(SIG_HANDSHAKE);
  278.  
  279.         Permit();
  280.     }
  281. }
  282.  
  283.     /* SetupCx():
  284.      *
  285.      *    Create the hotkey task.
  286.      */
  287.  
  288. BYTE
  289. SetupCx()
  290. {
  291.         /* If the task is already running, tell it to
  292.          * update the hotkey settings.
  293.          */
  294.  
  295.     if(CxProcess)
  296.     {
  297.         Signal(CxProcess,SIG_RESET);
  298.  
  299.         return(TRUE);
  300.     }
  301.     else
  302.     {
  303.         Forbid();
  304.  
  305.         if(CxProcess = (struct Process *)CreateNewProcTags(
  306.             NP_Entry,    TermCxServer,
  307.             NP_Name,    "term hotkey process",
  308.             NP_Priority,    0,
  309.             NP_StackSize,    8192,
  310.             NP_WindowPtr,    -1,
  311.         TAG_END))
  312.         {
  313.             ClrSignal(SIG_HANDSHAKE);
  314.  
  315.             Wait(SIG_HANDSHAKE);
  316.         }
  317.  
  318.         Permit();
  319.  
  320.         if(CxProcess)
  321.             return(TRUE);
  322.     }
  323.  
  324.     return(FALSE);
  325. }
  326.  
  327.     /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
  328.      *
  329.      *    Load the hotkey settings from a file.
  330.      */
  331.  
  332. BYTE
  333. LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
  334. {
  335.     struct IFFHandle    *Handle;
  336.     BYTE             Success = FALSE;
  337.     struct StoredProperty    *Prop;
  338.     struct TermInfo        *TermInfo;
  339.  
  340.     if(Handle = AllocIFF())
  341.     {
  342.         if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
  343.         {
  344.             InitIFFasDOS(Handle);
  345.  
  346.             if(!OpenIFF(Handle,IFFF_READ))
  347.             {
  348.                 /* Collect version number ID if
  349.                  * available.
  350.                  */
  351.  
  352.                 if(!PropChunks(Handle,VersionProps,1))
  353.                 {
  354.                     /* The following line tells iffparse to stop at the
  355.                      * very beginning of a `Type' chunk contained in a
  356.                      * `TERM' FORM chunk.
  357.                      */
  358.  
  359.                     if(!StopChunk(Handle,ID_TERM,ID_HOTK))
  360.                     {
  361.                         /* Parse the file... */
  362.  
  363.                         if(!ParseIFF(Handle,IFFPARSE_SCAN))
  364.                         {
  365.                             /* Did we get a version ID? */
  366.  
  367.                             if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
  368.                             {
  369.                                 TermInfo = (struct TermInfo *)Prop -> sp_Data;
  370.  
  371.                                 if((TermInfo -> Version < TermVersion) || (TermInfo -> Version == TermVersion && TermInfo -> Revision < TermRevision))
  372.                                 {
  373.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
  374.                                     {
  375.                                         strcpy(Keys -> AbortARexx,"lshift rshift escape");
  376.  
  377.                                         Success = TRUE;
  378.                                     }
  379.                                 }
  380.                                 else
  381.                                 {
  382.                                     if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
  383.                                         Success = TRUE;
  384.                                 }
  385.                             }
  386.                         }
  387.                     }
  388.                 }
  389.  
  390.                 CloseIFF(Handle);
  391.             }
  392.  
  393.             Close(Handle -> iff_Stream);
  394.         }
  395.  
  396.         FreeIFF(Handle);
  397.     }
  398.  
  399.     return(Success);
  400. }
  401.