home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 3
/
CDPDIII.bin
/
pd
/
commodities
/
mouseaccell
/
mouseaccelerator.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-07
|
38KB
|
1,183 lines
/*
* 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)
* V1.02 recompiled with changed (for 68040 compatiblity) cback.o
* V1.03 small changes; set MAX_THRESH to 20;
* setting acceleration = 1 now disables the mousefilter
* V1.04 removed enforcer hit under low mem in createallgadgets()
* now window opens on the front screen, if it is a public screen, else on
* the default public screen
* V1.05 14 Sep 1991 Stefan Sticht changed request() to open on the same screen
* as the window; replaced strlen() with sizeof();
* other optimizations
* V1.06 16 Sep 1991 Stefan Sticht removed error in lockfrontpubscr()
* V1.07 Mon 07-Oct-91 Stefan Sticht removed obsolete code: replying IDCMP messages before CloseWindow()
*/
#define VERSION "V1.07"
/********************************************************************
* interfacing *
********************************************************************/
/*
* include files
*/
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <devices/inputevent.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/gadtools_protos.h>
#include <pragmas/gadtools_pragmas.h>
#include <clib/graphics_protos.h>
#include <pragmas/graphics_pragmas.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition_pragmas.h>
#include <clib/utility_protos.h>
#include <pragmas/utility_pragmas.h>
#ifdef DEBUG
#define printf KPrintF
#include <clib/dlib_protos.h>
#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);
struct Screen *lockfrontpubscr(void);
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)
*/
#if defined(GERMAN)
#define RETRY_GADGETS "Wiederholen|Abbrechen"
#define RESUME_GADGETS "Weiter"
#define MSG_LIBRARY_OPENERR "Die %s (V%ld+) kann nicht geöffnet werden!"
#define MSG_WINDOW_OPENERR "Leider kann das Fenster nicht geöffnet werden!"
#define COM_NAME "Mausbeschleuniger"
#define COM_DESCR "Beschleunigt Mausbewegungen"
#define MSG_ACC "Beschleunigungsfaktor: %-lu "
#define MSG_ACC_SCC 'F'
#define MSG_THRESH "Beschleunigungsminimum: %-lu "
#define MSG_THRESH_SCC 'M'
#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 MSG_WINDOW_OPENERR "Window can't be opened!"
#define COM_NAME "MouseAccelerator"
#define COM_DESCR "Accelerates mouse movements"
#define MSG_ACC "Acceleration: %-lu "
#define MSG_ACC_SCC 'A'
#define MSG_THRESH "Threshold: %-lu "
#define MSG_THRESH_SCC 'T'
#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 20
#define MIN_ACC 1
#define MIN_THRESH 1
#define POP_KEY_ID 100
#define CCMD_NOP 0
#define CCMD_HIDE 1
#define CCMD_QUIT 2
#define CASE_DIFF ('a' - 'A')
#define ON 1l
#define OFF 0l
/*
* 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;
struct MsgPort *cxport;
/*
* signal flags
*/
unsigned long cxsigflag = 0l;
unsigned long idcmpsigflag = 0l;
/*
* programtitle and version for Version command
*/
char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
/*
* helpstring
*/
#if defined(GERMAN)
char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
"Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>] [" CX_POPKEY "=<Zeichenkette>] ["
CX_POPUP "=" YES "|" NO "] [" TT_ACC "=<Zahl>] [" TT_THRESH "=<Zahl>]\n";
#else
char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
"Usage: " COM_NAME " [" CX_PRIORITY "=<number>] [" CX_POPKEY "=<string>] ["
CX_POPUP "=" YES "|" NO "] [" TT_ACC "=<number>] [" TT_THRESH "=<number>]\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;
APTR vi;
struct Gadget *gadgetlist;
struct Screen *scr;
char windowtitle[] = 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,
WA_AutoAdjust, FALSE,
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;
/********************************************************************
* 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(win, &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);
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);
if (value < MIN_ACC) acceleration = MIN_ACC;
else if (value > MAX_ACC) acceleration = MAX_ACC;
else acceleration = value;
/*
* acceleration
*/
value = ArgInt(tooltypes, TT_THRESH, DEF_TT_THRESH);
if (value < MIN_THRESH) threshold = MIN_THRESH;
else if (value > MAX_THRESH) threshold = MAX_THRESH;
else threshold = value;
/*
* 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 && (hotkeyfilter = HotKey(hotkey, cxport, POP_KEY_ID))) {
AttachCxObj(broker, hotkeyfilter);
}
if (!CxObjError(mousefilter) &&
!CxObjError(broker) &&
!(hotkeyfilter && CxObjError(hotkeyfilter))) {
/*
* if acceleration == 1 we don't need to get events
*/
if (acceleration == MIN_ACC) ActivateCxObj(mousefilter, OFF);
#ifdef DEBUG
printf("main(): no acceleration, deactivate mousefilter\n");
#endif
/*
* activate our commodity
*/
ActivateCxObj(broker, ON);
/*
* 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 char command = CCMD_NOP;
if (window) {
if (!openwindow()) request(COM_NAME ":", RESUME_GADGETS, MSG_WINDOW_OPENERR);
}
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()) request(COM_NAME ":", RESUME_GADGETS, MSG_WINDOW_OPENERR);
}
break;
case CXM_COMMAND:
switch (msgid) {
case CXCMD_KILL:
quit = TRUE;
case CXCMD_DISABLE:
ActivateCxObj(broker, OFF);
#ifdef DEBUG
printf("processmessages(): broker disabled\n");
#endif
break;
case CXCMD_ENABLE:
ActivateCxObj(broker, ON);
#ifdef DEBUG
printf("processmessages(): broker enabled\n");
#endif
break;
case CXCMD_UNIQUE:
case CXCMD_APPEAR:
if (!openwindow()) request(COM_NAME ":", RESUME_GADGETS, MSG_WINDOW_OPENERR);
break;
case CXCMD_DISAPPEAR:
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 (idcmpport && (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:
if (code > MIN_ACC) {
if (acceleration == MIN_ACC) {
#ifdef DEBUG
printf("processmessages(): acceleration, activate mousefilter\n");
#endif
ActivateCxObj(mousefilter, ON);
}
}
else {
#ifdef DEBUG
printf("processmessages(): no acceleration, deactivate mousefilter\n");
#endif
ActivateCxObj(mousefilter, OFF);
}
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;
/* doesn't work yet
case MSG_ACC_SCC:
if (acceleration > MIN_ACC) {
acceleration--;
GT_SetGadgetAttrs(gad_acc, win, NULL, GTSL_Level, acceleration, TAG_DONE);
if (acceleration == MIN_ACC) {
#ifdef DEBUG
printf("processmessages(): no acceleration, deactivate mousefilter\n");
#endif
ActivateCxObj(mousefilter, OFF);
}
}
break;
case MSG_ACC_SCC + CASE_DIFF:
if (acceleration < MAX_ACC) {
if (acceleration == MIN_ACC) {
#ifdef DEBUG
printf("processmessages(): acceleration, activate mousefilter\n");
#endif
ActivateCxObj(mousefilter, ON);
}
acceleration++;
GT_SetGadgetAttrs(gad_acc, win, NULL, GTSL_Level, acceleration, TAG_DONE);
}
break;
case MSG_THRESH_SCC:
if (threshold > MIN_THRESH) {
threshold--;
GT_SetGadgetAttrs(gad_thresh, win, NULL, GTSL_Level, threshold, TAG_DONE);
}
break;
case MSG_THRESH_SCC + CASE_DIFF:
if (threshold < MAX_THRESH) {
threshold++;
GT_SetGadgetAttrs(gad_thresh, win, NULL, GTSL_Level, threshold, TAG_DONE);
}
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, OFF);
#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
*/
struct Screen *lockfrontpubscr(void)
{
struct Screen *scr;
struct Screen *pubscr = NULL;
struct List *pslist;
struct PubScreenNode *psnode;
unsigned long lock;
unsigned short screentype;
lock = LockIBase(0l);
if (scr = IntuitionBase->FirstScreen) {
screentype = scr->Flags & SCREENTYPE;
UnlockIBase(lock);
if (screentype == PUBLICSCREEN || screentype == WBENCHSCREEN) {
if (pslist = LockPubScreenList()) {
for (psnode = (struct PubScreenNode *)pslist->lh_Head;
psnode->psn_Node.ln_Succ && (psnode->psn_Screen != scr);
psnode = (struct PubScreenNode *)psnode->psn_Node.ln_Succ);
if (psnode && (psnode->psn_Screen == scr) && !(psnode->psn_Flags & PSNF_PRIVATE)) {
pubscr = LockPubScreen(psnode->psn_Node.ln_Name);
}
UnlockPubScreenList();
}
}
}
else UnlockIBase(lock);
if (pubscr && ((pubscr->Width < 640) || (pubscr->Height < 200))) {
UnlockPubScreen(NULL, pubscr);
pubscr = NULL;
}
/*
* no locked screen yet, try default public screen
*/
if (!pubscr) pubscr = LockPubScreen(NULL);
return(pubscr);
}
long openwindow(void)
{
struct DimensionInfo di;
struct Rectangle *rect;
unsigned long vpmid;
long ok = FALSE;
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
*/
if (win != IntuitionBase->ActiveWindow) ActivateWindow(win);
/*
* screen to front
*/
if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
ok = TRUE;
}
else {
/*
* lock the default public screen
*/
if (scr = lockfrontpubscr()) {
/*
* 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, sizeof(windowtitle) - 1l) + 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
*/
if (win->WScreen != IntuitionBase->FirstScreen) ScreenToFront(win->WScreen);
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) {
/*
* now close the window
*/
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
};
struct TagItem underscoretag[] = {
GT_Underscore, '_',
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 underscorewidth;
short borderswidth;
short buttonwidth;
short accwidth;
short threshwidth;
short dummy;
/*
* first get RastPort of screen to determine some TextLength()
*/
rp = &scr->RastPort;
borderswidth = scr->WBorLeft + scr->WBorRight;
underscorewidth = TextLength(rp, "_", 1l);
/*
* calculate width
*/
accwidth = TextLength(rp, msg_acc, sizeof(msg_acc) - 1l);
*width = max(accwidth + DBL_INTERWIDTH + borderswidth, *width);
threshwidth = TextLength(rp, msg_thresh, sizeof(msg_thresh) - 1l);
*width = max(threshwidth + DBL_INTERWIDTH + borderswidth, *width);
buttonwidth = TextLength(rp, (STRPTR)msg_hide, sizeof(msg_hide) - 1l);
dummy = TextLength(rp, (STRPTR)msg_quit, sizeof(msg_quit) - 1l);
buttonwidth = max(buttonwidth, dummy) - underscorewidth + DBL_INTERWIDTH;
/*
* check out if the window's width has to be enlarged
*/
*width = max((buttonwidth << 1) + (DBL_INTERWIDTH + INTERWIDTH) + borderswidth, *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 - borderswidth;
ng.ng_LeftEdge = INTERWIDTH + scr->WBorLeft;
ng.ng_Height = rp->TxHeight + 4;
ng.ng_TextAttr = scr->Font;
ng.ng_GadgetText = NULL;
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 = sizeof(msg_acc) - 2l;
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 = sizeof(msg_thresh) - 2l;
gad_thresh = gad = CreateGadgetA(SLIDER_KIND, gad, &ng, slidertags);
/*
* dummy now gets the spacing between the button gadgets
*/
dummy = (*width - (buttonwidth << 1) - borderswidth) / 3;
/*
* Hide gadget
*/
ng.ng_TopEdge += ng.ng_Height + DBL_INTERHEIGHT;
ng.ng_Width = buttonwidth;
ng.ng_LeftEdge = dummy + scr->WBorLeft;
ng.ng_GadgetText = (UBYTE *)msg_hide;
ng.ng_GadgetID = GAD_HIDE;
ng.ng_Flags = 0l;
ng.ng_UserData = (APTR)CCMD_HIDE;
gad = CreateGadgetA(BUTTON_KIND, gad, &ng, underscoretag);
/*
* 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 = CreateGadgetA(BUTTON_KIND, gad, &ng, underscoretag);
*height = ng.ng_TopEdge + ng.ng_Height + scr->WBorBottom + INTERHEIGHT;
return(gad);
}