home *** CD-ROM | disk | FTP | other *** search
- /*
- * Yak version 2.00
- * ----------------
- * [Yak == Yet Another K(?)ommodity
- *
- * There seems to be a profusion of commodities doing this or that.
- * Heres mine, to do what I want it to:
- *
- * AutoActivate windows (SunMouse)
- * ClickToFront, ClickToBack, ScreenCycle
- * Close/Zip/Shrink/Zoom/Turn a window via keyboard.
- * Bring up a palette on front screen.
- * Insert date into read-stream.
- * Produce key-click (like my keyclick program).
- * Some other things...
- *
- * Martin W. Scott, Gaƫl Marziou & Philippe Bastiani, 7/94.
- */
-
- #define __USE_SYSBASE
-
- #include <exec/types.h>
- #include <exec/libraries.h>
- #include <exec/memory.h>
- #include <devices/inputevent.h>
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <dos/notify.h>
- #include <graphics/displayinfo.h>
- #include <libraries/commodities.h>
- #include <libraries/reqtools.h>
- #include <libraries/locale.h>
- #include <intuition/intuitionbase.h>
- #include <workbench/startup.h>
- #include <clib/alib_protos.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/graphics.h>
- #include <proto/commodities.h>
- #include <proto/icon.h>
- #include <proto/iffparse.h>
- #include <proto/intuition.h>
- #include <proto/layers.h>
- #include <proto/locale.h>
- #include <proto/reqtools.h>
- #include <proto/wb.h>
-
- #include <string.h>
-
- #include "Code.h"
- #include "yak.h"
- #include "hotkey_types.h"
- #include "beep.h"
- #include "Handlers.h"
- #include "icon.h"
- #include "version.h"
- #include "Requesters.h"
- #include "Settings.h"
- #include "Pri.h"
- #include "UnixDirs.h"
- #include "LastActiveWindow.h"
-
- #define CATCOMP_BLOCK
- #define CATCOMP_NUMBERS
- #include "yak_locale_strings.h"
- #undef CATCOMP_BLOCK
-
- #ifdef USE_WB2CLI
- # include "WB2CLI.h" /* we'll be a shell process */
- #endif
-
- #define DEF_CURRENTDIR "SYS:"
-
- /* local prototypes for main.c */
- static void CloseResources(void);
- static BOOL OpenResources(void);
- static void FreePatterns(void);
- static LONG ProcessMsg(void);
- void MAIN(void);
-
-
- extern struct WBStartup *WBMsg;
- /*
- * libraries opened by startup code; basepointers needed by function pragmas
- */
-
- #if defined(_DCC)
-
- extern struct ExecBase *SysBase;
- extern struct DosLibrary *DOSBase;
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
-
- /* global data - library bases and the like */
- struct Library *CxBase, *IconBase,
- *LayersBase,
- *WorkbenchBase,
- *IFFParseBase;
-
- #endif
-
- struct MsgPort *broker_mp;
- CxObj *broker;
- char *PopKeyStr;
- #define POPKEY_EVENT 1L /* cannot clash with YHK event... */
-
- char *PrefsPrg;
-
-
- struct NewBroker newbroker = {
- NB_VERSION,
- "Yak", /* string to identify this broker */
- VERSION_BROKER,
- "Multi-purpose commodity",
- NBU_UNIQUE | NBU_NOTIFY, /* Don't want any new commodities
- * starting with this name. If someone
- * tries it, let me know */
- COF_SHOW_HIDE
- };
-
- ULONG cxsigflag;
- ULONG invariantsigflag;
- BYTE palette_count; /* how many palettes are open */
-
-
- /* from icon.c */
- extern ULONG appsigflag;
-
-
- /* close what we opened */
- static void
- CloseResources()
- {
- /* NULL pointers are valid so don't waste time to test them */
- CloseLibrary((struct Library *)IntuitionBase);
- CloseLibrary((struct Library *)GfxBase);
- CloseLibrary(CxBase);
- CloseLibrary(LayersBase);
- CloseLibrary(IconBase);
- CloseLibrary(WorkbenchBase);
- CloseLibrary(IFFParseBase);
- CloseLocaleStuff();
- }
-
-
-
- /* open libraries, devices that we need */
- static BOOL
- OpenResources(void)
- {
- if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37L)) &&
- (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37L)) &&
- (CxBase = OpenLibrary("commodities.library", 37L)) &&
- (LayersBase = OpenLibrary("layers.library", 37L)) &&
- (IconBase = OpenLibrary("icon.library", 37L)) &&
- (WorkbenchBase = OpenLibrary("workbench.library", 37L)) &&
- (IFFParseBase = OpenLibrary("iffparse.library", 37L)))
- {
- return TRUE;
- }
- CloseResources();
- return FALSE;
- }
-
-
-
- static void
- FreePatterns()
- {
- UWORD i;
-
- for (i = 0; i < NUM_PATTERNS; i++)
- if (patterns[i].pat) FreeVec(patterns[i].pat);
- }
-
-
- BOOL
- ShowYakInterface(void)
- {
- BPTR infh;
- BPTR ppl;
-
- if (ppl=Lock(PrefsPrg, ACCESS_READ))
- {
- UnLock(ppl);
-
- if (infh=Open("Nil:", MODE_OLDFILE))
- {
- SystemTags(PrefsPrg, SYS_Input, infh,
- SYS_Output, NULL,
- SYS_Asynch, TRUE,
- TAG_DONE);
- }
-
- return TRUE;
- }
-
- PostError("%s\n\"%s\"", getString(Launching_prefs_program_ERR), PrefsPrg);
- return(FALSE);
- }
-
-
- static LONG notifysigbit;
- static ULONG notifysigflag;
- static struct NotifyRequest NotifyRequest;
-
-
- void
- EndNotification(void)
- {
- EndNotify(&NotifyRequest);
- FreeSignal(notifysigbit);
- }
-
- void
- SetNotification(void)
- {
- /* Allocate a signalsbit */
- if ((notifysigbit = AllocSignal(-1L)) != -1)
- {
- notifysigflag = 1 << notifysigbit;
-
- /* Initialize notification request */
-
- NotifyRequest.nr_Name = ENV_CONFIG_FILE;
- NotifyRequest.nr_Flags = NRF_SEND_SIGNAL;
- /* Signal this task */
- NotifyRequest.nr_stuff.nr_Signal.nr_Task = (struct Task *) FindTask(NULL);
- /* with this signals bit */
- NotifyRequest.nr_stuff.nr_Signal.nr_SignalNum = notifysigbit;
-
- StartNotify(&NotifyRequest);
- }
- }
-
-
-
- #ifdef _DCC
- void _waitwbmsg(void);
- static void
- uncalled(void)
- {
- _waitwbmsg();
- }
- #endif
-
- UBYTE FRONT_DELAY, BACK_DELAY;
-
-
- void MAIN() /* Yak: multi-function commodity */
- {
- BPTR newdir=NULL, olddir;
- STRPTR ProgramName;
-
- if (OpenResources())
- {
- if (broker_mp = CreateMsgPort())
- {
- newbroker.nb_Port = broker_mp;
- cxsigflag = 1L << broker_mp->mp_SigBit;
-
- if (WBMsg) /* WB Startup */
- {
- struct WBArg *wbarg=&WBMsg->sm_ArgList[0];
-
- /* Get Program Name */
- if (ProgramName=AllocVec(256, MEMF_CLEAR))
- {
- BPTR lock=GetProgramDir();
- if (NameFromLock(lock, ProgramName, 256))
- AddPart(ProgramName, wbarg->wa_Name, 256);
- }
-
- /* Current Directory */
- if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
- olddir = CurrentDir(newdir);
- #ifdef USE_WB2CLI
- WB2CLI(WBMsg,4000,(struct DosLibrary *)DOSBase); /* get it over with... */
- #endif
- }
- else /* CLI Startup */
- {
- /* Get Program Name */
- if (ProgramName=AllocVec(256, MEMF_CLEAR))
- GetProgramName(ProgramName, 256);
- }
-
- /* process tool-types */
- GetOurIcon(ProgramName);
-
- newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
-
- FRONT_DELAY=(UBYTE)TTInt("FRONT_DELAY", 6);
- BACK_DELAY=(UBYTE)TTInt("BACK_DELAY", 6);
-
- if (broker = CxBroker(&newbroker, NULL))
- {
- /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
- if (InitMainHandler())
- {
- InitYakHotKeyList();
-
- /* Open the right locale if tooltype LANGUAGE is used */
- OpenLocaleStuff(TTString("LANGUAGE",NULL));
-
- PrefsPrg = DupStr(TTString("PREFSPRG", "Sys:Prefs/Yak"));
-
- if (PopKeyStr = DupStr(TTString("CX_POPKEY", "Rcommand help")))
- {
- CxObj *tmpobj;
-
- if (tmpobj = HotKey(PopKeyStr, broker_mp, POPKEY_EVENT))
- AttachCxObj(broker, tmpobj);
- else
- PostError("%s:\"%s\"", getString(CX_POPKEY_invalid_ERR),
- PopKeyStr);
- }
- /* else... if this failed, we lose */
-
- MyPri(ACTIVE);
-
- LoadSettings(ENV_CONFIG_FILE);
-
- ActivateCxObj(broker, 1L);
-
- if (TTBool("CX_POPUP", FALSE))
- ShowYakInterface();
-
- if (TTBool("APPICON", FALSE))
- {
- if (!MakeOurAppIcon(TTString("ICONNAME", "Yak!")))
- if (WBMsg)
- PostError(getString(Couldn_t_create_AppIcon_ERR));
- }
- /* WB makes a copy of icon, so can free it */
- FreeOurIcon();
-
- /*
- * We want to be notified each time either
- * ENV:yak.prefs is modified (by Yak Preferences)
- */
- SetNotification();
-
- /* these are the signals waited for, + window sig */
- invariantsigflag = SIGBREAKF_CTRL_C | cxsigflag
- | clicksigflag | intuiopsigflag | blankscreensigflag
- | appsigflag | notifysigflag | depthscreensigflag;
-
- while (ProcessMsg())
- ;
- RemoveOurAppIcon();
- DeleteYakHotKeyList();
-
- FreeVec(PopKeyStr);
- FreeVec(PrefsPrg);
- MyPri(ORIGINAL);
-
- EndNotification();
- EndMainHandler();
- FreePatterns();
- CleanMouseCycling();
- }
- else
- PostError(getString(Allocation_ERR));
-
- DeleteCxObjAll(broker);
- }
-
- if (newdir)
- {
- CurrentDir(olddir);
- UnLock(newdir);
- }
- DeleteMsgPort(broker_mp);
-
- FreeOurIcon(); /* may already be gone, but so what? */
-
- if (ProgramName) FreeVec(ProgramName);
- }
- else PostError(getString(Allocation_ERR));
-
- ToggleUnixDirs( FALSE );
-
- CloseResources();
- }
- else PostError(getString(Resource_ERR));
- }
-
- IMPORT BYTE oldpri; /* priority before handlers.c changed it */
-
- ULONG secs, micros;
-
- /* monitor cx port, act on messages */
- static LONG
- ProcessMsg(void)
- {
- CxMsg *msg;
- ULONG sigrcvd, msgid, msgtype;
- struct InputEvent *ie;
- LONG returnvalue = 1L;
-
- sigrcvd = Wait(invariantsigflag);
-
- if (sigrcvd & intuiopsigflag)
- {
- /* intuiop requested */
- intui_routine(intui_parameter);
-
- }
-
- if ((sigrcvd & clicksigflag) && click_volume) /* keyclick please */
- {
- beep(click_volume);
- }
-
- if (sigrcvd & depthscreensigflag) /* screen depth gadget has been pressed */
- {
- ScreenDepthGadget();
- }
-
- if (sigrcvd & blankscreensigflag) /* blank screen please */
- {
- BlankScreen();
- }
-
- if (sigrcvd & appsigflag) /* start the prefs program */
- {
- ClearAppMsgPort();
- ShowYakInterface();
- }
-
- if (sigrcvd & notifysigflag) /* settings have changed */
- {
- LoadSettings(ENV_CONFIG_FILE);
- }
-
- while(msg = (CxMsg *)GetMsg(broker_mp))
- {
- msgid = CxMsgID(msg);
- msgtype = CxMsgType(msg);
- if(msgtype==CXM_IEVENT)
- {
- /*
- * copy the interesting data of the inputevent
- */
- ie = (struct InputEvent *)CxMsgData(msg);
- secs = ie->ie_TimeStamp.tv_secs;
- micros = ie->ie_TimeStamp.tv_micro;
- }
- ReplyMsg((struct Message *)msg);
-
- switch(msgtype)
- {
- case CXM_IEVENT:
- switch (msgid)
- {
- /* The msgid is used in 2 different ways:
- * as a simple event number for both POPKEY_EVENT and mouse cycling events
- * as a pointer to the structure of the hotkey to process
- *
- * This may look like a kludge but we can use safely small numbers for events
- * because they will be out of adresses range. Low addresses are located in ROM.
- */
-
- case POPKEY_EVENT:
- ShowYakInterface();
- break;
-
- case WINDOW_TOFRONT_EVENT:
- case WINDOW_TOBACK_EVENT:
- case SCREENCYCLING_EVENT:
- /* Execute function attached to this event */
- (*(MouseCyclingHandlers[msgid-WINDOW_TOFRONT_EVENT].HandlerFunction))();
- break;
-
- default:
- /* a generic hotkey... */
- PerformAction((YakHotKey *)msgid);
- break;
-
- }
- break;
-
- case CXM_COMMAND:
- switch(msgid)
- {
- case CXCMD_UNIQUE:
- case CXCMD_APPEAR:
- ShowYakInterface();
- break;
-
- case CXCMD_DISAPPEAR:
- BrokerCommand("Yak_Prefs", CXCMD_DISAPPEAR);
- break;
-
- case CXCMD_DISABLE:
- ActivateCxObj(broker, 0L);
- TurnMouseOn();
- break;
-
- case CXCMD_ENABLE:
- ActivateCxObj(broker, 1L);
- break;
-
- case CXCMD_KILL:
- returnvalue = 0L;
- break;
- }
- break;
- }
- }
-
- if (sigrcvd & SIGBREAKF_CTRL_C)
- returnvalue = 0L;
-
- if (!returnvalue && !OkayToExit())
- {
- PostError(getString(Cannot_exit_palette_opened_ERR));
- returnvalue = 1;
- }
-
- return(returnvalue);
- }
-