/* * AutoActivate.c * * Commodity * * Author: Stefan Sticht * * Copyright: source is public domain, no copyright * * Version history: * * V1.00 initial release * V1.03 handlecustomsignal(): activate only if !ActiveWindow->FirstRequest * V1.04 recompiled with main.c V1.02 * V1.05 fixed code to find window under mouse pointer * V1.06 completly rewritten; shared commodity code thrown away; smaller, uses less CPU time * V1.07 changed priority to 21 * V1.08 added a LockIBase() */ #define VERSION "V1.08" /******************************************************************** * interfacing * ********************************************************************/ /* * include files */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEBUG #define printf KPrintF #include #endif /* * prototypes */ long request(char *title, char *gadgets, char *text, ...); struct Library *myopenlibrary(char *name, unsigned long version); void activate(void); void processmessages(void); /* * global data defined in other moduls * * libraries opened by startup code; basepointers needed by function pragmas */ extern struct Library *DOSBase; extern struct Library *SysBase; /* * Disable SAS/C CTRL/C handling */ void chkabort(void) {} /******************************************************************** * global data * ********************************************************************/ /* * definition of all messages (multi language support not completed yet) */ #ifdef GERMAN #define RETRY_GADGETS "Wiederholen|Abbrechen" #define RESUME_GADGETS "Weiter" #define MSG_LIBRARY_OPENERR "Die %s (V%ld+) kann nicht geöffnet werden!" #define COM_NAME "AutoActivate" #define COM_DESCR "Aktiviert Fenster unter Maus bei Tasten" #define NO "NEIN" #define TT_TIMEOUT "SEKUNDEN" #else #define RETRY_GADGETS "Retry|Cancel" #define RESUME_GADGETS "Resume" #define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!" #define COM_NAME "AutoActivate" #define COM_DESCR "Activate window under mouse by key" #define NO "NO" #define TT_TIMEOUT "SECONDS" #endif #define COM_TITLE COM_NAME " " VERSION #define CX_PRIORITY "CX_PRIORITY" #define DEF_CX_PRIORITY 0 /* * data for cback.o */ long _stack = 2048l; char *_procname = COM_NAME; long _priority = 21l; long _BackGroundIO = 1; extern BPTR _Backstdout; /* * library base pointers */ struct IntuitionBase *IntuitionBase; struct Library *CxBase; struct Library *IconBase; struct Library *LayersBase; /* * message port */ struct MsgPort *cxport = NULL; /* * pointer to our task */ struct Task *mytask = NULL; /* * signal flags */ unsigned long customsigflag = 0l; unsigned long cxsigflag = 0l; /* * programtitle and version for Version command */ char versionstring[] ="\0$VER: " COM_NAME " " VERSION; /* * helpstring */ #ifdef GERMAN char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\ "Aufruf: " COM_NAME " [" CX_PRIORITY "=]\n"; #else char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n" "Usage: " COM_NAME " [" CX_PRIORITY "=]\n"; #endif /* * the tooltypearray */ char **tooltypes; /* * our broker */ CxObj *broker = NULL; struct NewBroker newbroker = { NB_VERSION, /* BYTE nb_Version */ COM_NAME, /* BYTE *nb_Name */ COM_TITLE, /* BYTE *nb_Title */ COM_DESCR, /* BYTE *nb_Descr */ NBU_NOTIFY | NBU_UNIQUE, /* SHORT nb_Unique */ 0, /* SHORT nb_Flags */ 0, /* BYTE nb_Pri */ NULL, /* struct MsgPort nb_Port */ 0 /* WORD nb_ReservedChannel */ }; IX autoix = { IX_VERSION, /* UBYTE ix_version */ IECLASS_RAWKEY, /* UBYTE ix_Class */ 0, /* UWORD ix_Code */ 0, /* UWORD ix_CodeMask */ 0, /* UWORD ix_Qualifier */ 0, /* UWORD ix_Qualmask */ 0 /* UWORD ix_QualSame */ }; /******************************************************************** * functions * ********************************************************************/ /* * request(): a glue routine to EasyRequest as simple as printf plus * titlestring, gadgettexts * * Input: char *title: pointer to the title of the requester * char *gadgets: pointer to gadgettext * char *text: text displayed in requester * * Result: same as EasyrequestArgs() * * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!! */ long request(char *title, char *gadgets, char *text, ...) { /* * structure textreq only needed in this function, so hide it here * must be static, in order to be initialized only once */ static struct EasyStruct textreq = { sizeof (struct EasyStruct), /* ULONG es_StructSize */ 0l, /* ULONG es_Flags */ NULL, /* UBYTE *es_Title */ NULL, /* UBYTE *es_TextFormat */ NULL, /* UBYTE *es_GadgetFormat */ }; va_list ap; long rc; /* * get start of variable arguments */ va_start(ap, text); /* * update textreq */ textreq.es_Title = (UBYTE *)title; textreq.es_TextFormat = (UBYTE *)text; textreq.es_GadgetFormat = (UBYTE *)gadgets; /* * win may be NULL */ rc = EasyRequestArgs(NULL, &textreq, NULL, ap); va_end(ap); return(rc); } /* * myopenlibrary(): same as OpenLibrary(), but opens a retry-requester * if OpenLibrary() fails, to give the user a chance to * copy the library to libs: and retry * requires request(), see above */ struct Library *myopenlibrary(char *name, unsigned long version) { static char errortext[] = MSG_LIBRARY_OPENERR; struct Library *libptr; long ok = TRUE; do { if (!(libptr = OpenLibrary((UBYTE *)name, version))) { if (IntuitionBase) { ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version); } else ok = FALSE; } } while (!libptr && ok); #ifdef DEBUG printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr); #endif return(libptr); } void main(int argc, char *argv[]) { CxObj *autofilter; CxObj *signalobj; struct Message *msg; long signal; if ((argc > 1) && (*argv[1] == '?')) { /* * display help string */ if (_Backstdout) { Write(_Backstdout, helpstring, sizeof(helpstring) - 1l); Close(_Backstdout); } return; } else if (argc && _Backstdout) Close(_Backstdout); /* * open required libraries first */ if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) { if (CxBase = myopenlibrary("commodities.library", 37l)) { if (IconBase = myopenlibrary("icon.library", 37l)) { if (LayersBase = myopenlibrary("layers.library", 37l)) { /* * create tooltypes array (requires icon.library open!!!) */ tooltypes = (char **)ArgArrayInit(argc, argv); /* * create our message port */ if (cxport = CreateMsgPort()) { cxsigflag = 1l << cxport->mp_SigBit; /* * set up some broker data */ newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY); newbroker.nb_Port = cxport; if (broker = CxBroker(&newbroker, NULL)) { if (autofilter = CxFilter(NULL)) { AttachCxObj(broker, autofilter); SetFilterIX(autofilter, &autoix); if ((signal = (long)AllocSignal(-1)) != -1) { customsigflag = 1 << signal; if (mytask = FindTask(NULL)) { if (signalobj = CxSignal(mytask, signal)) { AttachCxObj(autofilter, signalobj); if (!CxObjError(autofilter)) { /* * activate our commodity */ ActivateCxObj(broker, 1l); /* * now watch our numerous ports */ processmessages(); } /* if !CxObjError() */ } /* if signalobj */ } /* if mytask */ customsigflag = 0l; FreeSignal(signal); } /* if signal */ } /* if autofilter */ #ifdef DEBUG else printf("main(): autofilter = CxFilter() failed!\n"); #endif DeleteCxObjAll(broker); } /* if broker */ #ifdef DEBUG else printf("main(): CxBroker() failed!\n"); #endif /* * delete our message port after replying all pending messages */ while (msg = GetMsg(cxport)) ReplyMsg(msg); DeleteMsgPort(cxport); } /* if cxport */ #ifdef DEBUG else printf("main(): CraeteMsgPort() failed!\n"); #endif ArgArrayDone(); CloseLibrary(LayersBase); } /* if LayersBase */ CloseLibrary(IconBase); } /* if IconBase */ CloseLibrary(CxBase); } /* if CxBase */ CloseLibrary((struct Library *)IntuitionBase); } /* if IntuitionBase */ } /* main() */ void processmessages(void) { struct Message *msg; unsigned long sigreceived; unsigned long msgtype; unsigned long msgid; unsigned short quit = FALSE; while (!quit) { sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | customsigflag); #ifdef DEBUG printf("processmessages(): signal received\n"); #endif if (sigreceived & customsigflag) activate(); if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE; if (sigreceived & cxsigflag) { while (msg = (struct Message *)GetMsg(cxport)) { msgid = CxMsgID((CxMsg *)msg); msgtype = CxMsgType((CxMsg *)msg); ReplyMsg(msg); switch (msgtype) { case CXM_COMMAND: switch (msgid) { case CXCMD_UNIQUE: case CXCMD_KILL: quit = TRUE; break; case CXCMD_DISABLE: ActivateCxObj(broker, 0l); break; case CXCMD_ENABLE: ActivateCxObj(broker, 1l); break; } break; } /* switch msgtype */ } /* while CxMsg */ } /* if (sigreceived & cxsigflag) */ } /* while !quit */ ActivateCxObj(broker, 0l); } /* * commodity functions */ void activate(void) { register struct Screen *scr; register struct Window *win; register struct Layer *layer; unsigned long lock; /* * here we go: find screen */ lock = LockIBase(0l); for (scr = IntuitionBase->FirstScreen; scr && (scr->TopEdge > 0) && (scr->MouseY < 0); scr = scr->NextScreen); if (scr) { #ifdef DEBUG printf("AutoActivate(): scr = 0x%lx\n", scr); #endif /* * get layer */ layer = WhichLayer(&scr->LayerInfo, (long)scr->MouseX, (long)scr->MouseY); #ifdef DEBUG printf("AutoActivate(): layer = 0x%lx\n", layer); #endif if (layer && layer != scr->BarLayer) { /* * get window ptr */ win = (struct Window *)layer->Window; #ifdef DEBUG printf("AutoActivate(): win = 0x%lx\n", win); #endif if (win && win != IntuitionBase->ActiveWindow && !IntuitionBase->ActiveWindow->FirstRequest) { #ifdef DEBUG printf("AutoActivate(): ActivateWindow(0x%lx)\n", win); #endif UnlockIBase(lock); ActivateWindow(win); } /* if win */ else UnlockIBase(0l); } /* if layer */ else UnlockIBase(0l); } /* if scr */ else UnlockIBase(0l); }