home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- GoldED API client. ©1995 Dietmar Eilert. All Rights Reserved.
-
- Dice:
-
- dcc main.c cx.a sprintf.a -// -mRR -proto -2.0 -l tmsr.lib -l reqtoolssr.lib -o ram:dock
-
- Note: Compiling this code requires ToolManger includes & ToolManager linker
- libraries. ToolManager is ©1990-1995 Stefan Becker.
-
- ------------------------------------------------------------------------------
- */
-
- /// "includes"
-
- #define Prototype extern
-
- #include <exec/exec.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos/dos.h>
- #include <dos/rdargs.h>
- #include <dos/dostags.h>
- #include <intuition/intuition.h>
- #include <workbench/startup.h>
- #include <rexx/errors.h>
- #include <rexx/rxslib.h>
- #include <rexx/storage.h>
- #include <libraries/reqtools.h>
- #include <utility/tagitem.h>
- #include <clib/toolmanager_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/utility_protos.h>
- #include <clib/rexxsyslib_protos.h>
- #include <clib/reqtools_protos.h>
- #include <clib/commodities_protos.h>
- #include "golded:api/include/golded.h"
-
- #define SIG_KILL SIGBREAKF_CTRL_C
- #define SIG_HANDSHAKE SIGF_SINGLE
- #define TMET_Hotkey 10
- #define TMET_GoldED 11
-
- ///
- /// "definitions"
-
- // ToolManager objects are a combination of action/image/sound:
-
- struct Tool {
-
- struct Node Node;
- APTR Exec;
- APTR Icon;
- APTR Sound;
- };
-
- // parser array: commands, templates, handlers
-
- struct Parser {
-
- UBYTE *Command;
- APTR Server;
- UBYTE *Template;
- };
-
- // linked list of all PROG objects (CLI/AREXX/HOTKEY/GOLDED) found in the preset file:
-
- struct Event {
-
- struct Node Node;
- UWORD Type;
- UBYTE *Command;
- UBYTE *Dir;
- UBYTE *Key;
- UBYTE *Output;
- BOOL Hotkey;
- BOOL Args;
- BOOL Activate;
- };
-
- // linked list of all docks found in the preset file:
-
- struct Dock {
-
- struct Node Node;
- struct TagItem *Tags;
- BOOL Visible;
- UWORD Elements;
- };
-
- ///
- /// "prototypes"
-
- Prototype void StopServer(struct Task **);
- Prototype void InsertEvent(UBYTE *);
- Prototype void PutIEvents(struct InputEvent *);
- Prototype int main(int, char **);
- Prototype UBYTE *xsprintf(UBYTE *, UBYTE *);
- Prototype void AddProg (ULONG *, struct List *);
- Prototype void AddIcon (ULONG *, struct List *);
- Prototype void AddSound(ULONG *, struct List *);
- Prototype void AddTool (ULONG *, struct List *);
- Prototype void AddDock (ULONG *, struct List *);
- Prototype void HandleAPI(struct Task **);
- Prototype void ReadConfig(UBYTE *);
- Prototype void CloseRexxPort(struct MsgPort *, UWORD, BOOL);
- Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *, BOOL, UWORD *, UBYTE *);
- Prototype struct Node *SearchName(struct List *, UBYTE *);
- Prototype void FreeRexxCommand(struct RexxMsg *);
- Prototype UWORD CountList(struct List *);
- Prototype void Puts(UBYTE *);
- Prototype UBYTE *myprintf(UBYTE *, UBYTE *, ...);
- Prototype void ARexxServer(void);
- Prototype void ShowDocks(struct Dock *);
- Prototype void HideDocks(void);
- Prototype void DoExecute(UBYTE *, BOOL, UBYTE *, UBYTE *, UWORD, WORD);
- Prototype UBYTE *stristr(UBYTE *, UBYTE *);
- Prototype void Replace(UBYTE *, UBYTE *, UBYTE *);
- Prototype void CommandDispatch(struct RDArgs *, struct APIMessage *);
- Prototype LONG ModifyDock(ULONG *, struct APIMessage *);
-
- Prototype __stkargs struct InputEvent *MyInvertString(UBYTE *, APTR);
- Prototype __stkargs void MyFreeIEvents(struct InputEvent *);
-
- ///
- /// "globals"
-
- UBYTE Version = "$VER: NextStep 1.6 (" __COMMODORE_DATE__ ")";
-
- UWORD ARexxReplies;
- struct Library *ReqToolsBase;
- struct Library *CxBase;
- struct Task *MainTask;
- struct List EventList, DockList;
- void *TMHandle;
- UBYTE Screen[255], Host[255];
-
- // parser definitions used to scan preset file
-
- struct Parser ConfigParser[] = {
-
- "PROG", (APTR)AddProg, "NAME/A,COMMAND/K/A,AREXX/S,CLI/S,HOTKEY/S,WB/S,DIR/K,OUTPUT/K,ARGS/S,KEY/K,GOLDED/S,ACTIVATE/S",
- "SOUND", (APTR)AddSound, "NAME/A,COMMAND/K/A,PORT/K/A",
- "ICON", (APTR)AddIcon, "NAME/A,FILE/A",
- "DTOOL", (APTR)AddTool, "PROG/K/A,ICON/K,SOUND/K",
- "DOCK", (APTR)AddDock, "NAME/A,X/N,Y/N,HORIZONTAL/S,COLUMNS/N,HOTKEY/K,TITLE/K,CENTER/S,POPUP/S,HIDDEN/S,TEXT/S,STICKY/S,FRONTMOST/S,PATTERN/S,VERTICAL/S,LINEAR/S",
- NULL
- };
-
- // parser definitions used to process commands sent by GoldED (API interface):
-
- struct Parser CommandParser[] = {
-
- "DOCK", (APTR)ModifyDock, "NAME/A,X/N,Y/N,SHOW/S,HIDE/S,TOGGLE/S,HORIZONTAL/S,VERTICAL/S,ROTATE/S,NEWLOOK/S,LINEAR/S",
- NULL
- };
-
- ///
- /// "main"
-
- /* ----------------------------------- main ------------------------------------
-
- Start ToolManager, start background server (server performs all dock-related
- actions, e.g. the server will run commands), read config file, call API loop.
-
- */
-
- int
- main(int argc, char **argv)
- {
- if (FindPort("DOCKSERVER"))
-
- Puts("NextStep: Can't run dock twice");
-
- else if (CxBase = OpenLibrary("commodities.library", 37)) {
-
- struct RDArgs *rdArgs;
-
- ULONG args[] = { 0, 0 };
-
- MainTask = FindTask(0);
-
- if (rdArgs = ReadArgs("CONFIG/K,HOST/K/A", args, NULL)) {
-
- UWORD try;
-
- for (try = 20; !(TMHandle = AllocTMHandle()) && try; try--)
- Delay(10);
-
- if (TMHandle) {
-
- struct Task *server;
-
- if (server = (struct Task *)CreateNewProcTags(NP_Entry, ARexxServer, NP_Name, "DOCKSERVER", NP_Priority, 1, TAG_DONE)) {
-
- NewList(&DockList );
- NewList(&EventList);
-
- strcpy(Host, (UBYTE *)args[1]);
-
- ReadConfig(args[0] ? (char *)args[0] : "progdir:dock.prefs");
-
- if (DockList.lh_Head->ln_Succ)
- HandleAPI(&server);
-
- FreeTMHandle(TMHandle);
-
- StopServer(&server);
- }
- }
- else
- Puts("got no ToolManager handle ?!");
-
- FreeArgs(rdArgs);
- }
- else
- Puts("syntax error");
-
- CloseLibrary(CxBase);
- }
-
- exit(0);
- }
-
- /* ---------------------------------- wbmain -----------------------------------
-
- Workbench entry point; exit gracefully
-
- */
-
- int
- wbmain(struct WBStartup *startup)
- {
- if (ReqToolsBase = OpenLibrary("reqtools.library", 37)) {
-
- rtEZRequestTags("No executable - to be used as GoldED API client", "OK", NULL, NULL, TAG_DONE);
-
- CloseLibrary(ReqToolsBase);
- }
-
- exit(0);
- }
-
-
- ///
- /// "read config"
-
- /* -------------------------------- ReadConfig ---------------------------------
-
- Read preset file. Build linked list of dock definitions (DockList). PROG
- definitions (AREXX/CLI/HOTKEY/GOLDED) are appended to the EventList; the
- contents of the EventList are examined if ToolManger tells us that a dock
- icon has been activated by the user. DTOOL definitions (command + icon +
- sound) are appended to the <toolList>. The <tooList> is appended to the next
- dock created by a DOCK line.
-
- */
-
- void
- ReadConfig(prefs)
-
- UBYTE *prefs;
- {
- BPTR config;
-
- if (config = Open(prefs, MODE_OLDFILE)) {
-
- struct RDArgs *rdArgs;
-
- struct List toolList;
-
- NewList(&toolList);
-
- if (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) {
-
- static UBYTE buffer[256];
-
- while (FGets(config, buffer, 255)) {
-
- UBYTE *cmd;
-
- for (strcat(buffer, "\12"), cmd = buffer; *cmd && (*cmd != ';'); ++cmd) {
-
- if ((*cmd != ' ') && (*cmd != 10)) {
-
- ULONG n, argArray[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- struct RDArgs *args;
-
- for (n = 0; ConfigParser[n].Command; ++n) {
-
- if (!memcmp(cmd, ConfigParser[n].Command, strlen(ConfigParser[n].Command))) {
-
- cmd += strlen(ConfigParser[n].Command);
-
- rdArgs->RDA_Source.CS_Buffer = cmd;
- rdArgs->RDA_Source.CS_Length = strlen(cmd);
- rdArgs->RDA_Source.CS_CurChr = 0;
- rdArgs->RDA_DAList = NULL;
- rdArgs->RDA_Buffer = NULL;
-
- if (args = ReadArgs(ConfigParser[n].Template, argArray, rdArgs)) {
-
- (*((void (*)(ULONG *, struct List *))ConfigParser[n].Server))(argArray, &toolList);
-
- FreeArgs(args);
- }
- else {
-
- PrintFault(IoErr(), "syntax error");
- Puts(buffer);
- }
- }
- }
-
- break;
- }
- }
- }
-
- FreeDosObject(DOS_RDARGS, rdArgs);
- }
-
- Close(config);
- }
- else
- Puts("dock preset file missing");
- }
-
- /* ---------------------------------- AddProg ----------------------------------
-
- Add a command object (exec/WB/ARexx). The command definition is added to our
- internal EventList only. An ARexx object is added to ToolManagers pool, telling
- ToolManager to send us the object's name upon activation: Events are performed
- by us (i.e. the background task), not by ToolManager. This gives us the
- opportunity to change command strings before execution (e.g. in order to insert
- GoldED's current screen name). Event definitions are added to the <EventList>;
- we are going to scan this list if we recieve ARexx messages by ToolManager to
- determine approbiate action.
-
- template: NAME/A,COMMAND/K/A,AREXX/S,CLI/S,HOTKEY/S,WB/S,DIR/K,OUTPUT/K,ARGS/S,KEY/K,GOLDED/S,ACTIVATE/S,SHANGHAI/N",
-
- */
-
- void
- AddProg(args, toolList)
-
- ULONG *args;
- struct List *toolList;
- {
- struct Event *event;
-
- if (event = malloc(sizeof(struct Event))) {
-
- UBYTE *name = strdup((UBYTE *)args[0]);
-
- struct TagItem execTags[] = {
-
- TMOP_ExecType, TMET_ARexx,
- TMOP_Command, xsprintf("'address DOCKSERVER; \42%s\42'", name),
- TAG_DONE
- };
-
- event->Node.ln_Name = strdup((UBYTE *)args[0]);
- event->Command = strdup((UBYTE *)args[1]);
- event->Dir = args[6] ? strdup((UBYTE *)args[6]) : NULL;
- event->Key = args[9] ? strdup((UBYTE *)args[9]) : NULL;
- event->Output = args[7] ? strdup((UBYTE *)args[7]) : NULL;
- event->Hotkey = args[4];
- event->Args = args[8];
- event->Activate = args[11];
- event->Type = TMET_CLI;
-
- if (args[2]) // AREXX/S
- event->Type = TMET_ARexx;
-
- if (args[5]) // WB/S
- event->Type = TMET_WB;
-
- if (args[4]) // HOTKEY/S
- event->Type = TMET_Hotkey;
-
- if (args[10])
- event->Type = TMET_GoldED; // GOLDED/S
-
- AddTail(&EventList, &event->Node);
-
- CreateTMObjectTagList(TMHandle, name, TMOBJTYPE_EXEC, execTags);
- }
- }
-
- /* ---------------------------------- AddIcon ----------------------------------
-
- Add icon object to ToolManager's pool
-
- template: NAME/A,FILE/A
-
- */
-
- void
- AddIcon(args, toolList)
-
- ULONG *args;
- struct List *toolList;
- {
- struct TagItem iconTags[] = {
-
- TMOP_File, strdup((UBYTE *)args[1]),
- TMOP_Data, NULL,
- TAG_DONE
- };
-
- CreateTMObjectTagList(TMHandle, strdup((UBYTE *)args[0]), TMOBJTYPE_IMAGE, iconTags);
- }
-
-
- /* --------------------------------- AddSound ----------------------------------
-
- Add a sound object to ToolManagers pool
-
- template: NAME/A,COMMAND/K/A,PORT/K/A
-
- */
-
- void
- AddSound(args, toolList)
-
- ULONG *args;
- struct List *toolList;
- {
- struct TagItem soundTags[] = {
-
- TMOP_Command, strdup((UBYTE *)args[1]),
- TMOP_Port, strdup((UBYTE *)args[2]),
- TAG_DONE
- };
-
- CreateTMObjectTagList(TMHandle, strdup((UBYTE *)args[0]), TMOBJTYPE_SOUND, soundTags);
- }
-
- /* ---------------------------------- AddTool ----------------------------------
-
- Add a tool object (i.e. combination of command, icon, sound) to the list of
- tool objects. This list is a temporary list only; the list is appended to the
- next dock created by a DOCK line found in the preset file.
-
- template: PROG/K/A,ICON/K,SOUND/K
-
- */
-
- void
- AddTool(args, toolList)
-
- ULONG *args;
- struct List *toolList;
- {
- struct Tool *tool;
-
- if (tool = malloc(sizeof(struct Tool))) {
-
- tool->Exec = args[0] ? strdup((UBYTE *)args[0]) : NULL;
- tool->Icon = args[1] ? strdup((UBYTE *)args[1]) : NULL;
- tool->Sound = args[2] ? strdup((UBYTE *)args[2]) : NULL;
-
- AddTail(toolList, &tool->Node);
- }
- }
-
- /* ---------------------------------- AddDock ----------------------------------
-
- Add a dock description to the list of docks. This function won't actually
- create a dock on the screen. Instead, it will create a ready-to-use tag list.
- Passing this list to the ToolManager library (done by ShowDocks()) will create
- the dock.
-
- template: NAME/A,X/N,Y/N,HORIZONTAL/S,COLUMNS/N,HOTKEY/K,TITLE/K,CENTER/S,POPUP/S,HIDDEN/S,TEXT/S,STICKY/S,FRONTMOST/S,PATTERN/S,VERTICAL/S,LINEAR/S
-
- */
-
- void
- AddDock(args, toolList)
-
- ULONG *args;
- struct List *toolList;
- {
- UWORD entries;
-
- if (entries = CountList(toolList)) {
-
- struct Dock *dock;
-
- if (dock = malloc(sizeof(struct Dock))) {
-
- if (dock->Tags = (struct TagItem *)calloc((entries + 14) * sizeof(struct TagItem), 1)) {
-
- struct Node *tool;
- UWORD n;
-
- dock->Tags[0].ti_Tag = TMOP_PubScreen;
-
- dock->Tags[1].ti_Tag = TMOP_LeftEdge;
- dock->Tags[1].ti_Data = args[1] ? *(ULONG *)args[1] : ~0;
-
- dock->Tags[2].ti_Tag = TMOP_TopEdge;
- dock->Tags[2].ti_Data = args[2] ? *(ULONG *)args[2] : ~0;
-
- dock->Tags[3].ti_Tag = TMOP_Activated;
- dock->Tags[3].ti_Data = !args[9];
-
- dock->Tags[4].ti_Tag = TMOP_Centered;
- dock->Tags[4].ti_Data = args[7];
-
- dock->Tags[5].ti_Tag = TMOP_Columns;
- dock->Tags[5].ti_Data = args[4] ? (*(ULONG *)args[4]) : (args[15] ? (args[14] ? 1 : entries) : 0);
-
- dock->Tags[6].ti_Tag = TMOP_Vertical;
- dock->Tags[6].ti_Data = !args[14];
-
- dock->Tags[7].ti_Tag = TMOP_HotKey;
- dock->Tags[7].ti_Data = args[5] ? strdup((UBYTE *)args[5]) : NULL;
-
- dock->Tags[8].ti_Tag = TMOP_Title;
- dock->Tags[8].ti_Data = args[6] ? strdup((UBYTE *)args[6]) : NULL; // TITLE/K
-
- dock->Tags[9].ti_Tag = TMOP_PopUp;
- dock->Tags[9].ti_Data = args[8]; // TITLE/K
-
- dock->Tags[10].ti_Tag = TMOP_Text;
- dock->Tags[10].ti_Data = args[10]; // TITLE/K
-
- dock->Tags[11].ti_Tag = TMOP_FrontMost;
- dock->Tags[11].ti_Data = args[12]; // TITLE/K
-
- dock->Tags[12].ti_Tag = TMOP_Pattern;
- dock->Tags[12].ti_Data = args[13]; // TITLE/K
-
- // add the tool description tags:
-
- for (n = 13, tool = toolList->lh_Head; tool->ln_Succ; ++n, tool = tool->ln_Succ) {
-
- dock->Tags[n].ti_Tag = TMOP_Tool;
- dock->Tags[n].ti_Data = &((struct Tool *)tool)->Exec;
- }
-
- dock->Tags[n].ti_Tag = TAG_DONE;
- dock->Tags[n].ti_Data = NULL;
-
- dock->Visible = FALSE;
- dock->Elements = entries;
-
- dock->Node.ln_Name = strdup((UBYTE *)args[0]);
-
- AddTail(&DockList, &dock->Node);
- }
- }
- }
- else
- Puts("error: dock empty");
-
- NewList(toolList);
- }
-
- ///
- /// "API management"
-
- /* --------------------------------- HandleAPI ---------------------------------
-
- Register with GoldED & handle incoming API messages.
-
- */
-
- void
- HandleAPI(server)
-
- struct Task **server;
- {
- struct MsgPort *rexxPort, *apiPort;
-
- if (rexxPort = CreateMsgPort()) {
-
- if (apiPort = CreateMsgPort()) {
-
- struct RDArgs *rdArgs;
-
- if (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) {
-
- UBYTE command[255];
- ULONG *result;
-
- myprintf(command, "API PORT=%ld CLASS=%ld", apiPort, API_CLASS_ROOT | API_CLASS_SCREEN | API_CLASS_REXX);
-
- if ((result = SendRexxCommand(Host, command, rexxPort, FALSE, NULL, NULL)) && (*result == RC_OK)) {
-
- do {
-
- struct APIMessage *apiMsg, *nextMsg;
-
- while (!(apiMsg = (struct APIMessage *)GetMsg(apiPort)))
-
- WaitPort(apiPort);
-
- do {
-
- for (nextMsg = apiMsg; nextMsg; nextMsg = nextMsg->api_Next) {
-
- if (nextMsg->api_State == API_STATE_NOTIFY) {
-
- switch (nextMsg->api_Class) {
-
- case API_CLASS_ROOT:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_DIE:
-
- HideDocks();
-
- StopServer(server);
-
- server = NULL;
-
- break;
-
- case API_ACTION_INTRODUCE:
-
- static struct TagItem tags[] = {
-
- API_Client_Name, "NeXTStep",
- API_Client_Copyright, "©1995 Dietmar Eilert",
- API_Client_Purpose, "Dock Management System",
- API_Client_Template, "DOCK NAME/A,X/N,Y/N,SHOW/S,HIDE/S,TOGGLE/S,HORIZONTAL/S,VERTICAL/S,ROTATE/S,NEWLOOK/S,LINEAR/S",
- TAG_DONE
- };
-
- nextMsg->api_Data = tags;
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
-
- break;
-
- case API_CLASS_REXX:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_COMMAND:
-
- CommandDispatch(rdArgs, nextMsg);
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
-
- case API_CLASS_SCREEN:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_HIDE:
-
- HideDocks();
- break;
-
- case API_ACTION_SHOW:
-
- strcpy(Screen, nextMsg->api_Global->F_ScrnName);
-
- ShowDocks(NULL);
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
-
- ReplyMsg((struct Message *)apiMsg);
-
- } while (apiMsg = (struct APIMessage *)GetMsg(apiPort));
-
- } while (server);
- }
-
- FreeDosObject(DOS_RDARGS, rdArgs);
- }
-
- DeleteMsgPort(apiPort);
- }
-
- DeleteMsgPort(rexxPort);
- }
- }
-
- ///
- /// "command dispatcher"
-
- /* ------------------------------ CommandDispatch ------------------------------
-
- Dispatch commands sent by GoldED via the API interface. Commands are uppercase.
-
- */
-
- void
- CommandDispatch(rdArgs, apiMsg)
-
- struct RDArgs *rdArgs;
- struct APIMessage *apiMsg;
- {
- struct APIRexxNotify *notify = (struct APIRexxNotify *)apiMsg->api_Data;
-
- UWORD n;
-
- for (n = 0; CommandParser[n].Command; ++n) {
-
- if (memcmp(notify->arn_Command, CommandParser[n].Command, strlen(CommandParser[n].Command)) == NULL) {
-
- static UBYTE buffer[1024];
-
- UBYTE *arguments = buffer + strlen(CommandParser[n].Command);
-
- strcpy(buffer, notify->arn_Command);
- strcat(buffer, "\12");
-
- rdArgs->RDA_Source.CS_Buffer = arguments;
- rdArgs->RDA_Source.CS_Length = strlen(arguments);
- rdArgs->RDA_Source.CS_CurChr = 0;
- rdArgs->RDA_DAList = NULL;
- rdArgs->RDA_Buffer = NULL;
-
- if (CommandParser[n].Template) {
-
- ULONG argArray[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- if (ReadArgs(CommandParser[n].Template, argArray, rdArgs)) {
-
- notify->arn_RC = (*(LONG (*)(ULONG *, struct APIMessage *))CommandParser[n].Server)(argArray, apiMsg);
-
- FreeArgs(rdArgs);
- }
- else {
-
- static char errorText[81];
-
- Fault(IoErr(), "IoErr()", errorText, 80);
-
- notify->arn_RC = RC_WARN;
- notify->arn_CommandError = errorText;
- }
- }
- else
- notify->arn_RC = (*(LONG (*)(ULONG *, struct APIMessage *))CommandParser[n].Server)(NULL, apiMsg);
-
- apiMsg->api_State = API_STATE_CONSUMED;
- }
- }
- }
-
- /* -------------------------------- ModifyDock ---------------------------------
-
- Modify look of a dock
-
- template: NAME/A,X/N,Y/N,SHOW/S,HIDE/S,TOGGLE/S,HORIZONTAL/S,VERTICAL/S,ROTATE/S,NEWLOOK/S,LINEAR/S
-
- */
-
- LONG
- ModifyDock(args, apiMsg)
-
- ULONG *args;
- struct APIMessage *apiMsg;
- {
- struct Dock *dock;
-
- if (dock = SearchName(&DockList, (UBYTE *)args[0])) {
-
- struct TagItem *tag;
- BOOL visible;
-
- if (visible = dock->Visible)
- DeleteTMObject(TMHandle, dock->Node.ln_Name);
-
- dock->Visible = FALSE;
-
- if (args[1]) // X/N
-
- FindTagItem(TMOP_LeftEdge, dock->Tags)->ti_Data = *(ULONG *)args[1];
-
- if (args[2]) // Y/N
-
- FindTagItem(TMOP_TopEdge, dock->Tags)->ti_Data = *(ULONG *)args[2];
-
- tag = FindTagItem(TMOP_Vertical, dock->Tags);
-
- if (args[6]) // HORIZONTAL/S
- tag->ti_Data = TRUE;
-
- if (args[7]) // VERTICAL/S
- tag->ti_Data = FALSE;
-
- if (args[8]) // ROTATE/S
- tag->ti_Data = !tag->ti_Data;
-
- if (args[10]) // LINEAR/S
-
- FindTagItem(TMOP_Columns, dock->Tags)->ti_Data = (tag->ti_Data) ? dock->Elements : 1;
-
- tag = FindTagItem(TMOP_Text, dock->Tags);
-
- if (args[9]) // NEWLOOK/S
- tag->ti_Data = !tag->ti_Data;
-
- if (args[3]) // SHOW/S
- visible = TRUE;
-
- if (args[4]) // HIDE/S
- visible = FALSE;
-
- if (args[5]) // TOGGLE/S
- visible = !visible;
-
- if (visible)
- ShowDocks(dock);
- }
- else
- Puts("Unknow dock");
-
- return(RC_OK);
- }
-
- ///
- /// "dock handling"
-
- /* --------------------------------- ShowDocks ---------------------------------
-
- Show specified (hidden) dock or all hidden docks if <dock> is FALSE.
-
- */
-
- void
- ShowDocks(showDock)
-
- struct Dock *showDock;
- {
- struct Screen *scr;
-
- if (scr = LockPubScreen(Screen)) {
-
- struct Dock *dock;
-
- for (dock = (struct Dock *)DockList.lh_Head; dock->Node.ln_Succ; dock = (struct Dock *)dock->Node.ln_Succ) {
-
- if (!dock->Visible) {
-
- if ((dock == showDock) || (showDock == NULL)) {
-
- struct TagItem *tag;
-
- FindTagItem(TMOP_PubScreen, dock->Tags)->ti_Data = Screen;
-
- if ((tag = FindTagItem(TMOP_LeftEdge, dock->Tags))->ti_Data == ~0)
- tag->ti_Data = scr->Width;
-
- if ((tag = FindTagItem(TMOP_TopEdge, dock->Tags))->ti_Data == ~0)
- tag->ti_Data = scr->BarHeight + ((scr->BitMap.Depth == 1) ? 2 : 1);
-
- if (CreateTMObjectTagList(TMHandle, dock->Node.ln_Name, TMOBJTYPE_DOCK, dock->Tags))
- dock->Visible = TRUE;
- else
- Puts("Couldn't create dock object");
- }
- }
- }
-
- UnlockPubScreen(NULL, scr);
- }
- }
-
- /* --------------------------------- HideDocks ---------------------------------
-
- Hide all open docks
-
- */
-
- void
- HideDocks()
- {
- struct Dock *dock;
-
- for (dock = (struct Dock *)DockList.lh_Head; dock->Node.ln_Succ; dock = (struct Dock *)dock->Node.ln_Succ) {
-
- if (dock->Visible) {
-
- DeleteTMObject(TMHandle, dock->Node.ln_Name);
-
- dock->Visible = FALSE;
- }
- }
- }
-
-
- ///
- /// "misc"
-
-
- /* --------------------------------- StopServer --------------------------------
-
- Stop server task
-
- */
-
- void
- StopServer(server)
-
- struct Task **server;
- {
- if (*server) {
-
- SetSignal(0, SIG_HANDSHAKE);
-
- Signal(*server, SIG_KILL);
-
- Wait(SIG_HANDSHAKE);
-
- *server = NULL;
- }
- }
-
-
- /* -------------------------------- PutIEvents ---------------------------------
-
- Add keyboard events to global stream of input events. Works recursively to
- invert the given linked list of events (which is inverted due to
- InvertString). Restores the links after usage to support a FreeIEvents()
- call later on.
-
- */
-
- void
- PutIEvents(inputEvent)
-
- struct InputEvent *inputEvent;
- {
- struct InputEvent *next;
-
- if (next = inputEvent->ie_NextEvent)
- PutIEvents(next);
-
- inputEvent->ie_NextEvent = NULL;
-
- AddIEvents(inputEvent);
-
- inputEvent->ie_NextEvent = next;
- }
-
- /* ---------------------------------- InsertEvent ------------------------------
-
- Insert string into input event loop. String is interpreted. Return FALSE on
- failure (interpretation error).
-
- */
-
- void
- InsertEvent(string)
-
- UBYTE *string;
- {
- struct InputEvent *inputEvent;
-
- if (inputEvent = MyInvertString(string, NULL)) {
-
- PutIEvents (inputEvent);
- MyFreeIEvents(inputEvent);
- }
- }
-
-
- /* ---------------------------------- stristr ----------------------------------
-
- strstr replacement: case insensitive (recursive)
-
- */
-
- UBYTE *
- stristr(buffer, pattern)
-
- UBYTE *buffer, *pattern;
- {
- if (*pattern) {
-
- while (*buffer) {
-
- if (toupper(*buffer) == *pattern)
- if (stristr(buffer + 1, pattern + 1))
- return(buffer);
-
- ++buffer;
- }
-
- return(NULL);
- }
- else
- return(buffer);
- }
-
- /* ---------------------------------- Replace ----------------------------------
-
- Replace given <pattern> within <buffer> by <new> (case insensitive)
-
- */
-
- void
- Replace(buffer, pattern, new)
-
- UBYTE *buffer, *pattern, *new;
- {
- UWORD newLen;
-
- for (newLen = strlen(new); buffer = stristr(buffer, pattern); buffer += newLen) {
-
- WORD diffLen = newLen - strlen(pattern);
-
- if (diffLen > 0)
- movmem(buffer, buffer + diffLen, strlen(buffer) + 1);
-
- if (diffLen < 0)
- strcpy(buffer, buffer - diffLen);
-
- movmem(new, buffer, newLen);
- }
- }
-
-
- /* -------------------------------- SearchName ---------------------------------
-
- Search for named node; case insensitive FindName() replacement
-
- */
-
- struct Node *
- SearchName(list, name)
-
- struct List *list;
- UBYTE *name;
- {
- struct Node *node;
-
- if (node = FindName(list, name))
- return(node);
-
- for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
- if (node->ln_Name && (stricmp(name, node->ln_Name) == 0))
- return(node);
-
- return(NULL);
- }
-
- /* ----------------------------------- Puts ------------------------------------
-
- puts() replacement; saves another 2K ;-)
-
- */
-
- void
- Puts(text)
-
- UBYTE *text;
- {
- Write(Output(), text, strlen(text));
- Write(Output(), "\n", 1);
- }
-
-
- /* ---------------------------------- CountList --------------------------------
-
- Count nodes of a list
-
- */
-
- UWORD
- CountList(list)
-
- struct List *list;
- {
- UWORD count;
- struct Node *nextNode;
-
- for (count = 0, nextNode = list->lh_Head; nextNode->ln_Succ; nextNode = nextNode->ln_Succ)
- count++;
-
- return(count);
- }
-
-
- /* --------------------------------- xsprintf ----------------------------------
-
- sprintf frontend (malloc buffer); limited to string insertion into string
-
- */
-
- UBYTE *
- xsprintf(mask, var)
-
- UBYTE *mask, *var;
- {
- char *buffer;
-
- if (buffer = malloc(strlen(mask) + strlen(var)))
- myprintf(buffer, mask, var);
-
- return(buffer);
- }
-
- ///
- /// "ARexx"
-
- /* ---------------------------------- SendRexxCommand -------------------------
-
- Send ARexx message & wait for answer. Don't wait for reply in asynchronous
- mode. In synchronous mode: return pointer to result or NULL. Result string
- is written to <buffer> if <buffer> is valid. In asynchronous mode: return
- TRUE (message sent; increase <counter>) or NULL.
-
- */
-
- ULONG *
- SendRexxCommand(port, cmd, replyPort, async, counter, buffer)
-
- UBYTE *cmd, *port, *buffer;
- UWORD *counter;
- BOOL async;
- struct MsgPort *replyPort;
- {
- struct MsgPort *rexxport;
-
- Forbid();
-
- if (rexxport = FindPort(port)) {
-
- struct RexxMsg *rexxMsg;
-
- if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
-
- if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
-
- static ULONG result;
-
- struct RexxMsg *answer;
-
- rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
-
- PutMsg(rexxport, &rexxMsg->rm_Node);
-
- Permit();
-
- if (counter)
- ++*counter;
-
- if (async)
- return(TRUE);
-
- do {
-
- WaitPort(replyPort);
-
- if (answer = (struct RexxMsg *)GetMsg(replyPort)) {
-
- if (answer->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
-
- if (counter)
- --*counter;
-
- if (answer == rexxMsg) {
-
- if ((result = answer->rm_Result1) == RC_OK) {
-
- if (answer->rm_Result2 && buffer)
- strcpy(buffer, (char *)answer->rm_Result2);
- }
- }
-
- FreeRexxCommand(answer);
- }
- else {
-
- answer->rm_Result1 = RC_FATAL;
-
- ReplyMsg((struct Message *)answer);
- }
- }
-
- } while (answer != rexxMsg);
-
- return(&result);
- }
- }
- }
-
- Permit();
-
- return(NULL);
- }
-
- /* ------------------------------- CloseRexxPort -------------------------------
-
- Close an ARexx port. Wait until all outstanding (i.e. sent) messages
- (<missing>) have been replied. Remove port from list of public ports if
- <removePort> is TRUE.
-
- */
-
- void
- CloseRexxPort(port, missing, removePort)
-
- struct MsgPort *port;
- UWORD missing;
- BOOL removePort;
- {
- if (removePort)
- RemPort(port);
-
- Forbid();
-
- while (missing) {
-
- struct RexxMsg *rexxMsg;
-
- Wait(1L<<port->mp_SigBit);
-
- while (rexxMsg = (struct RexxMsg *)GetMsg(port)) {
-
- if (rexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
-
- FreeRexxCommand(rexxMsg);
-
- missing--;
- }
- else {
-
- rexxMsg->rm_Result1 = RC_FATAL;
-
- ReplyMsg((struct Message *)rexxMsg);
- }
- }
- }
-
- DeleteMsgPort(port);
-
- Permit();
- }
-
- /* ------------------------------- FreeRexxCommand ----------------------------
-
- Free memory/file handles related to message <rexxmessage> replied by the
- ARexx server.
-
- */
-
- void
- FreeRexxCommand(rexxMsg)
-
- struct RexxMsg *rexxMsg;
- {
- if (rexxMsg->rm_Result1 == RC_OK)
- if (rexxMsg->rm_Result2)
- DeleteArgstring((char *)rexxMsg->rm_Result2);
-
- if (rexxMsg->rm_Stdin)
- Close(rexxMsg->rm_Stdin);
-
- if (rexxMsg->rm_Stdout && (rexxMsg->rm_Stdout != rexxMsg->rm_Stdin))
- Close(rexxMsg->rm_Stdout);
-
- DeleteArgstring((char *)ARG0(rexxMsg));
-
- DeleteRexxMsg(rexxMsg);
- }
-
- ///
- /// "execute programs"
-
- /* -------------------------------- DoExecute ------------------------------------
-
- Execute a DOS command.
-
- */
-
- void
- DoExecute(cmd, async, output, directory, stack, prio)
-
- UBYTE *cmd, *output, *directory;
- UWORD stack;
- WORD prio;
- BOOL async;
- {
- BPTR newCurrentDir;
-
- if (!directory)
- directory = "progdir:";
-
- if (!output)
- output = "NIL:";
-
- if (newCurrentDir = Lock(directory, SHARED_LOCK)) {
-
- BPTR inHandle, outHandle, oldCurrentDir = CurrentDir(newCurrentDir);
-
- if (outHandle = Open(output, MODE_NEWFILE)) {
-
- struct TagItem tagItems[] = {
-
- SYS_Output, NULL,
- SYS_Input , NULL,
- NP_ConsoleTask, NULL,
- SYS_UserShell, TRUE,
- SYS_Asynch, async,
- NP_StackSize, stack,
- NP_Priority, prio,
- TAG_DONE
- };
-
- struct MsgPort *oldct, *newct;
-
- BOOL success = FALSE;
-
- if (IsInteractive(outHandle)) {
-
- newct = ((struct FileHandle *)BADDR(outHandle))->fh_Type;
- oldct = SetConsoleTask(newct);
-
- inHandle = Open("CONSOLE:", MODE_OLDFILE);
-
- SetConsoleTask(oldct);
- }
- else {
-
- inHandle = Open("NIL:", MODE_OLDFILE);
- newct = NULL;
- }
-
- if (inHandle) {
-
- tagItems[0].ti_Data = outHandle;
- tagItems[1].ti_Data = inHandle;
- tagItems[2].ti_Data = newct;
-
- if (SystemTagList(cmd, tagItems) != -1L)
- success = TRUE;
-
- if (!(async && success))
- Close(inHandle);
- }
-
- if (!(async && success))
- Close(outHandle);
- }
-
- CurrentDir(oldCurrentDir);
-
- UnLock(newCurrentDir);
- }
- }
-
- ///
- /// "Server"
-
- /* -------------------------------- ARexxServer --------------------------------
-
- ARexx server; used to process ARexx commands sent by ToolManager. This
- function is installed as background task. Run until a SIG_HANDSHAKE is
- recieved from the main task. Rise SIG_HANDSHAKE on exit (multitasking
- disabled, i.e. if the main task detects the signal, this task is gone
- already).
-
- */
-
- __geta4 void
- ARexxServer()
- {
- struct MsgPort *port;
-
- Forbid();
-
- if (port = CreateMsgPort()) {
-
- ULONG mask;
- UWORD missing = 0;
-
- port->mp_Node.ln_Name = "DOCKSERVER";
-
- AddPort(port);
-
- do {
-
- struct RexxMsg *rexxMsg;
-
- mask = Wait(1L<<(port->mp_SigBit) | SIG_KILL);
-
- while (rexxMsg = (struct RexxMsg *)GetMsg(port)) {
-
- if (rexxMsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) {
-
- FreeRexxCommand(rexxMsg);
-
- if (missing)
- missing--;
- }
- else {
-
- struct Event *event;
-
- if (event = (struct Event *)SearchName(&EventList, ARG0(rexxMsg))) {
-
- if (event->Command) {
-
- static UBYTE buffer[1024];
-
- strcpy(buffer, event->Command);
-
- Replace(buffer, "%SCREEN", Screen);
- Replace(buffer, "%GOLDED", Host );
-
- if (event->Activate)
- SendRexxCommand(Host, "WINDOW FORCE", port, TRUE, &missing, NULL);
-
- switch (event->Type) {
-
- case TMET_ARexx:
-
- SendRexxCommand("AREXX", buffer, port, TRUE, &missing, NULL);
- break;
-
- case TMET_GoldED:
-
- SendRexxCommand(Host, buffer, port, TRUE, &missing, NULL);
- break;
-
- case TMET_CLI:
- case TMET_WB:
-
- DoExecute(buffer, TRUE, event->Output, event->Dir, 8192, 0);
- break;
-
- case TMET_Hotkey:
-
- InsertEvent(buffer);
- break;
- }
- }
- }
-
- rexxMsg->rm_Result1 = NULL;
- rexxMsg->rm_Result2 = NULL;
-
- ReplyMsg((struct Message *)rexxMsg);
- }
- }
-
- } while (!(mask & SIG_KILL));
-
- CloseRexxPort(port, missing, TRUE);
- }
- else
- Wait(SIG_KILL);
-
- Forbid();
-
- Signal(MainTask, SIG_HANDSHAKE);
- }
-
- ///
-