home *** CD-ROM | disk | FTP | other *** search
- /*
- * WindowShuffle.c
- *
- * Commodity
- *
- * Author: Stefan Sticht
- *
- * Copyright: source is public domain, no copyright
- *
- * Version history:
- *
- * V1.00 initial release
- * V1.02 recompiled with main.c V1.02
- * V1.03 completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
- * V1.04 now refuses to activate windows specified with REFUSE
- * second pair of hotkeys for only Activate without WindowToFront()
- * changed Priority to 21 to block out intuition for safety reasons
- * V1.05 some really minor changes
- * V1.06 recompiled with changed (for 68040 compatiblity) cback.o
- * removed error when started from WB: taskpri wasn't set to 21
- * thanks to Uwe R÷hm
- * V1.07 small changes, moved UnlockIBase() in processmessages()
- * V1.08 Changes by Andreas M. Kirchitz, see README.amk:
- * new option SETMOUSE,
- * changed break handling to work with SAS/C 6
- */
-
- #define VERSION "1.08"
-
- /********************************************************************
- * interfacing *
- ********************************************************************/
-
- /*
- * include files
- */
-
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/commodities.h>
-
- #include <clib/alib_protos.h>
- #include <clib/commodities_protos.h>
- #include <pragmas/commodities_pragmas.h>
- #include <clib/dos_protos.h>
- #include <pragmas/dos_pragmas.h>
- #include <clib/exec_protos.h>
- #include <pragmas/exec_pragmas.h>
- #include <clib/intuition_protos.h>
- #include <pragmas/intuition_pragmas.h>
-
- /* AMK: input.device stuff */
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <intuition/screens.h>
- /* AMK: input.device stuff */
-
- #ifdef DEBUG
- #define printf KPrintF
- #include <clib/dlib_protos.h>
- #endif
-
- /*
- * prototypes
- */
- long request(char *title, char *gadgets, char *text, ...);
- struct Library *myopenlibrary(char *name, unsigned long version);
- struct Window *lastwindow(struct Window *win);
- struct Window *nextwindow(struct Window *win);
- struct Window *prevwindow(struct Window *win);
- void *retryallocmem(unsigned long size, long mode);
- void processmessages(void);
-
- /* AMK: set mouse pointer */
- void setnewmousepos(struct Window *win);
- /* AMK: set mouse pointer */
-
- /*
- * 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) {}
-
- /* AMK: SAS/C 6.x */
- #ifdef __SASC
- __regargs int _CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
- __regargs int __chkabort(void) { return(0); } /* really */
- #endif
- /* AMK: SAS/C 6.x */
-
- /********************************************************************
- * global data *
- ********************************************************************/
-
- #define TT_PREVAC "PREV_ACTIVE"
- #define TT_NEXTAC "NEXT_ACTIVE"
- #define TT_PREVBO "PREV_BOTH"
- #define TT_NEXTBO "NEXT_BOTH"
-
- /*
- * definition of all messages (multi language support not completed yet)
- */
- #ifdef GERMAN
-
- #define RETRY_GADGETS "Wiederholen|Abbrechen"
- #define RESUME_GADGETS "Weiter"
- #define MSG_OUTOFMEM "Leider ein Speicherblock von %ld bytes\nnicht alloziert werden!"
- #define MSG_LIBRARY_OPENERR "Die %s (V%ld+) kann nicht ge÷ffnet werden!"
- #define COM_NAME "Fensterln"
- #define COM_DESCR "NΣchstes/letztes Fenster aktivieren"
- #define TT_BACKDROP "BACKDROP"
- #define TT_NOWINTITLE "OHNETITEL"
- #define TT_REFUSE "DIESENICHT"
- /* AMK: set mouse pointer */
- #define TT_SETMOUSE "SETZEMAUS"
- /* AMK: set mouse pointer */
- #define MSG_REFUSE_TOO_COMPLEX "Leider mu▀ " TT_REFUSE " ignoriert werden,\nda der Ausdruck zu komplex ist."
- #define NO "NEIN"
- #define YES "JA"
-
- #else
-
- #define RETRY_GADGETS "Retry|Cancel"
- #define RESUME_GADGETS "Resume"
- #define MSG_OUTOFMEM "Failure allocting %ld bytes of memory!"
- #define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!"
- #define COM_NAME "WindowShuffle"
- #define COM_DESCR "Activate next/previous window"
- #define TT_BACKDROP "BACKDROP"
- #define TT_NOWINTITLE "WITHOUTTITLE"
- #define TT_REFUSE "REFUSE"
- /* AMK: set mouse pointer */
- #define TT_SETMOUSE "SETMOUSE"
- /* AMK: set mouse pointer */
- #define MSG_REFUSE_TOO_COMPLEX TT_REFUSE " will be ignored\nas the pattern is too complex!"
- #define YES "YES"
- #define NO "NO"
-
- #endif
-
- #define COM_TITLE COM_NAME " " VERSION
- #define CX_PRIORITY "CX_PRIORITY"
- #define DEF_CX_PRIORITY 0
-
- #define DEF_TT_PREVAC "lcommand lshift j"
- #define DEF_TT_NEXTAC "lcommand lshift k"
- #define DEF_TT_PREVBO "lcommand j"
- #define DEF_TT_NEXTBO "lcommand k"
- #define DEF_TT_BACKDROP NO
- #define DEF_TT_NOWINTITLE NO
- #define DEF_TT_REFUSE ""
- /* AMK: set mouse pointer */
- #define DEF_TT_SETMOUSE NO
- /* AMK: set mouse pointer */
-
- /*
- * data for cback.o
- */
- long _stack = 4096l;
- char *_procname = COM_NAME;
- #define PRIORITY 21l
- long _priority = PRIORITY;
- long _BackGroundIO = 1;
- extern BPTR _Backstdout;
-
- /*
- * library base pointers
- */
- struct IntuitionBase *IntuitionBase;
- struct Library *CxBase;
- struct Library *IconBase;
-
- /*
- * message port
- */
- struct MsgPort *cxport = NULL;
-
- /*
- * signal flag
- */
- 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 "=<Zahl>] [" TT_NEXTAC "=<Zeichenkette>] [" TT_PREVAC "=<Zeichenkette>] ["\
- TT_NEXTBO "=<Zeichenkette>] [" TT_PREVBO "=<Zeichenkette>] [" TT_BACKDROP "=" YES "|" NO "] ["\
- TT_NOWINTITLE "=" YES "|" NO "] [" TT_SETMOUSE "=" YES "|" NO "] [" TT_REFUSE "=<Zeichenkette>]\n";
- #else
- char helpstring[] =
- "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
- "Usage: " COM_NAME " ["\
- CX_PRIORITY "=<number>] [" TT_NEXTAC "=<string>] [" TT_PREVAC "=<string>] ["\
- TT_NEXTBO "=<string>] [" TT_PREVBO "=<string>] [" TT_BACKDROP "=" YES "|" NO "] ["\
- TT_NOWINTITLE "=" YES "|" NO "] [" TT_SETMOUSE "=" YES "|" NO "] [" TT_REFUSE "=<string>]\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 */
- };
-
- #define NEXTAC 1
- #define PREVAC 2
- #define NEXTBO 3
- #define PREVBO 4
-
- /*
- * pointer to refuse tokens
- */
- char *refusetokens = NULL;
- /*
- * booleans for activation of backdrop windows and windows w/o title
- */
- unsigned short backdrop;
- unsigned short nowintitle;
- unsigned short setmouse;
-
- /********************************************************************
- * 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 *retryallocmem(unsigned long size, long mode)
- {
- void *addr;
-
- do {
-
- if (!(addr = AllocMem(size, mode))) {
- if (!(request(COM_NAME ":", RETRY_GADGETS, MSG_OUTOFMEM, size))) return(NULL);
- }
-
- } while (!addr);
-
- return(addr);
- }
-
- void main(int argc, char *argv[])
- {
- CxObj *nextacfilter = NULL;
- CxObj *prevacfilter = NULL;
- CxObj *nextbofilter = NULL;
- CxObj *prevbofilter = NULL;
- struct Message *msg;
- char *refuse;
- char *nextackey;
- char *prevackey;
- char *nextbokey;
- char *prevbokey;
- unsigned long size = 0l;
-
- 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);
- else if (!argc) {
- /*
- * started from Workbench: cback.o doesn't change our priority,
- * so we do here
- */
- struct Task *mytask;
- if (mytask = FindTask(NULL)) SetTaskPri(mytask, PRIORITY);
- }
-
- /*
- * open required libraries first
- */
- if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
-
- if (CxBase = myopenlibrary("commodities.library", 37l)) {
-
- if (IconBase = myopenlibrary("icon.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 ((nextackey = ArgString(tooltypes, TT_NEXTAC, DEF_TT_NEXTAC)) &&
- *nextackey) {
-
- if (nextacfilter = HotKey(nextackey, cxport, NEXTAC))
- AttachCxObj(broker, nextacfilter);
-
- } /* if nextackey */
-
- if ((prevackey = ArgString(tooltypes, TT_PREVAC, DEF_TT_PREVAC)) &&
- *prevackey) {
-
- if (prevacfilter = HotKey(prevackey, cxport, PREVAC))
- AttachCxObj(broker, prevacfilter);
-
- } /* if prevackey */
-
- if ((nextbokey = ArgString(tooltypes, TT_NEXTBO, DEF_TT_NEXTBO)) &&
- *nextbokey) {
-
- if (nextbofilter = HotKey(nextbokey, cxport, NEXTBO))
- AttachCxObj(broker, nextbofilter);
-
- } /* if nextbokey */
-
- if ((prevbokey = ArgString(tooltypes, TT_PREVBO, DEF_TT_PREVBO)) &&
- *prevbokey) {
-
- if (prevbofilter = HotKey(prevbokey, cxport, PREVBO))
- AttachCxObj(broker, prevbofilter);
-
- } /* if prevbokey */
-
- backdrop = (strcmpi((char *)ArgString(tooltypes, TT_BACKDROP, DEF_TT_BACKDROP),
- YES)) ? FALSE : TRUE;
-
- nowintitle = (strcmpi((char *)ArgString(tooltypes, TT_NOWINTITLE, DEF_TT_NOWINTITLE),
- YES)) ? FALSE : TRUE;
-
- refuse = (char *)ArgString(tooltypes, TT_REFUSE, DEF_TT_REFUSE);
-
- /* AMK: set mouse pointer */
- setmouse = (strcmpi((char *)ArgString(tooltypes, TT_SETMOUSE, DEF_TT_SETMOUSE),
- YES)) ? FALSE : TRUE;
- /* AMK: set mouse pointer */
-
- #ifdef DEBUG
- if (refuse) printf("WindowShuffle: refuse = %s\n", refuse);
- #endif
-
- if (*refuse && (size = (strlen(refuse) << 1)) &&
- (refusetokens = retryallocmem(size, 0l))) {
-
- #ifdef DEBUG
- printf("WindowShuffle: size = %ld, refusetokens = 0x%lx\n", size, refusetokens);
- #endif
-
- if (ParsePattern(refuse, refusetokens, size) == -1l)
- request(COM_NAME ":", RESUME_GADGETS, MSG_REFUSE_TOO_COMPLEX);
-
- #ifdef DEBUG
- printf("WindowShuffle: refusetokens = %s\n", refusetokens);
- #endif
-
- }
-
- if ((nextacfilter && !CxObjError(nextacfilter)) ||
- (prevacfilter && !CxObjError(prevacfilter)) ||
- (nextbofilter && !CxObjError(nextbofilter)) ||
- (prevbofilter && !CxObjError(prevbofilter))) {
- /*
- * activate our commodity
- */
- ActivateCxObj(broker, 1l);
- /*
- * now watch our numerous ports
- */
- processmessages();
-
- } /* if !CxObjError() */
-
- DeleteCxObjAll(broker);
-
- if (refusetokens) FreeMem(refusetokens, size);
-
- } /* 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(IconBase);
- } /* if IconBase */
-
- CloseLibrary(CxBase);
- } /* if CxBase */
-
- CloseLibrary((struct Library *)IntuitionBase);
- } /* if IntuitionBase */
-
- } /* main() */
-
- #define PREV 1
- #define TOF 2
- #define AC 4
- #define BO 6
-
- void processmessages(void)
- {
- struct Window *win;
- struct Message *msg;
- unsigned long sigreceived;
- unsigned long msgtype;
- unsigned long msgid;
- unsigned long lock;
- unsigned short quit = FALSE;
- unsigned char mode;
-
- while (!quit) {
-
- sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
-
- #ifdef DEBUG
- printf("processmessages(): signal received\n");
- #endif
-
- 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_IEVENT:
- mode = 0;
- switch (msgid) {
-
- case PREVAC: mode = PREV;
- case NEXTAC: mode |= AC;
- break;
-
- case PREVBO: mode = PREV;
- case NEXTBO: mode |= BO;
- break;
-
- } /* switch msgid */
-
- lock = LockIBase(0l);
- if (mode & PREV) {
- /*
- * get previous window
- */
- if (!(win = prevwindow(IntuitionBase->ActiveWindow))) {
- /*
- * no prev window; get last window;
- * if last window = backdrop || nowintitle ||
- * refusewindow get predecessor of lastwindow
- */
- if ((win = lastwindow(IntuitionBase->ActiveWindow)) &&
- ((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
- (!nowintitle && !win->Title)) ||
- (refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
- win = prevwindow(win);
- }
- }
- else {
- /*
- * get next window
- */
- if (!(win = nextwindow(IntuitionBase->ActiveWindow))) {
- /*
- * no next window; get first window;
- * if first window = backdrop || nowintitle ||
- * refusewindow get first window->NextWindow
- */
- if ((win = IntuitionBase->ActiveScreen->FirstWindow) &&
- ((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
- (!nowintitle && !win->Title)) ||
- (refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
- win = nextwindow(win);
- }
- }
-
- /*
- * now activate and windowtofront the window if (win != NULL)
- */
- if (win) {
-
- if ((mode & AC) && (win != IntuitionBase->ActiveWindow))
- ActivateWindow(win);
- if ((mode & TOF) && (!(win->Flags & WFLG_BACKDROP)))
- WindowToFront(win);
- }
-
- UnlockIBase(lock);
-
- /* AMK: set mouse pos, does not work while IBase is locked */
- if (win && setmouse) setnewmousepos(win);
- /* AMK: set mouse pos, does not work while IBase is locked */
-
- break;
-
- 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
- *
- * get next window
- */
- struct Window *nextwindow(register struct Window *win)
- {
- register struct Window *w = NULL;
-
- if (win) {
-
- while (!w && win->NextWindow) {
-
- w = win = win->NextWindow;
-
- if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
- (!nowintitle && !w->Title) ||
- (refusetokens && w->Title && MatchPattern(refusetokens, w->Title)))
- w = NULL;
-
- } /* while !w */
-
- } /* if win */
-
- return(w);
- }
-
- /*
- * get previous window
- */
- struct Window *prevwindow(register struct Window *win)
- {
- register struct Window *w = NULL;
-
- if (win) {
-
- while (!w && (win != win->WScreen->FirstWindow)) {
-
- for (w = win->WScreen->FirstWindow; w->NextWindow != win; w = w->NextWindow);
-
- if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
- (!nowintitle && !w->Title) ||
- (refusetokens && w->Title && MatchPattern(refusetokens, w->Title))) {
-
- win = w;
- w = NULL;
-
- }
-
- } /* while !w */
-
- } /* if win */
-
- return(w);
- }
-
- /*
- * get last window
- */
- struct Window *lastwindow(register struct Window *win)
- {
- if (win) {
-
- while (win->NextWindow) win = win->NextWindow;
-
- } /* if win */
-
- return(win);
- }
-
-
-
- /* AMK: set mouse pointer */
- /*
- * set new mouse pointer position
- */
- void setnewmousepos(struct Window *win)
- {
- struct IOStdReq *InputIO;
- struct MsgPort *InputMP;
- struct InputEvent *FakeEvent;
- struct IEPointerPixel *NewPixel;
-
- if (InputMP=CreateMsgPort()) {
- if (FakeEvent=AllocVec(sizeof(struct InputEvent),MEMF_PUBLIC|MEMF_CLEAR)) {
- if (NewPixel=AllocVec(sizeof(struct IEPointerPixel),MEMF_PUBLIC|MEMF_CLEAR)) {
- if (InputIO=CreateIORequest(InputMP,sizeof(struct IOStdReq))) {
- if (!OpenDevice("input.device",NULL,(struct IORequest *)InputIO,NULL)) {
- NewPixel->iepp_Screen = win->WScreen;
- NewPixel->iepp_Position.X = win->LeftEdge;
- NewPixel->iepp_Position.Y = win->TopEdge;
- FakeEvent->ie_EventAddress = (APTR)NewPixel;
- FakeEvent->ie_NextEvent = NULL;
- FakeEvent->ie_Class = IECLASS_NEWPOINTERPOS;
- FakeEvent->ie_SubClass = IESUBCLASS_PIXEL;
- FakeEvent->ie_Code = IECODE_NOBUTTON;
- FakeEvent->ie_Qualifier = NULL;
- InputIO->io_Data = (APTR)FakeEvent;
- InputIO->io_Length = sizeof(struct InputEvent);
- InputIO->io_Command = IND_WRITEEVENT;
- DoIO((struct IORequest *)InputIO);
- CloseDevice((struct IORequest *)InputIO);
- }
- DeleteIORequest(InputIO);
- }
- FreeVec(NewPixel);
- }
- FreeVec(FakeEvent);
- }
- DeleteMsgPort(InputMP);
- }
- }
- /* AMK: set mouse pointer */
-
-