/* * MouseAccelerator.c * * Commodity * * Author: Stefan Sticht * * Copyright: source is public domain, no copyright * * Version history: * * V1.00 initial release * V1.01 two small changes in messages (thanks to Holger Gzella) */ #define VERSION "V1.01" /******************************************************************** * 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 #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 accelerator(CxMsg *cxm); void closewindow(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; /* * 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 "Mausbeschleuniger" #define COM_DESCR "Beschleunigt Mausbewegungen" #define MSG_ACC "Beschleunigungsfaktor: %-lu " #define MSG_THRESH "Beschleunigungsminimum: %-lu " #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_ACC "FAKTOR" #define TT_THRESH "MINIMUM" #else #define RETRY_GADGETS "Retry|Cancel" #define RESUME_GADGETS "Resume" #define MSG_LIBRARY_OPENERR "%s (V%ld+) can't be opened!" #define COM_NAME "MouseAccelerator" #define COM_DESCR "Accelerates mouse movements" #define MSG_ACC "Acceleration: %-lu " #define MSG_THRESH "Threshold: %-lu " #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_ACC "ACCELERATION" #define TT_THRESH "THRESHOLD" #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_TT_ACC 5 #define DEF_TT_THRESH 4 #define MAX_ACC 20 #define MAX_THRESH 50 #define POP_KEY_ID 100 #define CCMD_NOP 0 #define CCMD_HIDE 1 #define CCMD_QUIT 2 #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 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_ACC "=] [" TT_THRESH "=]\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_ACC "=] [" TT_THRESH "=]\n"; #endif /* * the tooltypearray */ char **tooltypes; /* * our broker */ CxObj *broker = NULL; CxObj *mousefilter; CxObj *hotkeyfilter; 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 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 */ }; /* * acceleration and threshold */ unsigned short acceleration; unsigned short threshold; /* * 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 | SLIDERIDCMP | 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_acc[] = MSG_ACC; char msg_thresh[] = MSG_THRESH; char msg_hide[] = MSG_HIDE; char msg_quit[] = MSG_QUIT; /* * gadget definitions */ #define DBL_INTERWIDTH (INTERWIDTH << 1) #define DBL_INTERHEIGHT (INTERHEIGHT << 1) #define GAD_ACC 6 #define GAD_THRESH 7 #define GAD_HIDE 8 #define GAD_QUIT 9 struct Gadget *gad_acc; struct Gadget *gad_thresh; 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; 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)) { long value; /* * create tooltypes array (requires icon.library open!!!) */ tooltypes = (char **)ArgArrayInit(argc, argv); newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY); /* * acceleration */ value = ArgInt(tooltypes, TT_ACC, DEF_TT_ACC); acceleration = (value > 0l) ? value : 1l; if (acceleration > MAX_ACC) acceleration = MAX_ACC; /* * acceleration */ value = ArgInt(tooltypes, TT_THRESH, DEF_TT_THRESH); threshold = (value > 0l) ? value : 1l; if (threshold > MAX_THRESH) threshold = MAX_THRESH; /* * check for a hotkey */ hotkey = ArgString(tooltypes, CX_POPKEY, DEF_CX_POPKEY); if (UtilityBase = myopenlibrary("utility.library", 37l)) { if (Stricmp(ArgString(tooltypes, CX_POPUP, DEF_CX_POPUP), YES) == 0l) window = TRUE; 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 (mousefilter = CxFilter(NULL)) { AttachCxObj(broker, mousefilter); SetFilterIX(mousefilter, &mouseix); if (customobj = CxCustom(accelerator, 0l)) { AttachCxObj(mousefilter, 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(mousefilter) && !(hotkeyfilter && CxObjError(hotkeyfilter))) { /* * activate our commodity */ ActivateCxObj(broker, 1l); /* * now watch our numerous ports */ processmessages(window); } /* if !CxObjError() */ } /* if customobj */ } /* if mousefilter */ 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 | idcmpsigflag); #ifdef DEBUG printf("processmessages(): signal received\n"); #endif 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); #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 MOUSEMOVE: if (object) { switch(((struct Gadget *)object)->GadgetID & GADTOOLMASK) { case GAD_ACC: acceleration = code; break; case GAD_THRESH: threshold = code; break; } } 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; } 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: closewindow(); break; case CCMD_QUIT: quit = TRUE; break; } /* switch (command) */ command = CCMD_NOP; } /* while !quit */ ActivateCxObj(broker, 0l); #ifdef DEBUG printf("processmessages(): broker disabled\n"); #endif closewindow(); } /* * commodity functions */ void __saveds accelerator(CxMsg *cxm) { register struct InputEvent *ie; register short n; register short s; if ((ie = (struct InputEvent *)CxMsgData(cxm)) && (acceleration > 1)) { n = ie->ie_X; s = 1; if (n < 0) { n = -n; s = -1; } if (n > threshold) ie->ie_X = s * (short)((n - threshold - 1) * acceleration + threshold + 1); n = ie->ie_Y; s = 1; if (n < 0) { n = -n; s = -1; } if (n > threshold) ie->ie_Y = s * (short)((n - threshold - 1) * acceleration + threshold + 1); } } /* * window functions */ long openwindow(void) { struct DimensionInfo di; struct Rectangle *rect; unsigned long lock; unsigned long vpmid; long ok; if (win) { #ifdef DEBUG printf("openwindow(): window already open\n"); #endif /* * 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); } #ifdef DEBUG else printf("openwindow(): GetVPModeID() == INVALID_ID\n"); #endif 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)) */ #ifdef DEBUG else printf("openwindow(): OpenWindowTagList() failed\n"); #endif } /* if (createallgadgets() */ #ifdef DEBUG else printf("openwindow(): createallgadgets() failed\n"); #endif } /* if (vi = GetVisualInfo(scr, TAG_DONE)) */ #ifdef DEBUG else printf("openwindow(): GetVisualInfo() failed\n"); #endif } /* if (scr = LockPubScreen(NULL)) */ #ifdef DEBUG else printf("openwindow(): could LockPubScreen(NULL)\n"); #endif 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; } } #define TAG_Max 1 #define TAG_Level 2 #define TAG_LevelFormat 3 #define TAG_MaxLevelLen 4 struct TagItem slidertags[] = { GTSL_Min, 1l, GTSL_Max, 0l, GTSL_Level, 0l, GTSL_LevelFormat, 0l, GTSL_MaxLevelLen, 0l, GTSL_LevelPlace, PLACETEXT_ABOVE, TAG_END }; /* * 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 accwidth; short threshwidth; short dummy; /* * first get RastPort of screen to determine some TextLength() */ rp = &scr->RastPort; /* * calculate width */ accwidth = TextLength(rp, msg_acc, strlen(msg_acc)); *width = max(accwidth + DBL_INTERWIDTH, *width); threshwidth = TextLength(rp, msg_thresh, strlen(msg_thresh)); *width = max(threshwidth + 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); /* * Acceleration gadget: */ ng.ng_TopEdge = scr->WBorTop + (rp->TxHeight << 1) + 1 + DBL_INTERHEIGHT; ng.ng_Width = *width - DBL_INTERWIDTH; ng.ng_LeftEdge = INTERWIDTH; ng.ng_Height = rp->TxHeight + 4; ng.ng_TextAttr = scr->Font; ng.ng_GadgetID = GAD_ACC; ng.ng_VisualInfo = vi; slidertags[TAG_Max].ti_Data = (ULONG)MAX_ACC; slidertags[TAG_Level].ti_Data = (ULONG)acceleration; slidertags[TAG_LevelFormat].ti_Data = (ULONG)msg_acc; slidertags[TAG_MaxLevelLen].ti_Data = strlen(msg_acc); gad_acc = gad = CreateGadgetA(SLIDER_KIND, gad, &ng, slidertags); /* * threshold gadget */ ng.ng_TopEdge += ng.ng_Height + DBL_INTERHEIGHT + rp->TxHeight; ng.ng_GadgetID = GAD_THRESH; slidertags[TAG_Max].ti_Data = (ULONG)MAX_THRESH; slidertags[TAG_Level].ti_Data = (ULONG)threshold; slidertags[TAG_LevelFormat].ti_Data = (ULONG)msg_thresh; slidertags[TAG_MaxLevelLen].ti_Data = strlen(msg_thresh); gad_thresh = gad = CreateGadgetA(SLIDER_KIND, gad, &ng, slidertags); /* * dummy now gets the spacing between the button gadgets */ dummy = (*width - (buttonwidth << 1)) / 3; /* * Hide gadget */ ng.ng_TopEdge += ng.ng_Height + DBL_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); }