home *** CD-ROM | disk | FTP | other *** search
- /*
- ** termHotkeys.c
- **
- ** Hotkey support routines.
- **
- ** Copyright © 1990-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- */
-
- #include "termGlobal.h"
-
- enum { CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
-
- /* Asynchronous hotkey task. */
-
- STATIC struct Process *CxProcess;
-
- /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
- *
- * A custom version of the amiga.lib supplied code.
- */
-
- STATIC CxObj * __regargs
- CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
- {
- CxObj *Filter;
-
- if(Filter = CxFilter(Code))
- {
- CxObj *Sender;
-
- if(Sender = CxSender(Port,ID))
- {
- CxObj *Translator;
-
- AttachCxObj(Filter,Sender);
-
- if(Translator = CxTranslate(NULL))
- {
- AttachCxObj(Filter,Translator);
-
- if(!CxObjError(Filter))
- return(Filter);
- }
- }
-
- DeleteCxObjAll(Filter);
- }
-
- return(NULL);
- }
-
- /* CreateBroker(struct MsgPort *CxPort):
- *
- * Set up a CxObj commodity broker.
- */
-
- STATIC CxObj * __regargs
- CreateBroker(struct MsgPort *CxPort)
- {
- CxObj *Broker;
-
- /* Set the commodity priority. */
-
- NewTermBroker . nb_Pri = Hotkeys . CommodityPriority;
-
- /* Create the broker. */
-
- if(Broker = CxBroker(&NewTermBroker,NULL))
- {
- /* Add the hotkeys. */
-
- AttachCxObj(Broker,CustomHotKey(Hotkeys . termScreenToFront, CxPort,CX_TERMSCREENTOFRONT));
- AttachCxObj(Broker,CustomHotKey(Hotkeys . BufferScreenToFront, CxPort,CX_BUFFERSCREENTOFRONT));
- AttachCxObj(Broker,CustomHotKey(Hotkeys . SkipDialEntry, CxPort,CX_SKIPDIALENTRY));
- AttachCxObj(Broker,CustomHotKey(Hotkeys . AbortARexx, CxPort,CX_ABORTAREXX));
-
- /* Did an error show up? */
-
- if(!CxObjError(Broker))
- {
- /* Broker has been added, now activate it. */
-
- ActivateCxObj(Broker,Hotkeys . HotkeysEnabled);
-
- return(Broker);
- }
-
- DeleteCxObjAll(Broker);
- }
-
- return(NULL);
- }
-
- /* TermCxServer():
- *
- * Asynchronous hotkey server.
- */
-
- STATIC VOID __saveds
- TermCxServer(VOID)
- {
- CxObj *Broker;
- struct MsgPort *CxPort;
- CxMsg *Message;
-
- /* Create a reply port. */
-
- if(CxPort = CreateMsgPort())
- {
- /* Add the port to the public list. */
-
- CxPort -> mp_Node . ln_Name = NewTermBroker . nb_Name;
-
- AddPort(CxPort);
-
- /* Install the port. */
-
- NewTermBroker . nb_Port = CxPort;
-
- /* Create the broker. */
-
- if(Broker = CreateBroker(CxPort))
- {
- ULONG SignalSet;
- BYTE Terminated = FALSE;
-
- /* Signal father task that we're done. */
-
- Signal(ThisProcess,SIG_HANDSHAKE);
-
- /* Loop and loop... */
-
- while(!Terminated)
- {
- /* Wait for some signal. */
-
- SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
-
- /* ^C aborts. */
-
- if(SignalSet & SIG_KILL)
- Terminated = TRUE;
-
- /* ^D removes the broker and
- * creates a new one.
- */
-
- if(SignalSet & SIG_RESET)
- {
- DeleteCxObjAll(Broker);
-
- Broker = CreateBroker(CxPort);
- }
-
- /* A commodity message. */
-
- if(SignalSet & PORTMASK(CxPort))
- {
- ULONG MessageType,MessageID;
-
- /* Remove all messages. */
-
- while(Message = (CxMsg *)GetMsg(CxPort))
- {
- /* Extract type and ID. */
-
- MessageType = CxMsgID(Message);
- MessageID = CxMsgType(Message);
-
- ReplyMsg((struct Message *)Message);
-
- /* Take a look at the type... */
-
- switch(MessageID)
- {
- /* A hotkey was pressed. */
-
- case CXM_IEVENT:
-
- switch(MessageType)
- {
- case CX_TERMSCREENTOFRONT:
-
- Forbid();
-
- if(Window)
- BumpWindow(TopWindow);
- else
- Signal(ThisProcess,SIGBREAKF_CTRL_F);
-
- Permit();
-
- break;
-
- case CX_BUFFERSCREENTOFRONT:
-
- LaunchBuffer();
- break;
-
- case CX_SKIPDIALENTRY:
-
- Signal(ThisProcess,SIG_SKIP);
- break;
-
- case CX_ABORTAREXX:
-
- if(InRexx)
- Signal(ThisProcess,SIG_BREAK);
-
- break;
- }
-
- break;
-
- /* An internal commodity command. */
-
- case CXM_COMMAND:
-
- switch(MessageType)
- {
- case CXCMD_DISABLE:
-
- ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = FALSE);
- break;
-
- case CXCMD_ENABLE:
-
- ActivateCxObj(Broker,Hotkeys . HotkeysEnabled = TRUE);
- break;
- }
-
- break;
- }
- }
- }
- }
-
- /* Remove the broker. */
-
- DeleteCxObjAll(Broker);
- }
-
- /* Remove the port from the public list. */
-
- RemPort(CxPort);
-
- /* Remove all pendig messages. */
-
- while(Message = (CxMsg *)GetMsg(CxPort))
- ReplyMsg((struct Message *)Message);
-
- /* Delete the reply port. */
-
- DeleteMsgPort(CxPort);
- }
-
- Forbid();
-
- /* Clear the task ID. */
-
- CxProcess = NULL;
-
- /* Signal father process that we're done. */
-
- Signal(ThisProcess,SIG_HANDSHAKE);
- }
-
- /* ShutdownCx():
- *
- * Remove the hotkey task.
- */
-
- VOID
- ShutdownCx()
- {
- if(CxProcess)
- {
- Forbid();
-
- Signal(CxProcess,SIG_KILL);
-
- ClrSignal(SIG_HANDSHAKE);
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
- }
- }
-
- /* SetupCx():
- *
- * Create the hotkey task.
- */
-
- BYTE
- SetupCx()
- {
- /* If the task is already running, tell it to
- * update the hotkey settings.
- */
-
- if(CxProcess)
- {
- Signal(CxProcess,SIG_RESET);
-
- return(TRUE);
- }
- else
- {
- Forbid();
-
- if(CxProcess = (struct Process *)CreateNewProcTags(
- NP_Entry, TermCxServer,
- NP_Name, "term Hotkey Process",
- NP_Priority, 0,
- NP_StackSize, 8192,
- NP_WindowPtr, -1,
- TAG_END))
- {
- ClrSignal(SIG_HANDSHAKE);
-
- Wait(SIG_HANDSHAKE);
- }
-
- Permit();
-
- if(CxProcess)
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
- *
- * Load the hotkey settings from a file.
- */
-
- BYTE __regargs
- LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
- {
- struct IFFHandle *Handle;
- BYTE Success = FALSE;
- struct StoredProperty *Prop;
- struct TermInfo *TermInfo;
- LONG Error;
-
- if(Handle = AllocIFF())
- {
- if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
- {
- InitIFFasDOS(Handle);
-
- if(!(Error = OpenIFF(Handle,IFFF_READ)))
- {
- /* Collect version number ID if
- * available.
- */
-
- if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
- {
- /* The following line tells iffparse to stop at the
- * very beginning of a `Type' chunk contained in a
- * `TERM' FORM chunk.
- */
-
- if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
- {
- /* Parse the file... */
-
- if(!ParseIFF(Handle,IFFPARSE_SCAN))
- {
- /* Did we get a version ID? */
-
- if(Prop = FindProp(Handle,ID_TERM,ID_VERS))
- {
- TermInfo = (struct TermInfo *)Prop -> sp_Data;
-
- if((TermInfo -> Version < CONFIG_FILE_VERSION) || (TermInfo -> Version == CONFIG_FILE_VERSION && TermInfo -> Revision < CONFIG_FILE_REVISION))
- {
- if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) == sizeof(struct HotkeysOld))
- {
- strcpy(Keys -> AbortARexx,"lshift rshift escape");
-
- Success = TRUE;
- }
- else
- Error = IoErr();
- }
- else
- {
- if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) == sizeof(struct Hotkeys))
- Success = TRUE;
- else
- Error = IoErr();
- }
- }
- }
- }
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle -> iff_Stream);
- }
- else
- Error = IoErr();
-
- FreeIFF(Handle);
- }
- else
- Error = ERR_NO_MEM;
-
- if(Error)
- SetIoErr(Error);
-
- return(Success);
- }
-