home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
563.lha
/
toBack&Front_v1.09
/
toBack&Front.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-14
|
27KB
|
730 lines
/*
* toBack&Front.c
*
* Commodity
*
* Author: Stefan Sticht
*
* Copyright: source is public domain, no copyright
*
* Version history:
*
* V1.00 initial release
* V1.01 some minor changes
* V1.02 changed myparseix for commodities.library 37.27
* uses now utility.library's Stricmp()
* V1.03 added some LockIBase()
* V1.04 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)
* TT_BACK_REMOVED never got parsed (nobody noticed?)
* V1.05 removed bug that caused an Intuition lock up under certain circumstances;
* some other small changes
* V1.06 removed error where I called UnlockIBase(0l) instead of UnlockIBase(lock)
* V1.07 cosmetic changes
* V1.08 Sat 12-Oct-91 Stefan Sticht backorfront changed; another try to prevent lock ups
* V1.09 Sat 12-Oct-91 Stefan Sticht changed startup to make program smaller,
* changed argument parsing,
* changed default action for toback,
* added (back|front)_leftbuttonup
*/
#define VERSION "V1.09"
/********************************************************************
* interfacing *
********************************************************************/
/*
* include files
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <devices/inputevent.h>
#include <intuition/intuitionbase.h>
#include <libraries/commodities.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <clib/alib_protos.h>
#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/icon_protos.h>
#include <clib/intuition_protos.h>
#include <clib/layers_protos.h>
#include <pragmas/commodities_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/layers_pragmas.h>
#ifdef DEBUG
#define printf KPrintF
#include <clib/dlib_protos.h>
#endif
/*
* prototypes
*/
struct Library *myopenlibrary(char *name, unsigned long version);
void backorfront(unsigned short mode);
void processmessages(void);
/* located in myparseix.c */
long myparseix(char *description, IX *ix);
/*
* global data
*
* libraries opened by startup code; basepointers needed by function pragmas
*/
extern struct Library *DOSBase;
extern struct Library *SysBase;
extern struct WBStartup *WBenchMsg;
/*
* Disable SAS/C CTRL/C handling
*/
void chkabort(void) {}
/********************************************************************
* global data *
********************************************************************/
/*
* definition of messages
*/
#if defined(GERMAN)
/*
* Wenn jemand bessere Übersetzungsvorschläge hat, soll er mir die bitte mitteilen!
* (This is german. If you don't understand, doesn't matter (belongs to the german version)
*/
#define COM_DESCR "Fenster o. Schirm nach hinten o. vorne"
#define COM_NAME "toBack&Front"
#define MSG_ERROR_IX "Die Beschreibung für %s ist fehlerhaft!"
#define MSG_ERROR_LIBRARY "Die %s (V%ld+) kann nicht geöffnet werden!"
#define RESUME_GADGETS "Weiter"
#define RETRY_GADGETS "Wiederholen|Abbrechen"
#define OPT_BACK_ACTION "BACK_AKTION"
#define OPT_BACK_CLICKS "BACK_CLICKS"
#define OPT_BACK_REMOVE "BACK_REMOVE"
#define OPT_BACK_LEFTBUTTONUP "BACK_LEFTBUTTONUP"
#define OPT_FRONT_ACTION "FRONT_AKTION"
#define OPT_FRONT_CLICKS "FRONT_CLICKS"
#define OPT_FRONT_REMOVE "FRONT_REMOVE"
#define OPT_FRONT_LEFTBUTTONUP "FRONT_LEFTBUTTONUP"
#define BY "von"
#else
#define COM_DESCR "Window or screen to back or front"
#define COM_NAME "toBack&Front"
#define MSG_ERROR_IX "Error in description for %s!"
#define MSG_ERROR_LIBRARY "%s (V%ld+) can't be opened!"
#define RESUME_GADGETS "Resume"
#define RETRY_GADGETS "Retry|Cancel"
#define OPT_BACK_ACTION "BACK_ACTION"
#define OPT_BACK_CLICKS "BACK_CLICKS"
#define OPT_BACK_LEFTBUTTONUP "BACK_LEFTBUTTONUP"
#define OPT_BACK_REMOVE "BACK_REMOVE"
#define OPT_FRONT_ACTION "FRONT_ACTION"
#define OPT_FRONT_CLICKS "FRONT_CLICKS"
#define OPT_FRONT_REMOVE "FRONT_REMOVE"
#define OPT_FRONT_LEFTBUTTONUP "FRONT_LEFTBUTTONUP"
#define BY "by"
#endif
#define COM_TITLE COM_NAME " " VERSION
#define OPT_CX_PRIORITY "CX_PRIORITY"
#define DEF_BACK_ACTION "rawmouse leftbutton rbutton rbuttoncode"
#define DEF_BACK_CLICKS 1
#define DEF_BACK_REMOVE FALSE
#define DEF_BACK_LEFTBUTTONUP FALSE
#define DEF_FRONT_ACTION "rawmouse leftbutton lbuttoncode"
#define DEF_FRONT_CLICKS 2
#define DEF_FRONT_REMOVE FALSE
#define DEF_FRONT_LEFTBUTTONUP FALSE
#define WARN 5
#define ERROR 10
#define FAIL 20
#define FRONT 1
#define BACK 2
/*
* library base pointers
*/
struct IntuitionBase *IntuitionBase;
struct Library *CxBase;
struct Library *IconBase;
struct Library *LayersBase;
/*
* message ports
*/
struct MsgPort *cxport;
unsigned long cxsigflag;
/*
* programtitle and version for Version command
*/
char version[] ="\0$VER: " COM_TITLE " " BY " Stefan Sticht";
#define TITLE_OFFSET 7l
/*
* command line arguments for ReadArgs()
*/
#define TEMPLATE OPT_CX_PRIORITY "/K/N,"\
OPT_BACK_ACTION "/K," OPT_BACK_CLICKS "/K/N," OPT_BACK_REMOVE "/S,"\
OPT_BACK_LEFTBUTTONUP "/S,"\
OPT_FRONT_ACTION "/K," OPT_FRONT_CLICKS "/K/N," OPT_FRONT_REMOVE "/S,"\
OPT_FRONT_LEFTBUTTONUP "/S"
#define OPTN_CX_PRIORITY 0
#define OPTN_BACK_ACTION 1
#define OPTN_BACK_CLICKS 2
#define OPTN_BACK_REMOVE 3
#define OPTN_BACK_LEFTBUTTONUP 4
#define OPTN_FRONT_ACTION 5
#define OPTN_FRONT_CLICKS 6
#define OPTN_FRONT_REMOVE 7
#define OPTN_FRONT_LEFTBUTTONUP 8
#define OPTN_COUNT 9
long options[OPTN_COUNT];
/*
* number of clicks required
*/
unsigned char requiredbackclicks = DEF_BACK_CLICKS;
unsigned char requiredfrontclicks = DEF_FRONT_CLICKS;
unsigned char back_leftbuttonup = DEF_BACK_LEFTBUTTONUP;
unsigned char front_leftbuttonup = DEF_FRONT_LEFTBUTTONUP;
/*
* our broker
*/
CxObj *broker;
struct NewBroker newbroker = {
NB_VERSION, /* BYTE nb_Version */
COM_NAME, /* BYTE *nb_Name */
&version[TITLE_OFFSET], /* 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 backix = {
IX_VERSION, /* UBYTE ix_version */
0, /* UBYTE ix_Class */
0, /* UWORD ix_Code */
0, /* UWORD ix_CodeMask */
0, /* UWORD ix_Qualifier */
0, /* UWORD ix_QualMask */
0 /* UWORD ix_QualSame */
};
IX frontix = {
IX_VERSION, /* UBYTE ix_version */
0, /* UBYTE ix_Class */
0, /* UWORD ix_Code */
0, /* UWORD ix_CodeMask */
0, /* UWORD ix_Qualifier */
0, /* UWORD ix_QualMask */
0 /* UWORD ix_QualSame */
};
struct InputEvent ievent = {
NULL, /* struct InputEvent *ie_NextEvent */
IECLASS_RAWMOUSE, /* UBYTE ie_Class; */
0, /* UBYTE ie_SubClass; */
IECODE_LBUTTON | IECODE_UP_PREFIX, /* UWORD ie_Code; */
IEQUALIFIER_RELATIVEMOUSE, /* UWORD ie_Qualifier; */
{0, 0},
{0, 0},
};
/********************************************************************
* 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_ERROR_LIBRARY;
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);
return(libptr);
}
void _main(char *line)
{
CxObj *backfilter = NULL;
CxObj *frontfilter = NULL;
CxObj *obj;
long error;
struct Message *msg;
struct Task *mytask;
unsigned long rc = 0;
unsigned char backremove = DEF_BACK_REMOVE;
unsigned char frontremove = DEF_FRONT_REMOVE;
char startpri;
if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
if (CxBase = myopenlibrary("commodities.library", 37l)) {
if (!WBenchMsg) {
/*
* started from Shell
*/
struct RDArgs *args;
/*
* change name of program
*/
SetProgramName(COM_NAME);
/*
* display banner
*/
PutStr(&version[TITLE_OFFSET]); PutStr("\n");
/*
* parse command line
*/
if (args = ReadArgs((UBYTE *)TEMPLATE, options, NULL)) {
if (options[OPTN_CX_PRIORITY]) newbroker.nb_Pri = (BYTE)*((long *)options[OPTN_CX_PRIORITY]);
if (options[OPTN_BACK_ACTION]) error = myparseix((char *)options[OPTN_BACK_ACTION], &backix);
else error = myparseix(DEF_BACK_ACTION, &backix);
if (error) {
char *s = OPT_BACK_ACTION;
VPrintf(MSG_ERROR_IX, (long *)&s);
PutStr("\n");
rc = ERROR;
}
if (options[OPTN_BACK_CLICKS]) requiredbackclicks = (unsigned char)*((long *)options[OPTN_BACK_CLICKS]);
if (options[OPTN_BACK_REMOVE]) backremove = TRUE;
if (options[OPTN_BACK_LEFTBUTTONUP] &&
(backix.ix_Code & ~IECODE_LBUTTON) &&
(backix.ix_Qualifier & IEQUALIFIER_LEFTBUTTON)) back_leftbuttonup = TRUE;
if (options[OPTN_FRONT_ACTION]) error = myparseix((char *)options[OPTN_FRONT_ACTION], &frontix);
else error = myparseix(DEF_FRONT_ACTION, &frontix);
if (error) {
char *s = OPT_FRONT_ACTION;
VPrintf(MSG_ERROR_IX, (long *)&s);
PutStr("\n");
rc = ERROR;
}
if (options[OPTN_FRONT_CLICKS]) requiredfrontclicks = (unsigned char)*((long *)options[OPTN_FRONT_CLICKS]);
if (options[OPTN_FRONT_REMOVE]) frontremove = TRUE;
if (options[OPTN_FRONT_LEFTBUTTONUP] &&
(frontix.ix_Code & ~IECODE_LBUTTON) &&
(frontix.ix_Qualifier & IEQUALIFIER_LEFTBUTTON)) front_leftbuttonup = TRUE;
/*
* we don't look anylonger at args, so we can release them
*/
FreeArgs(args);
}
else {
/*
* error parsing args
*/
PrintFault(IoErr(), NULL);
rc = WARN;
}
}
else {
BPTR olddir = -1l;
char *tooltype;
char **tooltypesarray;
struct DiskObject *diskobj;
struct Library *IconBase;
struct WBArg *wbarg;
if (IconBase = myopenlibrary(ICONNAME, 37l)) {
if (wbarg = &(WBenchMsg->sm_ArgList)[WBenchMsg->sm_NumArgs - 1l]) {
if (wbarg->wa_Name) {
if (wbarg->wa_Lock) olddir = CurrentDir(wbarg->wa_Lock);
if (diskobj = GetDiskObject(wbarg->wa_Name)) {
tooltypesarray = diskobj->do_ToolTypes;
if (tooltype = FindToolType(tooltypesarray, OPT_CX_PRIORITY)) newbroker.nb_Pri = (BYTE)atol(tooltype);
if (tooltype = FindToolType(tooltypesarray, OPT_BACK_ACTION)) error = myparseix(tooltype, &backix);
else error = myparseix(DEF_BACK_ACTION, &backix);
if (error) {
request(COM_NAME, RESUME_GADGETS, MSG_ERROR_IX, OPT_BACK_ACTION);
rc = ERROR;
}
if (tooltype = FindToolType(tooltypesarray, OPT_BACK_CLICKS)) requiredbackclicks = (unsigned char)atol(tooltype);
if (FindToolType(tooltypesarray, OPT_BACK_REMOVE)) backremove = TRUE;
if (FindToolType(tooltypesarray, OPT_BACK_LEFTBUTTONUP) &&
(backix.ix_Code & ~IECODE_LBUTTON) &&
(backix.ix_Qualifier & IEQUALIFIER_LEFTBUTTON)) back_leftbuttonup = TRUE;
if (tooltype = FindToolType(tooltypesarray, OPT_FRONT_ACTION)) error = myparseix(tooltype, &frontix);
else error = myparseix(DEF_FRONT_ACTION, &frontix);
if (error) {
request(COM_NAME, RESUME_GADGETS, MSG_ERROR_IX, OPT_FRONT_ACTION);
rc = ERROR;
}
if (tooltype = FindToolType(tooltypesarray, OPT_FRONT_CLICKS)) requiredfrontclicks = (unsigned char)atol(tooltype);
if (FindToolType(tooltypesarray, OPT_FRONT_REMOVE)) frontremove = TRUE;
if (FindToolType(tooltypesarray, OPT_FRONT_LEFTBUTTONUP) &&
(frontix.ix_Code & ~IECODE_LBUTTON) &&
(frontix.ix_Qualifier & IEQUALIFIER_LEFTBUTTON)) front_leftbuttonup = TRUE;
FreeDiskObject(diskobj);
} /* if diskobj */
if (olddir != -1l) CurrentDir(olddir);
} /* if wbarg->wa_Name */
} /* if wbarg */
CloseLibrary(IconBase);
} /* if IconBase */
} /* if WBenchMsg */
if ((CheckSignal(SIGBREAKF_CTRL_C) == DOSFALSE) &&
!rc && (LayersBase = myopenlibrary("layers.library", 37l))) {
if (frontix.ix_Class || backix.ix_Class) {
/*
* create our message port
*/
if (cxport = CreateMsgPort()) {
cxsigflag = 1l << cxport->mp_SigBit;
newbroker.nb_Port = cxport;
/*
* open broker
*/
if (broker = CxBroker(&newbroker, NULL)) {
if (backix.ix_Class && (backfilter = CxFilter(NULL))) {
SetFilterIX(backfilter, &backix);
AttachCxObj(broker, backfilter);
if (obj = CxSender(cxport, BACK)) {
AttachCxObj(backfilter, obj);
if (backremove && (obj = CxTranslate(NULL))) AttachCxObj(backfilter, obj);
}
}
if (frontix.ix_Class && (frontfilter = CxFilter(NULL))) {
SetFilterIX(frontfilter, &frontix);
AttachCxObj(broker, frontfilter);
if (obj = CxSender(cxport, FRONT)) {
AttachCxObj(frontfilter, obj);
if (frontremove && (obj = CxTranslate(NULL))) AttachCxObj(frontfilter, obj);
}
}
if (!CxObjError(broker) &&
((frontfilter && !CxObjError(frontfilter)) ||
(backfilter && !CxObjError(backfilter)))) {
if (mytask = FindTask(NULL)) {
/*
* change priority of our process
*/
startpri = SetTaskPri(mytask, 21l);
/*
* activate our commodity
*/
ActivateCxObj(broker, 1l);
/*
* now watch our port
*/
processmessages();
/*
* change to old priority
*/
SetTaskPri(mytask, (long)startpri);
} /* if mytask */
} /* if !CxObjError() */
DeleteCxObjAll(broker);
} /* if broker */
/*
* delete our message port after replying all pending messages
*/
while (msg = GetMsg(cxport)) ReplyMsg(msg);
DeleteMsgPort(cxport);
} /* if cxport */
#ifdef DEBUG
else printf("main(): CreateMsgPort() failed!\n");
#endif
} /* if (frontaction || backaction) */
CloseLibrary(LayersBase);
} /* if LayersBase */
CloseLibrary(CxBase);
} /* if CxBase */
CloseLibrary((struct Library *)IntuitionBase);
} /* if IntuitionBase */
_exit(rc);
} /* main() */
void processmessages(void)
{
static unsigned long lastfrontmicros = 0l;
static unsigned long lastfrontsecs = 0l;
static unsigned long lastbackmicros = 0l;
static unsigned long lastbacksecs = 0l;
static unsigned char frontclicks = 0;
static unsigned char backclicks = 0;
struct InputEvent *ie;
struct Message *msg;
unsigned long sigreceived;
unsigned long msgtype;
unsigned long msgid;
unsigned long micros;
unsigned long secs;
unsigned char quit = FALSE;
if (requiredfrontclicks == 1) frontclicks = 1;
if (requiredbackclicks == 1) backclicks = 1;
while (!quit) {
sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
#ifdef DEBUG
printf("processmessages(): signal received\n");
#endif
if (sigreceived & cxsigflag) {
while (msg = (struct Message *)GetMsg(cxport)) {
msgid = CxMsgID((CxMsg *)msg);
msgtype = CxMsgType((CxMsg *)msg);
if ((msgtype == CXM_IEVENT) &&
(ie = (struct InputEvent *)CxMsgData((CxMsg *)msg))) {
/*
* copy the interesting data of the inputevent
*/
secs = ie->ie_TimeStamp.tv_secs;
micros = ie->ie_TimeStamp.tv_micro;
}
ReplyMsg(msg);
switch (msgtype) {
case CXM_IEVENT:
switch (msgid) {
case FRONT:
if (requiredfrontclicks > 1) {
if (DoubleClick(lastfrontsecs, lastfrontmicros, secs, micros))
frontclicks++;
else frontclicks = 1;
lastfrontsecs = secs;
lastfrontmicros = micros;
}
if (frontclicks == requiredfrontclicks) {
backorfront(FRONT);
if (requiredfrontclicks > 1) frontclicks = 0;
}
break;
case BACK:
if (requiredbackclicks > 1) {
if (DoubleClick(lastbacksecs, lastbackmicros, secs, micros))
backclicks++;
else backclicks = 1;
lastbacksecs = secs;
lastbackmicros = micros;
}
if (backclicks == requiredbackclicks) {
backorfront(BACK);
if (requiredbackclicks > 1) backclicks = 0;
}
break;
}
case CXM_COMMAND:
switch (msgid) {
case CXCMD_UNIQUE:
case CXCMD_KILL:
quit = TRUE;
case CXCMD_DISABLE:
ActivateCxObj(broker, 0l);
break;
case CXCMD_ENABLE:
ActivateCxObj(broker, 1l);
break;
}
break;
} /* switch msgtype */
} /* while CxMsg */
} /* if (sigreceived & cxsigflag) */
if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
} /* while !quit */
ActivateCxObj(broker, 0l);
}
void backorfront(unsigned short mode)
{
struct Screen *scr;
struct Layer *layer;
struct Window *win;
Forbid();
/*
* here we go: find screen
*/
for (scr = IntuitionBase->FirstScreen;
scr && (scr->TopEdge > 0) && (scr->MouseY < 0);
scr = scr->NextScreen);
if (scr) {
if (layer = WhichLayer(&scr->LayerInfo, (long)scr->MouseX, (long)scr->MouseY)) {
if ((layer != scr->BarLayer) &&
(win = (struct Window *)layer->Window) &&
!(win->Flags & BACKDROP)) {
if (win->NextWindow || win->WScreen->FirstWindow != win) {
if (mode == BACK) {
WindowToBack(win);
if (back_leftbuttonup && win->WLayer->LayerInfo->LockLayersCount) AddIEvents(&ievent);
}
else {
WindowToFront(win);
if (front_leftbuttonup && win->WLayer->LayerInfo->LockLayersCount) AddIEvents(&ievent);
}
}
} /* if win */
else {
/*
* screen to back/front
*/
if (mode == BACK) {
if (back_leftbuttonup && (layer == scr->BarLayer)) AddIEvents(&ievent);
ScreenToBack(scr);
}
else if (scr != IntuitionBase->FirstScreen) {
if (front_leftbuttonup && (layer == scr->BarLayer)) AddIEvents(&ievent);
ScreenToFront(scr);
}
}
} /* if layer */
} /* if scr */
Permit();
}