/* * MouseBlanker.c * * Commodity * * Author: Stefan Sticht * * Copyright: source is public domain, no copyright * * Version history: * * V1.00 initial release * V1.03 added window * V1.04 recompiled with window.c V1.01 * V1.05 recompiled with window.c V1.02 * V1.06 recompiled with main.c V1.02 * V1.07 completly rewritten; shared commodity code thrown away; smaller, uses less CPU time * V1.08 uses now Stricmp from utility.library * V1.09 changed parameter parsing * V1.10 changed parameter parsing; introduced an error with V1.09 * V1.11 a minor change * V1.12 replaced menu by gadtools underscores & vanillakeys * added blanking on key option * disables inputevent-filters if not needed * V1.13 added some LockIBase() where needed */ #define VERSION "V1.13" /******************************************************************** * interfacing * ********************************************************************/ /* * include files */ #include #include #include #include #include #include #include #include #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 openwindow(void); struct Gadget * createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width); struct Library *myopenlibrary(char *name, unsigned long version); void __saveds mousemon(void); void __saveds timermon(void); void __saveds keymon(CxMsg *cxm); void changestateofmousepointer(unsigned char blanked); void closewindow(void); void getseconds(void); void processmessages(short window); /* * global data defined in other moduls * * libraries opened by startup code; basepointers needed by function pragmas */ extern struct Library *DOSBase; extern struct Library *SysBase; /* * access to custom chips */ extern struct Custom __far custom; /* * 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 "Mausweg" #define COM_DESCR "Versteckt Mauszeiger" #define MSG_PROJECT "Projekt" #define MSG_SECONDS "_Sekunden:" #define MSG_SECONDS_SCC 'S' #define MSG_KEY "auf _Tastendruck löschen" #define MSG_KEY_SCC 'T' #define MSG_HIDE "_Verstecken" #define MSG_HIDE_SCC 'V' #define MSG_QUIT "_Beenden" #define MSG_QUIT_SCC 'B' #define YES "JA" #define NO "NEIN" #define TT_TIMEOUT "SEKUNDEN" #define TT_KEY "TASTENDRUCK" #else #define RETRY_GADGETS "Retry|Cancel" #define RESUME_GADGETS "Resume" #define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!" #define COM_NAME "MouseBlanker" #define COM_DESCR "Blanks mouse pointer" #define MSG_PROJECT "Project" #define MSG_SECONDS "_Seconds:" #define MSG_SECONDS_SCC 'S' #define MSG_KEY "blank on pressing any _key" #define MSG_KEY_SCC 'K' #define MSG_HIDE "_Hide" #define MSG_HIDE_SCC 'H' #define MSG_QUIT "_Quit" #define MSG_QUIT_SCC 'Q' #define YES "YES" #define NO "NO" #define TT_TIMEOUT "SECONDS" #define TT_KEY "KEYPRESS" #endif #define COM_TITLE COM_NAME " " VERSION #define CX_PRIORITY "CX_PRIORITY" #define DEF_CX_PRIORITY 0 #define CX_POPKEY "CX_POPKEY" #define DEF_CX_POPKEY "" #define CX_POPUP "CX_POPUP" #define DEF_CX_POPUP NO #define DEF_TIMEOUT 3 #define DEF_KEY YES #define POP_KEY_ID 100 #define CCMD_NOP 0 #define CCMD_HIDE 1 #define CCMD_QUIT 2 #define CCMD_SECONDS 3 #define CCMD_KEY 4 #define CCMD_SECONDS_ACTIVATE 5 #define CCMD_KEY_SHORTCUT 6 #define CASE_DIFF ('A' - 'a') /* * data for cback.o */ long _stack = 2048l; char *_procname = COM_NAME; long _priority = 0l; long _BackGroundIO = 1; extern BPTR _Backstdout; /* * library base pointers */ struct IntuitionBase *IntuitionBase; struct Library *CxBase; struct Library *IconBase; struct Library *GadToolsBase; struct Library *GfxBase; struct Library *UtilityBase; /* * our task */ struct Task *mytask = NULL; /* * signal we AllocSignal() in main() */ long signal = -1l; /* * message ports */ struct MsgPort *idcmpport = NULL; struct MsgPort *cxport = NULL; /* * signal flags */ unsigned long customsigflag = 0l; unsigned long cxsigflag = 0l; unsigned long idcmpsigflag = 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 "=] [" CX_POPKEY "=] [" CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=] ["\ TT_KEY "=" YES "|" NO "]\n"; #else char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n" "Usage: " COM_NAME " [" CX_PRIORITY "=] [" CX_POPKEY "=] [" CX_POPUP "=" YES "|" NO "] [" TT_TIMEOUT "=] ["\ TT_KEY "=" YES "|" NO "]\n"; #endif /* * timeout values */ unsigned short timeout; unsigned short timeoutseconds; unsigned short timeoutperiod; unsigned short keypress; #define UNBLANKED 0 #define BLANKED 1 unsigned char blankstatus = UNBLANKED; /* * the tooltypearray */ char **tooltypes; /* * our broker */ CxObj *broker = NULL; CxObj *hotkeyfilter; CxObj *mousefilter; CxObj *timerfilter; CxObj *keyfilter; 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 */ COF_SHOW_HIDE, /* SHORT nb_Flags */ 0, /* BYTE nb_Pri */ NULL, /* struct MsgPort nb_Port */ 0 /* WORD nb_ReservedChannel */ }; IX timerix = { IX_VERSION, /* UBYTE ix_version */ IECLASS_TIMER, /* UBYTE ix_Class */ 0, /* UWORD ix_Code */ 0, /* UWORD ix_CodeMask */ 0, /* UWORD ix_Qualifier */ 0, /* UWORD ix_Qualmask */ 0 /* UWORD ix_QualSame */ }; IX mouseix = { IX_VERSION, /* UBYTE ix_version */ IECLASS_RAWMOUSE, /* UBYTE ix_Class */ 0, /* UWORD ix_Code */ 0, /* UWORD ix_CodeMask */ IEQUALIFIER_RELATIVEMOUSE, /* UWORD ix_Qualifier */ IEQUALIFIER_RELATIVEMOUSE, /* UWORD ix_Qualmask */ 0 /* UWORD ix_QualSame */ }; IX keyix = { 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 */ }; /* * data for our window */ struct Window *win = NULL; APTR vi = NULL; struct Gadget *gadgetlist = NULL; struct Screen *scr = NULL; #define WINDOWTITLE_LEN 63 char windowtitle[WINDOWTITLE_LEN + 1] = COM_TITLE; /* * space for zoomed window pos & size */ WORD zoompos[4]; #define P_WA_Left 0 #define P_WA_Top 1 #define P_WA_Width 2 #define P_WA_Height 3 #define P_WA_Title 6 #define P_WA_PubScreen 7 #define P_WA_Gadgets 8 struct TagItem mywindowtag[] = { WA_Left, 0l, WA_Top, 20l, WA_Width, 400l, WA_Height, 150l, WA_IDCMP, IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_VANILLAKEY, WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP, WA_Title, (ULONG)windowtitle, WA_PubScreen, 0l, WA_Gadgets, 0l, WA_Zoom, (ULONG)zoompos, TAG_END }; char msg_seconds[] = MSG_SECONDS; char msg_key[] = MSG_KEY; char msg_hide[] = MSG_HIDE; char msg_quit[] = MSG_QUIT; /* * gadget definitions */ #define DBL_INTERWIDTH (INTERWIDTH << 1) #define DBL_INTERHEIGHT (INTERHEIGHT << 1) #define GAD_SECONDS 6 #define GAD_KEY 7 #define GAD_HIDE 8 #define GAD_QUIT 9 struct Gadget *gad_seconds; struct Gadget *gad_key; struct Gadget *gad_hide; struct Gadget *gad_quit; /******************************************************************** * 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 *customobj; char *hotkey; struct Message *msg; long seconds; short window = FALSE; 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); if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) { /* * parse command line or tool types * * we need icon.library therefore */ if (IconBase = myopenlibrary("icon.library", 37l)) { /* * create tooltypes array (requires icon.library open!!!) */ tooltypes = (char **)ArgArrayInit(argc, argv); newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY); /* * check for a hotkey */ hotkey = ArgString(tooltypes, CX_POPKEY, DEF_CX_POPKEY); /* * get the user's prefered timeout */ seconds = ArgInt(tooltypes, TT_TIMEOUT, DEF_TIMEOUT); if (seconds < 1) timeoutseconds = 0; else timeoutseconds = seconds; timeoutperiod = timeoutseconds * 10; if (UtilityBase = myopenlibrary("utility.library", 37l)) { if (Stricmp(ArgString(tooltypes, CX_POPUP, DEF_CX_POPUP), YES) == 0l) window = TRUE; /* * blank on key press? */ keypress = (Stricmp(ArgString(tooltypes, TT_KEY, DEF_KEY), YES) == 0l) ? TRUE : FALSE; CloseLibrary(UtilityBase); } /* if UtilityBase */ if (CxBase = myopenlibrary("commodities.library", 37l)) { if (GfxBase = myopenlibrary("graphics.library", 37l)) { if (GadToolsBase = myopenlibrary("gadtools.library", 37l)) { /* * create our message port */ if (cxport = CreateMsgPort()) { cxsigflag = 1l << cxport->mp_SigBit; newbroker.nb_Port = cxport; if (broker = CxBroker(&newbroker, NULL)) { if (timerfilter = CxFilter(NULL)) { AttachCxObj(broker, timerfilter); if (mousefilter = CxFilter(NULL)) { AttachCxObj(broker, mousefilter); if (keyfilter = CxFilter(NULL)) { AttachCxObj(broker, keyfilter); SetFilterIX(timerfilter, &timerix); SetFilterIX(mousefilter, &mouseix); SetFilterIX(keyfilter, &keyix); if ((signal = (long)AllocSignal(-1)) != -1) { customsigflag = 1 << signal; if (mytask = FindTask(NULL)) { if (customobj = CxCustom(timermon, 0l)) { AttachCxObj(timerfilter, customobj); if (customobj = CxCustom(mousemon, 0l)) { AttachCxObj(mousefilter, customobj); if (customobj = CxCustom(keymon, 0l)) { AttachCxObj(keyfilter, customobj); if (*hotkey) { unsigned long len; if (hotkeyfilter = HotKey(hotkey, cxport, POP_KEY_ID)) { AttachCxObj(broker, hotkeyfilter); len = strlen(windowtitle); strncpy(windowtitle + len, ": HotKey=", WINDOWTITLE_LEN - len); len += sizeof(": HotKey=") - 1; strncpy(windowtitle + len, hotkey, WINDOWTITLE_LEN - len); } } /* if hotkey */ if (!CxObjError(timerfilter) && !CxObjError(mousefilter) && !CxObjError(keyfilter) && !(hotkeyfilter && CxObjError(hotkeyfilter))) { /* * deactivate timerfilter if timeout = 0 */ if (!timeoutseconds) ActivateCxObj(timerfilter, 0l); /* * deactivate keyfilter if !keypress */ if (!keypress) ActivateCxObj(keyfilter, 0l); /* * activate our commodity */ ActivateCxObj(broker, 1l); /* * deactivate again, if no timeout and not keypress */ if (!timeoutseconds && !keypress) ActivateCxObj(broker, 0l); /* * now watch our numerous ports */ processmessages(window); } /* if !CxObjError() */ } /* if keymon */ } /* if mousemon */ } /* if timermon */ } /* if mytask */ FreeSignal(signal); customsigflag = 0l; } /* if signal */ } /* if keyfilter */ #ifdef DEBUG else printf("main(): keyfilter = CxFilter() failed!\n"); #endif } /* if mousefilter */ #ifdef DEBUG else printf("main(): mousefilter = CxFilter() failed!\n"); #endif } /* if timerfilter */ #ifdef DEBUG else printf("main(): timerfilter = 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 CloseLibrary(GadToolsBase); } /* if GadToolsBase */ CloseLibrary(GfxBase); } /* if GfxBase */ CloseLibrary(CxBase); } /* if CxBase */ /* * free memory allocated by ArgArrayInit() */ ArgArrayDone(); CloseLibrary(IconBase); } /* if IconBase */ CloseLibrary((struct Library *)IntuitionBase); } /* if IntuitionBase */ } /* main() */ void processmessages(short window) { struct Message *msg; unsigned long sigreceived; unsigned long msgtype; unsigned long msgid; unsigned short quit = FALSE; unsigned short windowopen = FALSE; unsigned char command = CCMD_NOP; if (window) { if (openwindow()) windowopen = TRUE; } while (!quit) { sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag | customsigflag | idcmpsigflag); #ifdef DEBUG printf("processmessages(): signal received\n"); #endif if (sigreceived & customsigflag) changestateofmousepointer(blankstatus); if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE; if (sigreceived & cxsigflag) { #ifdef DEBUG printf("processmessages(): message at cxport\n"); #endif while (msg = (struct Message *)GetMsg(cxport)) { msgid = CxMsgID((CxMsg *)msg); msgtype = CxMsgType((CxMsg *)msg); ReplyMsg(msg); switch (msgtype) { case CXM_IEVENT: if (msgid == POP_KEY_ID) { if (openwindow()) windowopen = TRUE; } break; case CXM_COMMAND: switch (msgid) { case CXCMD_KILL: quit = TRUE; case CXCMD_DISABLE: ActivateCxObj(broker, 0l); blankstatus = UNBLANKED; changestateofmousepointer(blankstatus); #ifdef DEBUG printf("processmessages(): broker disabled\n"); #endif break; case CXCMD_ENABLE: ActivateCxObj(broker, 1l); #ifdef DEBUG printf("processmessages(): broker enabled\n"); #endif break; case CXCMD_UNIQUE: case CXCMD_APPEAR: if (openwindow()) windowopen = TRUE; break; case CXCMD_DISAPPEAR: windowopen = FALSE; closewindow(); break; } break; } /* switch msgtype */ } /* while CxMsg */ } /* if (sigreceived & cxsigflag) */ if (sigreceived & idcmpsigflag) { APTR *object; ULONG class; UWORD code; #ifdef DEBUG printf("processmessages(): message at idcmpport\n"); #endif while (windowopen && (msg = (struct Message *)GT_GetIMsg(idcmpport))) { /* * handle IDCMP messages */ class = ((struct IntuiMessage *)msg)->Class; code = ((struct IntuiMessage *)msg)->Code; object = ((struct IntuiMessage *)msg)->IAddress; GT_ReplyIMsg((struct IntuiMessage *)msg); switch (class) { case CLOSEWINDOW: command = CCMD_HIDE; break; case REFRESHWINDOW: GT_BeginRefresh(win); GT_EndRefresh(win, TRUE); break; case GADGETUP: if (object) command = (unsigned char)((struct Gadget *)object)->UserData; break; case VANILLAKEY: switch (code) { case 27: case MSG_HIDE_SCC: case MSG_HIDE_SCC - CASE_DIFF: command = CCMD_HIDE; break; case MSG_QUIT_SCC: case MSG_QUIT_SCC - CASE_DIFF: command = CCMD_QUIT; break; case MSG_SECONDS_SCC: case MSG_SECONDS_SCC - CASE_DIFF: command = CCMD_SECONDS_ACTIVATE; break; case MSG_KEY_SCC: case MSG_KEY_SCC - CASE_DIFF: command = CCMD_KEY_SHORTCUT; break; } break; } /* switch class */ } /* while idcmp message */ } /* if (sigreceived & idcmpsigflag) */ #ifdef DEBUG printf("processmessages(): command = %ld\n", command); #endif switch(command) { case CCMD_NOP: break; case CCMD_HIDE: getseconds(); closewindow(); break; case CCMD_QUIT: quit = TRUE; break; case CCMD_SECONDS: getseconds(); break; case CCMD_KEY_SHORTCUT: GT_SetGadgetAttrs(gad_key, win, NULL, GTCB_Checked, !keypress, TAG_END); case CCMD_KEY: keypress = !keypress; ActivateCxObj(keyfilter, keypress); #ifdef DEBUG printf("processmessages(): ActivateCxObj(keyfilter, %ld)\n", keypress); #endif if (!keypress && !timeoutseconds) { /* * unblank mouse pointer */ blankstatus = UNBLANKED; changestateofmousepointer(blankstatus); ActivateCxObj(broker, 0l); #ifdef DEBUG printf("processmessages(): broker disabled\n"); #endif } else { ActivateCxObj(broker, 1l); #ifdef DEBUG printf("processmessages(): broker enabled\n"); #endif } break; case CCMD_SECONDS_ACTIVATE: ActivateGadget(gad_seconds, win, NULL); break; } /* switch (command) */ command = CCMD_NOP; } /* while !quit */ ActivateCxObj(broker, 0l); #ifdef DEBUG printf("processmessages(): broker disabled\n"); #endif changestateofmousepointer(UNBLANKED); closewindow(); } /* * commodity functions */ void __saveds timermon(void) { if (++timeout >= timeoutperiod) { blankstatus = BLANKED; if (mytask && customsigflag) Signal(mytask, customsigflag); #ifdef DEBUG printf(COM_NAME ": timermon blanked\n"); #endif } } void __saveds mousemon(void) { #ifdef DEBUG printf(COM_NAME ": mousemon\n"); #endif timeout = 0; if (blankstatus == BLANKED) { blankstatus = UNBLANKED; if (mytask && customsigflag) Signal(mytask, customsigflag); #ifdef DEBUG printf(COM_NAME ": mousemon unblanked\n"); #endif } } void __saveds keymon(CxMsg *cxm) { register struct InputEvent *ie = (struct InputEvent *)CxMsgData(cxm); #ifdef DEBUG printf(COM_NAME ": keymon\n"); #endif if (ie->ie_Code < 0x60) { if (blankstatus == UNBLANKED) { blankstatus = BLANKED; if (mytask && customsigflag) Signal(mytask, customsigflag); #ifdef DEBUG printf(COM_NAME ": keymon blanked\n"); #endif } } } void changestateofmousepointer(unsigned char blankstatus) { if (blankstatus == BLANKED) { /* * clear mouse pointer */ WaitTOF(); OFF_SPRITE; custom.spr[0].dataa=0; custom.spr[0].datab=0; timeout = 0; if (keypress) { /* * no mousepointer => * disable keyfilter, no rawkey event needs to be monitored * if no timeout specified, enable mousefilter */ if (!timeoutseconds) { ActivateCxObj(mousefilter, 1l); #ifdef DEBUG printf("changestateofmousepointer(): mousefilter enabled\n"); #endif } ActivateCxObj(keyfilter, 0l); #ifdef DEBUG printf("changestateofmousepointer(): keyfilter disabled\n"); #endif } } /* if blanked */ else { ON_SPRITE; timeout = 0; if (keypress) { /* * mouse pointer on => * enable keyfilter and disbale mousefilter if no timeout specified */ if (!timeoutseconds) { ActivateCxObj(mousefilter, 0l); #ifdef DEBUG printf("changestateofmousepointer(): mousefilter disabled\n"); #endif } ActivateCxObj(keyfilter, 1l); #ifdef DEBUG printf("changestateofmousepointer(): keyfilter enabled\n"); #endif } } } /* * window functions */ long openwindow(void) { struct DimensionInfo di; struct Rectangle *rect; unsigned long lock; unsigned long vpmid; long ok; if (win) { /* * dont't open window but pop it to front, unzip it * * unzip window if zipped */ if (win->Height < mywindowtag[P_WA_Height].ti_Data) ZipWindow(win); /* * window to front */ WindowToFront(win); /* * activate window */ lock = LockIBase(0l); if (win != IntuitionBase->ActiveWindow) { UnlockIBase(lock); ActivateWindow(win); } else UnlockIBase(lock); /* * screen to front */ lock = LockIBase(0l); if (win->WScreen != IntuitionBase->FirstScreen) { UnlockIBase(lock); ScreenToFront(win->WScreen); } else UnlockIBase(lock); ok = TRUE; } else { /* * lock the default public screen */ if (scr = LockPubScreen(NULL)) { /* * GetVisualInfo() for gadtools */ if (vi = GetVisualInfo(scr, TAG_DONE)) { /* * update some window information */ mywindowtag[P_WA_Width].ti_Data = zoompos[2] = TextLength(&scr->RastPort, (STRPTR)windowtitle, strlen(windowtitle)) + 100; mywindowtag[P_WA_Height].ti_Data = zoompos[3] = scr->WBorTop + scr->RastPort.TxHeight + 1; /* * create all gadgets: * * this function may also change the width and height of our window */ if (createallgadgets(&gadgetlist, vi, scr, &mywindowtag[P_WA_Height].ti_Data, &mywindowtag[P_WA_Width].ti_Data)) { /* * center the window in the visible box of the screen */ if ((vpmid = GetVPModeID(&scr->ViewPort )) != INVALID_ID) { GetDisplayInfoData(0, (UBYTE *)&di, sizeof(struct DimensionInfo), DTAG_DIMS, vpmid); rect = &di.TxtOScan; zoompos[0] = mywindowtag[P_WA_Left].ti_Data = (scr->LeftEdge < 0 ? -scr->LeftEdge : 0) + ((min((rect->MaxX - rect->MinX + 1), scr->Width) - mywindowtag[P_WA_Width].ti_Data) >> 1); zoompos[1] = mywindowtag[P_WA_Top].ti_Data = (scr->TopEdge < 0 ? -scr->TopEdge : 0) + ((min((rect->MaxY - rect->MinY + 1), scr->Height) - mywindowtag[P_WA_Height].ti_Data) >> 1); } mywindowtag[P_WA_PubScreen].ti_Data = (ULONG)scr; mywindowtag[P_WA_Gadgets].ti_Data = (ULONG)gadgetlist; if (win = OpenWindowTagList(NULL, mywindowtag)) { /* * save IDCMP port */ idcmpport = win->UserPort; idcmpsigflag = 1L << idcmpport->mp_SigBit; GT_RefreshWindow(win, NULL); /* * switch screen to front */ lock = LockIBase(0l); if (win->WScreen != IntuitionBase->FirstScreen) { UnlockIBase(lock); ScreenToFront(win->WScreen); } else UnlockIBase(lock); ok = TRUE; } /* if (win = OpenWindowTagList(NULL, mywindowtag)) */ } /* if (createallgadgets() */ } /* if (vi = GetVisualInfo(scr, TAG_DONE)) */ } /* if (scr = LockPubScreen(NULL)) */ if (!ok) { /* * window could not be opened - free all resources */ closewindow(); } } /* if (!win) */ return(ok); } void closewindow(void) { if (win) { CloseWindow(win); win = NULL; idcmpport = NULL; idcmpsigflag = 0l; } if (gadgetlist) { FreeGadgets(gadgetlist); gadgetlist = NULL; } if (vi) { FreeVisualInfo(vi); vi = NULL; } if (scr) { UnlockPubScreen(NULL, scr); scr = NULL; } } void getseconds(void) { long seconds; if (blankstatus == BLANKED && !keypress) { /* * unblank mouse pointer */ blankstatus = UNBLANKED; changestateofmousepointer(blankstatus); } if ((seconds = ((struct StringInfo *)gad_seconds->SpecialInfo)->LongInt) > 0) { /* * input value ok */ timeoutseconds = seconds; timeoutperiod = timeoutseconds * 10; timeout = 0; ActivateCxObj(timerfilter, 1l); #ifdef DEBUG printf("getseconds(): timerfilter enabled\n"); #endif ActivateCxObj(broker, 1l); #ifdef DEBUG printf("getseconds(): broker enabled\n"); #endif } else { /* * value given was < 1 */ timeoutseconds = timeout = 0; /* * disable timerfilter */ ActivateCxObj(timerfilter, 0l); /* * update gadget contents */ GT_SetGadgetAttrs(gad_seconds, win, NULL, GTIN_Number, timeoutseconds, TAG_END); } /* * disable broker if all blanking actions are disabled */ if (!keypress && !timeoutseconds) { ActivateCxObj(broker, 0l); #ifdef DEBUG printf("getseconds(): broker disabled\n"); #endif } } /* * createallgadgets(): create all gadgets and put required width and height * of window in height and width */ struct Gadget * createallgadgets(struct Gadget **glist, APTR vi, struct Screen *scr, ULONG *height, ULONG *width) { static struct NewGadget ng; struct Gadget *gad; struct RastPort *rp; short buttonwidth; short keywidth; short secondswidth; short dummy; /* * first get RastPort of screen to determine some TextLength() */ rp = &scr->RastPort; /* * calculate width of the seconds gadget: * I tried out that 8 times the width of the digit "0" gives a nice value * for the integer gadget; add INTERWIDTH and length of gadgettitle */ secondswidth = ((TextLength(rp, (STRPTR)"0", 1l)) << 3) + INTERWIDTH + TextLength(rp, (STRPTR)&msg_seconds[1], strlen(msg_seconds) - 1l); *width = max(secondswidth + DBL_INTERWIDTH, *width); /* * */ keywidth = TextLength(rp, (STRPTR)msg_key, strlen(msg_key)) - TextLength(rp, (STRPTR)"_", 1l) + 26 + INTERWIDTH; *width = max(keywidth + DBL_INTERWIDTH, *width); buttonwidth = TextLength(rp, (STRPTR)&msg_hide[1], strlen(msg_hide) - 1l); dummy = TextLength(rp, (STRPTR)&msg_quit[1], strlen(msg_quit) - 1l); buttonwidth = max(buttonwidth, dummy); buttonwidth += DBL_INTERWIDTH; /* * check out if the window's width has to be enlarged */ *width = max((buttonwidth << 1) + (DBL_INTERWIDTH + INTERWIDTH), *width); /* * now create the gadgets */ gad = CreateContext(glist); /* * seconds gadget */ ng.ng_TopEdge = scr->WBorTop + rp->TxHeight + 1 + DBL_INTERHEIGHT; ng.ng_Width = (TextLength(rp, (STRPTR)"0", 1l)) << 3; ng.ng_LeftEdge = TextLength(rp, (STRPTR)&msg_seconds[1], strlen(msg_seconds) - 1l); ng.ng_LeftEdge += (*width - secondswidth) >> 1; ng.ng_Height = rp->TxHeight + 4; ng.ng_GadgetText = (UBYTE *)msg_seconds; ng.ng_TextAttr = scr->Font; ng.ng_GadgetID = GAD_SECONDS; ng.ng_Flags = PLACETEXT_LEFT; ng.ng_VisualInfo = vi; ng.ng_UserData = (APTR)CCMD_SECONDS; gad_seconds = gad = CreateGadget(INTEGER_KIND, gad, &ng, GTIN_MaxChars, 3l, GTIN_Number, (ULONG)timeoutseconds, GT_Underscore, '_', TAG_DONE); /* * key pressed gadget */ ng.ng_TopEdge += ng.ng_Height + INTERHEIGHT; ng.ng_LeftEdge = (*width - keywidth) >> 1; ng.ng_GadgetText = (UBYTE *)msg_key; ng.ng_GadgetID = GAD_KEY; ng.ng_Flags = PLACETEXT_RIGHT; ng.ng_UserData = (APTR)CCMD_KEY; gad_key = gad = CreateGadget(CHECKBOX_KIND, gad, &ng, GTCB_Checked, keypress, GT_Underscore, '_', TAG_DONE); /* * dummy now gets the spacing between the button gadgets */ dummy = (*width - (buttonwidth << 1)) / 3; /* * Hide gadget */ ng.ng_TopEdge += ng.ng_Height + INTERHEIGHT; ng.ng_Width = buttonwidth; ng.ng_LeftEdge = dummy; ng.ng_GadgetText = (UBYTE *)msg_hide; ng.ng_GadgetID = GAD_HIDE; ng.ng_Flags = 0l; ng.ng_UserData = (APTR)CCMD_HIDE; gad_hide = gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE); /* * Quit gadget */ ng.ng_LeftEdge += ng.ng_Width + dummy; ng.ng_GadgetText = (UBYTE *)msg_quit; ng.ng_GadgetID = GAD_QUIT; ng.ng_UserData = (APTR)CCMD_QUIT; gad_quit = gad = CreateGadget(BUTTON_KIND, gad, &ng, GT_Underscore, '_', TAG_DONE); *height = gad->TopEdge + gad->Height + DBL_INTERHEIGHT; return(gad); }