home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
commod
/
rotor_v1.lha
/
Rotor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-20
|
47KB
|
1,799 lines
/*
Rotor V1.01
Written by Markus "ill" Illenseer markus@Techfak.Uni-Bielefeld.de
Based on ASwarm II V1.4 by Matthias Scheler and Markus Illenseer.
Please leave this source intact. Rotor is freely distributable.
If you have suggestions or Bug-Reports, please contact me.
Read the Manuals for known Bugs and Contact-Adresses.
*/
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/execbase.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/commodities.h>
#include <libraries/gadtools.h>
#include <workbench/startup.h>
#include <workbench/icon.h>
#include <workbench/workbench.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/rdargs.h>
#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/icon_protos.h>
#include <clib/intuition_protos.h>
#include <clib/macros.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#ifdef LATTICE /* some stuff for SAS-C */
#include <pragmas/commodities_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/icon_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#define VOID_INTERRUPT void __interrupt __saveds
#define REGARGS __regargs
#define VOID_STDARGS void __stdargs
CxObj *HotKey(UBYTE *,struct MsgPort *,long);
void NewList(struct List *);
UBYTE *VersionString = "$VER: Rotor V1.01 (compiled with SAS/C)";
void chkabort(void)
{}
#else /* some stuff for Dice especially for -mR */
#define VOID_INTERRUPT __stkargs __geta4 void
#define REGARGS
#define VOID_STDARGS __stkargs void
__stkargs CxObj *HotKey(UBYTE *,struct MsgPort *,long);
__stkargs void NewList(struct List *);
UBYTE *VersionString = "$VER: Rotor V1.01 (compiled with DICE)";
void main(LONG,UBYTE **);
void wbmain(struct WBStartup *WBS)
{
if (WBS->sm_NumArgs) (void)CurrentDir(WBS->sm_ArgList->wa_Lock);
main(0L,(UBYTE **)WBS);
}
#endif
/*
Common Definitions
*/
#define custom (*((struct Custom *)0xDFF000L))
extern struct ExecBase *SysBase;
extern struct DosLibrary *DOSBase;
#define FINDPROCPORT (&((struct Process *)SysBase->ThisTask)->pr_MsgPort)
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *CxBase,*GadToolsBase,*IconBase;
LONG WBStarted;
#define NUMTOOLTYPES 11
char *ToolTypeIDs[NUMTOOLTYPES] =
{"CX_PRIORITY","CX_POPUP","CX_POPKEY","BLANKKEY",
"TIMEOUT","CLIENTTIMEOUT","CYCLE",
"DISPLAY","MOUSEBLANKMETHOD","CHANGE","TRAIL"};
/*
Definitions for our Commodity
*/
struct NewBroker NewBroker =
{NB_VERSION,"Rotor","Amiga Rotor 1.01","Screen Blanker by Markus Illenseer",
NBU_NOTIFY|NBU_UNIQUE,COF_SHOW_HIDE,0,NULL,0};
CxObj *Broker,*PopKeyFilter,*BlankKeyFilter;
struct MsgPort *CxPort;
LONG CxPri,CxPopUp;
UBYTE PopKey[32],BlankKey[32];
#define EVENT_OPEN_WINDOW 1L
#define EVENT_BLANK 2L
#define DEF_CX_PRI 0L
#define DEF_POPKEY "CONTROL ALT r" /* Hot Key for the Edit Window */
#define DEF_BLANKKEY "CONTROL ALT b" /* Hot Key for immediate Blank */
LONG TimeLeft,InitTimeLeft,TimeOut,ClientTimeOut;
#define MAX_TIMEOUT 3600L
#define MAX_CLIENT_TIMEOUT 60L
#define DEF_TIMEOUT 60L
#define DEF_CLIENT_TIMEOUT 5L
#define SERVER_PRI 5L /* Don't change this, saves live */
#define CLIENT_PRI -40L
/*
Definitions for our Blanker Screen
*/
struct ModeNode
{
struct Node mn_Node;
UWORD mn_Index;
ULONG mn_DisplayID;
char mn_Name[DISPLAYNAMELEN];
};
struct List *ModeList;
struct ModeNode *DisplayMode;
#define FindMode(l,n) ((struct ModeNode *)FindName(l,n))
#define DEF_MODE HIRES
#define DEF_MODE_NAME "HighRes"
/* Mini and Maximum definitions for possible parameters */
#define MAX_CHANGE 10000
#define DEF_CHANGE 1000
#define MAX_TRAIL 2000
#define DEF_TRAIL 200
char *Template = /* extra extra extra long :-) */
"CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,BLANKKEY/K,SECONDS=TIMEOUT/N/K,"
"CLIENTTIMEOUT/N/K,DISPLAY/K,CYCLE/S,MOUSEBLANKMETHOD/K,CHANGE/N/K,TRAIL/N/K";
/*
Definitions for our Configuration Window
*/
#ifndef WFLG_NEWLOOKMENUS
#define WFLG_NEWLOOKMENUS 0x200000L
#endif
WORD LeftEdge=68,TopEdge=13; /* Hard Coded, the window is too big to */
struct Window *BlankerWindow; /* let it open under the mouse pointer */
#define GID_HIDE 0 /* The Gadget-ID's */
#define GID_BLANK 1
#define GID_QUIT 2
#define GID_MODE 3
#define GID_TIMEOUT 4
#define GID_CLIENT 5
#define GID_MOUSE 6
#define GID_POPKEY 7
#define GID_BLANKKEY 8
#define GID_CHANGE 9
#define GID_TRAIL 10
#define GID_CYCLE 11
#define NUM_GADS 12
char *MouseBlankMethods[] = /* List of Mouse Blank Methods */
{"Hardware","FreeSprite",NULL};
struct VisualInfo *BlankerVisualInfo;
struct Menu *BlankerMenu;
struct Gadget *BlankerContext,*BlankerGadgets[NUM_GADS];
struct TextAttr BlankerAttr={"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
#ifndef GTMN_NewLookMenus
#define GTMN_NewLookMenus (TAG_USER+0x80043)
#endif
struct NewMenu NewBlankerMenus[] =
{NM_TITLE,"Project",NULL,0,0L,NULL,
NM_ITEM,"Load Config","L",0,0L,NULL,
NM_ITEM,"Save Config","S",0,0L,NULL,
NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
NM_ITEM,"About ...",NULL,0,0L,NULL,
NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
NM_ITEM,"Hide","H",0,0L,NULL,
NM_ITEM,"Quit","Q",0,0L,NULL,
NM_TITLE,"Edit",NULL,0,0L,NULL,
NM_ITEM,"Reset To Defaults","D",0,0L,NULL,
NM_END,NULL,NULL,0,0L,NULL};
struct NewGadget NewBlankerGadgets[NUM_GADS] =
{16,101,48,12,"_Hide",&BlankerAttr,GID_HIDE,PLACETEXT_IN,NULL,NULL,
98,101,48,12,"_Blank",&BlankerAttr,GID_BLANK,PLACETEXT_IN,NULL,NULL,
180,101,48,12,"_Quit",&BlankerAttr,GID_QUIT,PLACETEXT_IN,NULL,NULL,
240,55,272,58,"Display Mode",&BlankerAttr,
GID_MODE,PLACETEXT_ABOVE,NULL,NULL,
172,10,56,12,"_Timeout",&BlankerAttr,GID_TIMEOUT,PLACETEXT_LEFT,NULL,NULL,
172,24,56,12,"C_lient Timeout",&BlankerAttr,
GID_CLIENT,PLACETEXT_LEFT,NULL,NULL,
104,55,124,12,"_Mouse Blank",&BlankerAttr,GID_MOUSE,PLACETEXT_LEFT,NULL,NULL,
324,10,188,12,"_Pop Key",&BlankerAttr,GID_POPKEY,PLACETEXT_LEFT,NULL,NULL,
324,24,188,12,"Blank _Key",&BlankerAttr,
GID_BLANKKEY,PLACETEXT_LEFT,NULL,NULL,
128,69,100,12,"_Change ",&BlankerAttr,
GID_CHANGE,PLACETEXT_LEFT,NULL,NULL,
128,83,100,12,"_Trail ",&BlankerAttr,
GID_TRAIL,PLACETEXT_LEFT,NULL,NULL ,
202,43,16,12,"C_olor Cycling",&BlankerAttr,
GID_CYCLE,PLACETEXT_LEFT,NULL,NULL };
UBYTE BlankerGadgetKinds[NUM_GADS] =
{BUTTON_KIND,BUTTON_KIND,BUTTON_KIND,LISTVIEW_KIND,
INTEGER_KIND,INTEGER_KIND,CYCLE_KIND,
STRING_KIND,STRING_KIND,SLIDER_KIND,SLIDER_KIND,CHECKBOX_KIND};
struct TagItem BlankerGadgetTags[] =
{GTLV_Labels,0L,GTLV_Selected,0L,GTLV_ShowSelected,NULL,TAG_DONE,0L,
GTIN_Number,0L,GTIN_MaxChars,4L,TAG_DONE,0L,
GTIN_Number,0L,GTIN_MaxChars,2L,TAG_DONE,0L,
GTCY_Labels,NULL,GTCY_Active,0,TAG_DONE,0L,
GTST_String,0L,GTST_MaxChars,31L,TAG_DONE,0L,
GTST_String,0L,GTST_MaxChars,31L,TAG_DONE,0L,
GTSL_Min,1L,GTSL_Max,MAX_CHANGE,GTSL_Level,0L,
GTSL_MaxLevelLen,5L,GTSL_LevelFormat,(ULONG)"%5ld",
GA_RelVerify,TRUE,PGA_Freedom,LORIENT_HORIZ,TAG_DONE,0L,
GTSL_Min,2L,GTSL_Max,MAX_TRAIL,GTSL_Level,0L,
GTSL_MaxLevelLen,5L,GTSL_LevelFormat,(ULONG)"%4ld",
GA_RelVerify,TRUE,PGA_Freedom,LORIENT_HORIZ,TAG_DONE,0L ,
GTCB_Checked,0L,TAG_DONE,0L };
UBYTE BlankerTagsIndex[NUM_GADS] = {3,3,3,0,4,7,10,13,16,19,27,35};
struct EasyStruct AboutEasyStruct =
{sizeof(struct EasyStruct),0L,"About ...",
"Rotor V1.01\n"
"© 1993 by Markus Illenseer\n"
"Have fun.","Ok"};
/*
Definitions for Server/Client Communication
*/
BYTE bsp_TimeOut,bsp_InputSig,bsp_ClientSig;
struct Task *BlankerServerProcess;
#define MASK(n) (1L<<(n))
struct BlankerClientMsg
{
struct Message bcm_Message;
struct Screen *bcm_Screen;
LONG bcm_Status;
ULONG bcm_SigMask;
LONG bmc_MouseBlank,bcm_Change,bcm_Trail;
LONG bcm_Cycle;
} BlankerClientMsg;
/*
Definitions for Rotor Stuff
*/
/*#define SAVE 200*/ /* this is a good constant to tweak */
#define REPS 50
#define BORDER 1
#define SIZEFACTOR 3000.0
#define MAXANGLE 10000 /* irrectangular */
#define DEFAULTCOUNT 3
typedef unsigned char Boolean;
struct elem {
float angle;
float radius;
float start_radius;
float end_radius;
float radius_drift_max;
float radius_drift_now;
float ratio;
float start_ratio;
float end_ratio;
float ratio_drift_max;
float ratio_drift_now;
};
typedef struct flightstruct {
struct elem *elements;
int pix;
int lastx,
lasty;
int num,
rotor,
prev;
int *savex,
*savey;
float angle;
int centerx,
centery;
int height, width;
int Trail;
Boolean firsttime;
Boolean forward;
Boolean unused;
Boolean smallscreen; /* for small viewmodes */
} flightstruct;
#define ROTOR_COL_NUM 33
UWORD RotorColors[ROTOR_COL_NUM] = /* Color Cycling Table */
{0x000F,0x000F,0x004F,0x008F,0x00BF,0x00FF,0x00FB,0x00F7,0x00F3,0x00F0,0x04F0,
0x08F0,0x09F0,0x0AF0,0x0BF0,0x0CF0,0x0DF0,0x0EF0,0x0FF0,0x0FE0,0x0FD0,0x0FC0,
0x0FB0,0x0F90,0x0F80,0x0F70,0x0F60,0x0F50,0x0F40,0x0F30,0x0F20,0x0F10,0x0F00};
UWORD Colors[4] = {0x0000,0x0FFF};
#define RAND(m) (Random(m)-(m)/2)
LONG MouseBlank,Change,Trail,Cycle;
/*
The following functions are taken from Mattias's resource tracker library for
SAS/C. I normally use to link the programs with this library, but to make
it possible for other people to compile Rotor included the required
source codes. Thanks Matthias!
*/
struct ToolNode
{
struct ToolNode *Next;
void *Tool;
void (*RemProc)(void *,LONG); /* requires stack arguments !!! */
LONG Size;
} *ToolList;
void REGARGS RemTool(void *Tool)
{
struct ToolNode **Ptr,*ToolNode;
Ptr=&ToolList;
while (ToolNode=*Ptr)
if (ToolNode->Tool==Tool)
{
*Ptr=ToolNode->Next;
ToolNode->RemProc(ToolNode->Tool,ToolNode->Size);
FreeVec ((APTR)ToolNode);
return;
}
else Ptr=&ToolNode->Next;
}
VOID_STDARGS RemoveAll(void)
{
while (ToolList) RemTool (ToolList->Tool);
}
void REGARGS AddTool(void *NewTool,void *ProcPtr,LONG NewSize)
{
struct ToolNode *Ptr;
void (*NewRemProc)(void *,LONG);
static BOOL First=TRUE;
NewRemProc=(void (*)(void *,LONG))ProcPtr;
if (NewTool==NULL) exit (10);
if (First)
{
First=FALSE;
if (atexit(RemoveAll))
{
NewRemProc (NewTool,NewSize);
exit (20);
}
}
if ((Ptr=AllocVec(sizeof(struct ToolNode),0L))==NULL)
{
NewRemProc (NewTool,NewSize);
exit (20);
}
Ptr->Next=ToolList;
Ptr->Tool=NewTool;
Ptr->RemProc=NewRemProc;
Ptr->Size=NewSize;
ToolList=Ptr;
}
/*
Some useful functions
*/
VOID_STDARGS DeleteMsgPortSafely(struct MsgPort *AnyPort)
{
struct Message *AnyMsg;
while (AnyMsg=GetMsg(AnyPort)) ReplyMsg (AnyMsg);
DeleteMsgPort (AnyPort);
}
LONG RDArgsLong(LONG Param,LONG Default,LONG Min,LONG Max)
{
LONG *Ptr;
if ((Ptr=(LONG *)Param)==NULL) return Default;
if ((*Ptr<Min)||(*Ptr>Max)) return Default;
else return *Ptr;
}
UWORD PutChar[2] = {0x16C0,0x4E75};
/* dirty hack to avoid assembler part :-)
16C0: move.b d0,(a3)+
4E75: rts
*/
VOID_STDARGS SPrintF(char *Buffer,char *FormatString,...)
{
RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),
(void *)PutChar,Buffer);
}
/*
Functions for Handling the List of the avaible Graphics Modes
*/
VOID_STDARGS DeleteModeList(struct List *ModeList)
{
struct ModeNode *ModeNode;
while (ModeList->lh_Head->ln_Succ)
{
ModeNode=(struct ModeNode *)ModeList->lh_Head;
RemHead (ModeList);
FreeVec ((APTR)ModeNode);
}
FreeVec ((APTR)ModeList);
}
struct List *CreateModeList(void)
{
struct List *ModeList;
UWORD Num;
ULONG DisplayID;
struct DimensionInfo DimInfo;
struct NameInfo NameInfo;
struct ModeNode *ModeNode;
if (ModeList=AllocVec(sizeof(struct List),MEMF_PUBLIC)) NewList (ModeList);
else return NULL;
Num=0;
DisplayID=INVALID_ID;
while ((DisplayID=NextDisplayInfo(DisplayID))!=INVALID_ID)
if ((DisplayID&MONITOR_ID_MASK)&&(ModeNotAvailable(DisplayID)==0L))
if (GetDisplayInfoData(NULL,(UBYTE *)&DimInfo,sizeof(struct DimensionInfo),
DTAG_DIMS,DisplayID))
if (DimInfo.MaxDepth>1)
if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
DTAG_NAME,DisplayID))
if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
{
(void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,
NameInfo.Name);
ModeNode->mn_Index=Num++;
ModeNode->mn_DisplayID=DisplayID;
AddTail (ModeList,&ModeNode->mn_Node);
}
if (ModeList->lh_Head->ln_Succ==NULL)
if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
{
(void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,DEF_MODE_NAME);
ModeNode->mn_Index=Num;
ModeNode->mn_DisplayID=DEF_MODE;
AddTail (ModeList,&ModeNode->mn_Node);
}
else
{
FreeVec ((APTR)ModeList);
return NULL;
}
return ModeList;
}
struct ModeNode *GetDefaultMode(struct List *ModeList)
{
struct NameInfo NameInfo;
struct ModeNode *ModeNode;
if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
DTAG_NAME,DEF_MODE))
if (ModeNode=FindMode(ModeList,NameInfo.Name)) return ModeNode;
return (struct ModeNode *)ModeList->lh_Head;
}
struct ModeNode *GetIndexMode(struct List *ModeList,UWORD Index)
{
struct ModeNode *ModeNode;
ModeNode=(struct ModeNode *)ModeList->lh_Head;
while (ModeNode->mn_Node.ln_Succ)
if (ModeNode->mn_Index==Index) return ModeNode;
else ModeNode=(struct ModeNode *)ModeNode->mn_Node.ln_Succ;
return (struct ModeNode *)ModeList->lh_Head;
}
/*
"icon.library" Stuff
*/
char REGARGS *YesNo(LONG Flag)
{
return Flag?"YES":"NO";
}
char REGARGS *ToolTypeString(struct DiskObject *DiskObject,char *ID,
char *Default)
{
char *String;
if (DiskObject==NULL) return Default;
if (String=FindToolType(DiskObject->do_ToolTypes,ID)) return String;
else return Default;
}
LONG REGARGS ToolTypeBoolean(struct DiskObject *DiskObject,char *ID,
LONG Default)
{
if (Default) return (stricmp(ToolTypeString(DiskObject,ID,""),
YesNo(FALSE))!=0);
else return (stricmp(ToolTypeString(DiskObject,ID,""),YesNo(TRUE))==0);
}
LONG REGARGS ToolTypeLong(struct DiskObject *DiskObject,char *ID,LONG Default,
LONG Min,LONG Max)
{
char *String;
if (DiskObject==NULL) return Default;
if (String=FindToolType(DiskObject->do_ToolTypes,ID))
{
LONG Value;
Value=atol(String);
if ((Value<Min)||(Value>Max)) return Default;
else return Value;
}
else return Default;
}
void REGARGS LoadConfig(char *Name)
{
struct DiskObject *DiskObject;
if (Name) DiskObject=GetDiskObject(Name);
else DiskObject=NULL;
CxPri=ToolTypeLong(DiskObject,ToolTypeIDs[0],0L,-128L,127L);
CxPopUp=ToolTypeBoolean(DiskObject,ToolTypeIDs[1],TRUE);
(void)strcpy(PopKey,ToolTypeString(DiskObject,ToolTypeIDs[2],DEF_POPKEY));
(void)strcpy(BlankKey,ToolTypeString(DiskObject,ToolTypeIDs[3],DEF_BLANKKEY));
/* get Time Out, Client Time Out and Display mode */
if ((TimeOut=ToolTypeLong(DiskObject,"SECONDS",0L,1L,MAX_TIMEOUT))==0L)
TimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
ClientTimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[5],
DEF_CLIENT_TIMEOUT,1L,MAX_CLIENT_TIMEOUT);
if ((DisplayMode=FindMode(ModeList,ToolTypeString(DiskObject,ToolTypeIDs[6],
"")))==NULL)
DisplayMode=GetDefaultMode(ModeList);
if (stricmp(ToolTypeString(DiskObject,ToolTypeIDs[7],""),
MouseBlankMethods[1])) MouseBlank=0L;
else MouseBlank=1L;
Change=ToolTypeLong(DiskObject,ToolTypeIDs[8],DEF_CHANGE,1L,MAX_CHANGE);
Trail=ToolTypeLong(DiskObject,ToolTypeIDs[9],DEF_TRAIL,2L,MAX_TRAIL);
Cycle=ToolTypeBoolean(DiskObject,ToolTypeIDs[10],TRUE);
if (BlankerWindow)
{
GT_SetGadgetAttrs (BlankerGadgets[GID_TIMEOUT],BlankerWindow,NULL,
GTIN_Number,TimeOut,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_CLIENT],BlankerWindow,NULL,
GTIN_Number,ClientTimeOut,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_MODE],BlankerWindow,NULL,
GTLV_Selected,DisplayMode->mn_Index,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_MOUSE],BlankerWindow,NULL,
GTCY_Active,MouseBlank,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_POPKEY],BlankerWindow,NULL,
GTST_String,PopKey,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_BLANKKEY],BlankerWindow,NULL,
GTST_String,BlankKey,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_CHANGE],BlankerWindow,NULL,
GTSL_Level,Change,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_TRAIL],BlankerWindow,NULL,
GTSL_Level,Trail,TAG_DONE);
GT_SetGadgetAttrs (BlankerGadgets[GID_CYCLE],BlankerWindow,NULL,
GTCB_Checked,Cycle,TAG_DONE);
}
if (DiskObject) FreeDiskObject (DiskObject);
}
void REGARGS SaveConfig(char *Name)
{
struct DiskObject *DiskObject;
ULONG Index;
char **NewToolTypes,**NextEntry,**OldToolTypes;
if ((DiskObject=GetDiskObjectNew(Name))==NULL)
{
DisplayBeep (BlankerWindow->WScreen);
return;
}
Index=0L;
OldToolTypes=DiskObject->do_ToolTypes;
while (OldToolTypes[Index]) Index++;
Index+=NUMTOOLTYPES+1L;
if ((NewToolTypes=(char **)AllocVec(Index*4L+NUMTOOLTYPES*48L,
MEMF_PUBLIC|MEMF_CLEAR))==NULL)
{
FreeDiskObject (DiskObject);
return;
}
NextEntry=NewToolTypes;
SPrintF (*NextEntry++=(char *)&NewToolTypes[Index],"%s=%ld",ToolTypeIDs[0],
CxPri);
SPrintF (*NextEntry++=NewToolTypes[0]+48L,"%s=NO",ToolTypeIDs[1]);
SPrintF (*NextEntry++=NewToolTypes[1]+48L,"%s=%s",ToolTypeIDs[2],PopKey);
SPrintF (*NextEntry++=NewToolTypes[2]+48L,"%s=%s",ToolTypeIDs[3],BlankKey);
SPrintF (*NextEntry++=NewToolTypes[3]+48L,"%s=%ld",ToolTypeIDs[4],TimeOut);
SPrintF (*NextEntry++=NewToolTypes[4]+48L,"%s=%ld",ToolTypeIDs[5],
ClientTimeOut);
SPrintF (*NextEntry++=NewToolTypes[5]+48L,"%s=%s",ToolTypeIDs[6],
DisplayMode->mn_Name);
SPrintF (*NextEntry++=NewToolTypes[6]+48L,"%s=%s",ToolTypeIDs[7],
MouseBlankMethods[MouseBlank]);
SPrintF (*NextEntry++=NewToolTypes[7]+48L,"%s=%ld",ToolTypeIDs[8],Change);
SPrintF (*NextEntry++=NewToolTypes[8]+48L,"%s=%ld",ToolTypeIDs[9],Trail);
SPrintF (*NextEntry++=NewToolTypes[9]+48L,"%s=%s",ToolTypeIDs[10],
YesNo(Cycle));
Index=0L;
while (OldToolTypes[Index])
{
char *Ptr,*Asgn;
if (Ptr=(char *)AllocVec(strlen(OldToolTypes[Index])+1L,0L))
{
if (Asgn=strchr(strcpy(Ptr,OldToolTypes[Index]),'=')) *Asgn='\0';
if (FindToolType(NewToolTypes,Ptr)==NULL) *NextEntry++=OldToolTypes[Index];
FreeVec ((APTR)Ptr);
}
Index++;
}
DiskObject->do_ToolTypes=NewToolTypes;
if (!PutDiskObject(Name,DiskObject)) DisplayBeep (BlankerWindow->WScreen);
DiskObject->do_ToolTypes=OldToolTypes;
FreeVec ((APTR)NewToolTypes);
FreeDiskObject (DiskObject);
}
/*
Our "InputHandler"
*/
VOID_INTERRUPT BlankerAction(CxMsg *CxMsg,CxObj *CO)
{
struct InputEvent *IE;
IE=(struct InputEvent *)CxMsgData(CxMsg);
if (IE->ie_Class==IECLASS_TIMER)
{
if (TimeLeft)
{
TimeLeft--;
if (TimeLeft==0L) Signal (BlankerServerProcess,1L<<bsp_TimeOut);
}
}
else
{
Signal (BlankerServerProcess,1L<<bsp_InputSig);
TimeLeft=InitTimeLeft;
}
}
/*
Functions for Handling the Configuration Window
*/
LONG GetNum(struct Gadget *Gadget,LONG *Data,LONG Max)
{
LONG NewData;
NewData=((struct StringInfo *)Gadget->SpecialInfo)->LongInt;
if ((NewData<1L)||(NewData>Max))
{
GT_SetGadgetAttrs (Gadget,BlankerWindow,NULL,GTIN_Number,(ULONG)*Data,
TAG_DONE);
return FALSE;
}
else
{
*Data=NewData;
return TRUE;
}
}
void CloseBlankerWindow(void)
{
if (BlankerContext)
{
if (BlankerWindow)
{
LeftEdge=BlankerWindow->LeftEdge;
TopEdge=BlankerWindow->TopEdge;
ClearMenuStrip (BlankerWindow);
if (BlankerVisualInfo)
{
FreeVisualInfo (BlankerVisualInfo);
BlankerVisualInfo=NULL;
if (BlankerMenu)
{
FreeMenus (BlankerMenu);
BlankerMenu=NULL;
}
}
CloseWindow (BlankerWindow);
BlankerWindow=NULL;
}
FreeGadgets (BlankerContext);
BlankerContext=NULL;
}
}
void OpenBlankerWindow(void)
{
struct Gadget *Ptr;
UWORD Index;
if (BlankerWindow==NULL)
{
struct NewGadget NewGadget;
BlankerContext=NULL;
if ((Ptr=CreateContext(&BlankerContext))==NULL) return;
if ((BlankerWindow=OpenWindowTags(NULL,
WA_Left,LeftEdge,
WA_Top,TopEdge,
WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
IDCMP_VANILLAKEY|IDCMP_MENUPICK|LISTVIEWIDCMP,
WA_Flags,WFLG_DRAGBAR|WFLG_DEPTHGADGET|
WFLG_CLOSEGADGET|WFLG_SIMPLE_REFRESH|
WFLG_NEWLOOKMENUS,
WA_Title,
(ULONG)"Rotor V1.01 © 1993 by Illenseer",
WA_AutoAdjust,TRUE,
WA_InnerWidth,512,
WA_InnerHeight,117L,TAG_DONE))==NULL)
{
CloseBlankerWindow();
return;
}
if ((BlankerVisualInfo=GetVisualInfo(BlankerWindow->WScreen,TAG_DONE))==NULL)
{
CloseBlankerWindow();
return;
}
if (!WBStarted)
{
NewBlankerMenus[1].nm_Flags|=NM_ITEMDISABLED;
NewBlankerMenus[2].nm_Flags|=NM_ITEMDISABLED;
}
if ((BlankerMenu=CreateMenus(NewBlankerMenus,
GTMN_FullMenu,TRUE,
TAG_DONE))==NULL)
{
CloseBlankerWindow();
return;
}
if (!LayoutMenus(BlankerMenu,BlankerVisualInfo,
GTMN_NewLookMenus,TRUE,TAG_DONE))
{
CloseBlankerWindow();
return;
}
else SetMenuStrip (BlankerWindow,BlankerMenu);
BlankerGadgetTags[0].ti_Data=(ULONG)ModeList;
BlankerGadgetTags[1].ti_Data=(ULONG)DisplayMode->mn_Index;
BlankerGadgetTags[4].ti_Data=(ULONG)TimeOut;
BlankerGadgetTags[7].ti_Data=(ULONG)ClientTimeOut;
BlankerGadgetTags[13].ti_Data=(ULONG)PopKey;
BlankerGadgetTags[16].ti_Data=(ULONG)BlankKey;
BlankerGadgetTags[10].ti_Data=(ULONG)&MouseBlankMethods[0];
BlankerGadgetTags[11].ti_Data=(ULONG)MouseBlank;
BlankerGadgetTags[21].ti_Data=(ULONG)Change;
BlankerGadgetTags[29].ti_Data=(ULONG)Trail;
BlankerGadgetTags[35].ti_Data=(ULONG)Cycle;
for (Index=0L; Index<NUM_GADS; Index++)
{
NewGadget=NewBlankerGadgets[Index];
NewGadget.ng_TopEdge+=BlankerWindow->BorderTop;
NewGadget.ng_VisualInfo=BlankerVisualInfo;
Ptr=CreateGadget((ULONG)BlankerGadgetKinds[Index],Ptr,&NewGadget,
GT_Underscore,(ULONG)'_',TAG_MORE,
&BlankerGadgetTags[BlankerTagsIndex[Index]]);
if ((BlankerGadgets[Index]=Ptr)==NULL)
{
CloseBlankerWindow();
return;
}
}
AddGList (BlankerWindow,BlankerContext,0L,-1L,NULL);
RefreshGadgets (BlankerContext,BlankerWindow,NULL);
GT_RefreshWindow (BlankerWindow,NULL);
}
ScreenToFront (BlankerWindow->WScreen);
WindowToFront (BlankerWindow);
ActivateWindow (BlankerWindow);
}
void About(void)
{
ULONG IDCMPFlags;
IDCMPFlags=0L;
(void)EasyRequestArgs(NULL,&AboutEasyStruct,&IDCMPFlags,NULL);
}
/*
Function to handle the Commodity Stuff
*/
void REGARGS HandleCxMsg(CxMsg *CxMsg)
{
ULONG MsgType,MsgID;
MsgType=CxMsgType(CxMsg);
MsgID=CxMsgID(CxMsg);
ReplyMsg ((struct Message *)CxMsg);
switch (MsgType)
{
case CXM_IEVENT: /* PopKey was pressed */
if (MsgID==EVENT_BLANK) InitTimeLeft=2L;
else OpenBlankerWindow();
break;
case CXM_COMMAND:
switch (MsgID)
{
case CXCMD_DISABLE:
/* Message created by Exchange (except CXCMD_UNIQUE) */
(void)ActivateCxObj(Broker,FALSE);
break;
case CXCMD_ENABLE:
(void)ActivateCxObj(Broker,TRUE);
break;
case CXCMD_UNIQUE:
case CXCMD_APPEAR:
OpenBlankerWindow();
break;
case CXCMD_DISAPPEAR:
CloseBlankerWindow();
break;
case CXCMD_KILL:
exit (0);
}
}
}
CxObj REGARGS *InstallHotKey(CxObj *Filter,char *Describ,LONG Event,
char *Default)
{
if (Filter)
{
RemoveCxObj (Filter);
DeleteCxObj (Filter);
}
if (Filter=HotKey(Describ,CxPort,Event))
if (CxObjError(Filter)==0L)
{
AttachCxObj (Broker,Filter);
return Filter;
}
else DeleteCxObj (Filter);
if (Filter=HotKey(Default,CxPort,Event))
if (CxObjError(Filter)==0L)
{
AttachCxObj (Broker,Filter);
(void)strcpy(Describ,Default);
return Filter;
}
else DeleteCxObj (Filter);
(void)strcpy(Describ,"<NONE>");
return NULL;
}
/*
Functions fore Creating/Deleting the Client Process
*/
VOID_STDARGS DeleteBlankerClient(struct MsgPort *BlankerClientPort,
struct BlankerClientMsg *BlankerClientMsg)
{
Forbid();
PutMsg (BlankerClientPort,(struct Message *)BlankerClientMsg);
(void)SetTaskPri(BlankerClientPort->mp_SigTask,SERVER_PRI+1L);
Permit();
(void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
(void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
}
struct MsgPort *REGARGS CreateBlankerClient(void *CodePtr,
struct BlankerClientMsg *BlankerClientMsg)
{
struct Process *BlankerClientProcess;
if (BlankerClientProcess=CreateNewProcTags(NP_Entry,CodePtr,
NP_Name,"Rotor_BlankerClient",
NP_StackSize,4000L,TAG_DONE))
{
PutMsg (&BlankerClientProcess->pr_MsgPort,
(struct Message *)BlankerClientMsg);
(void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
(void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
(void)SetTaskPri((struct Task *)BlankerClientProcess,CLIENT_PRI);
if (BlankerClientMsg->bcm_Status) return &BlankerClientProcess->pr_MsgPort;
}
return NULL;
}
/*
Open a Screen with the supplied DisplayID
*/
void SpritesOff(void)
{
ULONG Index;
if (MouseBlank)
{
FreeSprite (0); /* hack required for DOMINO-Gfx-Board */
GfxBase->SpriteReserved|=1;
}
else
{
OFF_SPRITE /* switch sprites off */
for (Index=0L; Index<8L; Index++) custom.spr[Index].ctl=0;
}
}
struct Screen *CreateScreen(struct List *ModeList,struct ModeNode *ModeNode)
{
struct Screen *Screen;
if (Screen=OpenScreenTags(NULL,
SA_Depth,1,
SA_Title,"Rotor",
SA_DisplayID,ModeNode->mn_DisplayID,
SA_Quiet,TRUE,TAG_DONE))
{
SetRGB4 (&Screen->ViewPort,0,0,0,0);
SetRast (&Screen->RastPort,0);
SpritesOff();
}
return Screen;
}
/*
Functions for Creating/Drawing/Removing the Gfx
*/
/* Ill's strange and genius Random Function :-) */
UWORD REGARGS Random(UWORD Max)
{
static ULONG Num=0L; /* So the last random-number is still stored ! */
ULONG Sec,Mic;
CurrentTime((LONG *)&Sec,(LONG *)&Mic);
Num*=Sec;
Num+=Mic;
while (Num>32767L) Num=Num>>1;
return (UWORD)(Num%Max);
}
ULONG RotorSize(LONG elems)
{
return sizeof(struct flightstruct);
}
struct flightstruct *REGARGS CreateRotor(struct Screen *RotorScreen,int Trail)
/* allocate Memory and such */
{
flightstruct *fs; /* !!!!!!!!!!!!!! */
int x;
struct elem *pelem;
if((fs=AllocVec(RotorSize(DEFAULTCOUNT),MEMF_ANY | MEMF_CLEAR))==NULL) return NULL;
fs->centerx = (RotorScreen->Width / 2);
fs->centery = (RotorScreen->Height / 2);
fs->firsttime = TRUE;
fs->height=RotorScreen->Height;
fs->width=RotorScreen->Width;
fs->smallscreen = fs->width < 320; /* Oops ? Screenmode below LowRes ? */
fs->num = DEFAULTCOUNT;
fs->Trail = Trail;
if (fs->elements == NULL) {
if ((fs->elements = (struct elem *) malloc(sizeof(struct elem) * fs->num)) == NULL) {
exit (10);
}
}
if (fs->savex == NULL) {
if ((fs->savex= (int *) calloc(sizeof(int) , Trail)) == NULL) {
exit (10);
}
}
if (fs->savey == NULL) {
if ((fs->savey= (int *) calloc(sizeof(int) , Trail)) == NULL) {
exit (10);
}
}
pelem = fs->elements;
for (x = fs->num; --x >= 0; pelem++) {
pelem->radius_drift_max = 1.0;
pelem->radius_drift_now = 1.0;
pelem->end_radius = fs->height/5.0;
pelem->ratio_drift_max = 1.0;
pelem->ratio_drift_now = 1.0;
pelem->end_ratio = 10.0;
}
fs->rotor = 0;
fs->prev = 1;
fs->lastx = fs->centerx;
fs->lasty = fs->centery;
fs->angle = (float)(Random(MAXANGLE)) / 3;
fs->forward = fs->firsttime = TRUE;
return fs;
}
void REGARGS DrawRotor(struct RastPort *RP,struct flightstruct *fs)
{
register struct elem *pelem;
int thisx,
thisy;
int i,
rp;
int x1,
y1,
x2,
y2;
#define CAT(X,Y) X##Y
#define SCALE(W,N) CAT(W,N)=(CAT(fs->center,W)) +((CAT(W,N) - CAT(fs->center,W))/2)
#define SCALEIFSMALL() if (fs->smallscreen) { \
SCALE(x,1); SCALE(x,2); \
SCALE(y,1); SCALE(y,2); \
}
for (rp = 0; rp < REPS; rp++) {
thisx = fs->centerx;
thisy = fs->centery;
for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) {
if (pelem->radius_drift_max <= pelem->radius_drift_now) {
pelem->start_radius = pelem->end_radius;
pelem->end_radius = (float) (Random(40000)) / 100.0 - 200.0;
pelem->radius_drift_max = (float) (Random(65375)+Random(34464)) + 10000.0;
pelem->radius_drift_now = 0.0;
}
if (pelem->ratio_drift_max <= pelem->ratio_drift_now) {
pelem->start_ratio = pelem->end_ratio;
pelem->end_ratio = (float) (Random(2000)) / 100.0 - 10.0;
pelem->ratio_drift_max = (float) (Random(65375)+Random(34464)) + 10000.0;
pelem->ratio_drift_now = 0.0;
}
pelem->ratio = pelem->start_ratio + (pelem->end_ratio - pelem->start_ratio) /
pelem->ratio_drift_max * pelem->ratio_drift_now;
pelem->angle = fs->angle * pelem->ratio;
pelem->radius = pelem->start_radius + (pelem->end_radius - pelem->start_radius) /
pelem->radius_drift_max * pelem->radius_drift_now;
thisx += (int) (cos(pelem->angle) * pelem->radius);
thisy += (int) (sin(pelem->angle) * pelem->radius);
if (thisx<BORDER) thisx=BORDER;
if (thisx>fs->width-BORDER-1) thisx=fs->width-BORDER-1;
if (thisy<BORDER) thisy=BORDER;
if (thisy>fs->height-BORDER-1) thisy=fs->height-BORDER-1;
pelem->ratio_drift_now += 1.0;
pelem->radius_drift_now += 1.0;
}
if (fs->firsttime)
fs->firsttime = FALSE;
else {
x1 = (int) fs->savex[fs->rotor];
y1 = (int) fs->savey[fs->rotor];
x2 = (int) fs->savex[fs->prev];
y2 = (int) fs->savey[fs->prev];
SCALEIFSMALL();
SetAPen(RP,0);
Move(RP,x1, y1);
Draw(RP,x2, y2);
x1 = fs->lastx;
y1 = fs->lasty;
x2 = thisx;
y2 = thisy;
SCALEIFSMALL();
SetAPen(RP,1);
Move(RP,x1, y1);
Draw(RP,x2, y2);
}
fs->savex[fs->rotor] = fs->lastx = thisx;
fs->savey[fs->rotor] = fs->lasty = thisy;
++fs->rotor;
fs->rotor %= Trail;
++fs->prev;
fs->prev %= Trail;
if (fs->forward) {
fs->angle += 0.01;
if (fs->angle >= MAXANGLE) {
fs->angle = MAXANGLE;
fs->forward = FALSE;
}
}
else {
fs->angle -= 0.1;
if (fs->angle <= 0) {
fs->angle = 0.0;
fs->forward = TRUE;
}
}
}
}
/*
This is the Client Process's Main Loop
*/
VOID_INTERRUPT RotorClientProcess(void)
{
struct BlankerClientMsg *BlankerClientMsg;
struct MsgPort *BlankerClientPort;
struct Task *BlankerServerTask;
ULONG BlankerServerSigMask;
struct Screen *RotorScreen;
struct flightstruct *fs;
LONG Change,Trail,Cycle;
WORD Color,DColor;
WORD Count;
/* wait for Server's initial Message */
BlankerClientPort=FINDPROCPORT;
(void)WaitPort(BlankerClientPort);
BlankerClientMsg=(struct BlankerClientMsg *)GetMsg(BlankerClientPort);
BlankerServerTask=BlankerClientMsg->bcm_Message.mn_ReplyPort->mp_SigTask;
BlankerServerSigMask=BlankerClientMsg->bcm_SigMask;
Change=BlankerClientMsg->bcm_Change;
Trail=BlankerClientMsg->bcm_Trail;
Cycle=BlankerClientMsg->bcm_Cycle;
RotorScreen=BlankerClientMsg->bcm_Screen;
if ((fs=CreateRotor(RotorScreen,Trail))==NULL)
{
BlankerClientMsg->bcm_Status=FALSE;
Forbid();
ReplyMsg ((struct Message *)BlankerClientMsg);
return;
}
BlankerClientMsg->bcm_Status=TRUE;
ReplyMsg ((struct Message *)BlankerClientMsg);
Color=ROTOR_COL_NUM-1;
DColor=Cycle?1:0;
Count=1;
while ((BlankerClientMsg=(struct BlankerClientMsg *)
GetMsg(BlankerClientPort))==NULL)
{
/* Color Cycling */
Colors[1]=RotorColors[Color];
LoadRGB4 (&RotorScreen->ViewPort,Colors,4);
Color+=DColor;
if ((Color==-1)||(Color==ROTOR_COL_NUM))
{
DColor=-DColor;
Color+=2*DColor;
}
if(Count++>Change) {
fs->rotor = 0;
fs->prev = 1;
fs->lastx = fs->centerx;
fs->lasty = fs->centery;
fs->angle = (float)(Random(MAXANGLE)) / 3;
fs->forward = fs->firsttime = TRUE;
Count=0;
SetRast(&RotorScreen->RastPort,0);
}
DrawRotor(&RotorScreen->RastPort,fs);
if (IntuitionBase->FirstScreen!=RotorScreen)
{
ScreenToFront (RotorScreen);
SpritesOff();
}
Signal (BlankerServerTask,BlankerServerSigMask);
}
FreeVec ((APTR)fs);
/* We are requested to finish, so we do. */
Forbid();
ReplyMsg ((struct Message *)BlankerClientMsg);
}
/*
The Main Loop
*/
void main(LONG argc,UBYTE **argv)
{
CxObj *ObjectList;
struct IntuiMessage *IntMsg;
CxMsg *BlankerCxMsg;
struct Screen *BlankerScreen=NULL;
struct MsgPort *BlankerClientPort=NULL;
/* open our Libraries */
AddTool (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L),
CloseLibrary,0L);
AddTool (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",
37L),CloseLibrary,0L);
AddTool (CxBase=OpenLibrary("commodities.library",37L),CloseLibrary,0L);
AddTool (GadToolsBase=OpenLibrary("gadtools.library",37L),CloseLibrary,0L);
/* create List of Graphics Modes */
AddTool (ModeList=CreateModeList(),DeleteModeList,0L);
/* get some Signals */
BlankerServerProcess=SysBase->ThisTask;
if ((bsp_TimeOut=AllocSignal(-1L))==-1) exit (10);
AddTool ((void *)bsp_TimeOut,FreeSignal,0L);
if ((bsp_InputSig=AllocSignal(-1L))==-1) exit (10);
AddTool ((void *)bsp_InputSig,FreeSignal,0L);
if ((bsp_ClientSig=AllocSignal(-1L))==-1) exit (10);
AddTool ((void *)bsp_ClientSig,FreeSignal,0L);
/* Were we started from Workbench or from CLI ? */
if (WBStarted=(argc==0L))
{
/* Workbench: load Config from DiskObject */
struct WBStartup *WBenchMsg;
AddTool (IconBase=OpenLibrary(ICONNAME,37L),CloseLibrary,0L);
WBenchMsg=(struct WBStartup *)argv;
LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:NULL);
}
else
{
struct RDArgs *RDArgs;
LONG Array[NUMTOOLTYPES];
(void)memset(Array,'\0',sizeof(Array));
if (RDArgs=ReadArgs(Template,Array,NULL))
{
AddTool (RDArgs,FreeArgs,0L);
CxPri=RDArgsLong(Array[0],0L,-128L,127L);
(void)strcpy(PopKey,Array[1]?(char *)Array[1]:DEF_POPKEY);
CxPopUp=Array[2];
(void)strcpy(BlankKey,Array[3]?(char *)Array[3]:DEF_BLANKKEY);
/* get Time Out, Client Time Out and Display mode */
TimeOut=RDArgsLong(Array[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
ClientTimeOut=RDArgsLong(Array[5],DEF_CLIENT_TIMEOUT,1L,
MAX_CLIENT_TIMEOUT);
if ((DisplayMode=FindMode(ModeList,Array[6]?(char *)Array[6]:""))==NULL)
DisplayMode=GetDefaultMode(ModeList);
if (stricmp(Array[7]?(char *)Array[7]:"",MouseBlankMethods[1]))
MouseBlank=0L;
else MouseBlank=1L;
Change=RDArgsLong(Array[8],DEF_CHANGE,1L,MAX_CHANGE);
Trail=RDArgsLong(Array[9],DEF_TRAIL,1L,MAX_TRAIL);
Cycle=Array[10];
}
else
{
PrintFault (IoErr(),"Rotor");
exit (10);
}
}
/* initialize our Broker=install us as a Commodity */
AddTool (CxPort=CreateMsgPort(),DeleteMsgPortSafely,0L);
NewBroker.nb_Pri=(BYTE)CxPri;
NewBroker.nb_Port=CxPort;
AddTool (Broker=CxBroker(&NewBroker,NULL),DeleteCxObjAll,0L);
/* install our Hot Keys */
PopKeyFilter=InstallHotKey(NULL,PopKey,EVENT_OPEN_WINDOW,DEF_POPKEY);
BlankKeyFilter=InstallHotKey(NULL,BlankKey,EVENT_BLANK,DEF_BLANKKEY);
/* install our "InputHandler" */
TimeLeft=InitTimeLeft=TimeOut*10L;
ObjectList=CxCustom(BlankerAction,0L);
AttachCxObj (Broker,ObjectList);
if (CxObjError(ObjectList)) exit (10);
(void)ActivateCxObj(Broker,TRUE);
AddTool (Broker,ActivateCxObj,FALSE);
/* open Window on startup if not forbidden */
AddTool ((void *)-1L,CloseBlankerWindow,0L);
if (CxPopUp) OpenBlankerWindow();
/* increase our Priority */
AddTool (FindTask(NULL),SetTaskPri,(LONG)SetTaskPri(FindTask(NULL),
SERVER_PRI));
/* start the Loop */
FOREVER
{
ULONG Mask;
if (BlankerWindow)
Mask=Wait(MASK(bsp_TimeOut)|MASK(bsp_InputSig)|MASK(bsp_ClientSig)|
MASK(CxPort->mp_SigBit)|MASK(BlankerWindow->UserPort->mp_SigBit)|
SIGBREAKF_CTRL_C);
else
Mask=Wait(MASK(bsp_TimeOut)|MASK(bsp_InputSig)|MASK(bsp_ClientSig)|
MASK(CxPort->mp_SigBit)|SIGBREAKF_CTRL_C);
/* process Window Events */
while ((BlankerWindow!=NULL)&&(IntMsg=GT_GetIMsg(BlankerWindow->UserPort)))
switch (IntMsg->Class)
{
struct Gadget *Clicked;
UWORD Code;
case IDCMP_CLOSEWINDOW:
GT_ReplyIMsg (IntMsg);
CloseBlankerWindow();
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh (BlankerWindow);
GT_EndRefresh (BlankerWindow,TRUE);
break;
case IDCMP_GADGETUP:
Code=IntMsg->Code;
Clicked=(struct Gadget *)IntMsg->IAddress;
GT_ReplyIMsg (IntMsg);
switch (Clicked->GadgetID)
{
case GID_HIDE:
CloseBlankerWindow();
break;
case GID_QUIT:
exit (0);
case GID_BLANK:
InitTimeLeft=2L;
break;
case GID_MODE:
DisplayMode=GetIndexMode(ModeList,Code);
break;
case GID_TIMEOUT:
if (GetNum(Clicked,&TimeOut,MAX_TIMEOUT))
TimeLeft=InitTimeLeft=10L*TimeOut;
break;
case GID_CLIENT:
GetNum(Clicked,&ClientTimeOut,MAX_CLIENT_TIMEOUT);
break;
case GID_MOUSE:
MouseBlank=1L-MouseBlank;
break;
case GID_CHANGE:
Change=Code;
break;
case GID_TRAIL:
Trail=Code;
break;
case GID_POPKEY:
(void)strcpy(PopKey,((struct StringInfo *)
Clicked->SpecialInfo)->Buffer);
PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
DEF_POPKEY);
GT_SetGadgetAttrs (Clicked,BlankerWindow,NULL,GTST_String,PopKey,
TAG_DONE);
break;
case GID_BLANKKEY:
(void)strcpy(BlankKey,((struct StringInfo *)
Clicked->SpecialInfo)->Buffer);
BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
DEF_BLANKKEY);
GT_SetGadgetAttrs (Clicked,BlankerWindow,NULL,GTST_String,BlankKey,
TAG_DONE);
case GID_CYCLE:
Cycle=!Cycle;
break;
}
break;
case IDCMP_MENUPICK:
Code=IntMsg->Code;
GT_ReplyIMsg (IntMsg);
switch (Code)
{
struct WBStartup *WBenchMsg;
case 0xF800:
WBenchMsg=(struct WBStartup *)argv;
LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:
NULL);
PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
DEF_POPKEY);
BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
DEF_BLANKKEY);
break;
case 0xF820:
WBenchMsg=(struct WBStartup *)argv;
if (WBenchMsg->sm_NumArgs) SaveConfig(WBenchMsg->sm_ArgList->wa_Name);
break;
case 0xF860:
About();
break;
case 0xF8A0:
CloseBlankerWindow();
break;
case 0xF8C0:
exit (0);
break;
case 0xF801:
LoadConfig (NULL);
PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
DEF_POPKEY);
BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
DEF_BLANKKEY);
}
break;
case IDCMP_VANILLAKEY:
Code=IntMsg->Code;
GT_ReplyIMsg (IntMsg);
switch ((char)Code)
{
case 'H':
case 'h':
CloseBlankerWindow();
break;
case 'Q':
case 'q':
exit (0);
case 'B':
case 'b':
InitTimeLeft=2L;
break;
case 'I':
case 'i':
ActivateGadget (BlankerGadgets[GID_TIMEOUT],BlankerWindow,NULL);
break;
case 'L':
case 'l':
ActivateGadget (BlankerGadgets[GID_CLIENT],BlankerWindow,NULL);
break;
case 'P':
case 'p':
ActivateGadget (BlankerGadgets[GID_POPKEY],BlankerWindow,NULL);
break;
case 'K':
case 'k':
ActivateGadget (BlankerGadgets[GID_BLANKKEY],BlankerWindow,NULL);
break;
case 'M':
case 'm':
MouseBlank=1L-MouseBlank;
GT_SetGadgetAttrs (BlankerGadgets[GID_MOUSE],BlankerWindow,
NULL,GTCY_Active,MouseBlank,TAG_DONE);
break;
case 'C':
if (Change>1 && Change-10>1)
{
Change-=10;
GT_SetGadgetAttrs (BlankerGadgets[GID_CHANGE],BlankerWindow,
NULL,GTSL_Level,Change,TAG_DONE);
}
break;
case 'c':
if (Change<MAX_CHANGE && Change+10<=MAX_CHANGE)
{
Change+=10;
GT_SetGadgetAttrs (BlankerGadgets[GID_CHANGE],BlankerWindow,
NULL,GTSL_Level,Change,TAG_DONE);
}
break;
case 'T':
if (Trail>2 && Trail-10>2)
{
Trail-=10;
GT_SetGadgetAttrs (BlankerGadgets[GID_TRAIL],BlankerWindow,
NULL,GTSL_Level,Trail,TAG_DONE);
}
break;
case 't':
if (Trail<=MAX_TRAIL && Trail+10<=MAX_TRAIL)
{
Trail+=10;
GT_SetGadgetAttrs (BlankerGadgets[GID_TRAIL],BlankerWindow,
NULL,GTSL_Level,Trail,TAG_DONE);
}
break;
case 'O':
case 'o':
Cycle=!Cycle;
GT_SetGadgetAttrs (BlankerGadgets[GID_CYCLE],BlankerWindow,
NULL,GTCB_Checked,Cycle,TAG_DONE);
break;
}
break;
default:
GT_ReplyIMsg (IntMsg);
}
/* process Commodity Messages */
while (BlankerCxMsg=(CxMsg *)GetMsg(CxPort)) HandleCxMsg (BlankerCxMsg);
/* check for <CTRL>-C */
if (Mask&SIGBREAKF_CTRL_C) exit (0);
/* Input detected, unblank if necessary */
if (Mask&MASK(bsp_InputSig))
{
if (BlankerScreen)
{
if (BlankerClientPort) RemTool (BlankerClientPort);
RemTool (BlankerScreen);
BlankerScreen=NULL;
InitTimeLeft=TimeOut*10L;
ON_SPRITE
}
TimeLeft=InitTimeLeft;
}
/* client has confirmed that it is still alive */
if (Mask&MASK(bsp_ClientSig)) TimeLeft=InitTimeLeft;
/* time run out */
if (TimeLeft==0L)
if (BlankerScreen)
{
TimeLeft=10L; /* check again after on second to keep screen in front */
SetRGB4 (&BlankerScreen->ViewPort,0,0,0,0);
SetRGB4 (&BlankerScreen->ViewPort,1,0,0,0);
if (IntuitionBase->FirstScreen!=BlankerScreen)
{
ScreenToFront (BlankerScreen);
SpritesOff();
}
/* Client Time Out reached, turn entire screen black */
}
else
{
AddTool (BlankerScreen=CreateScreen(ModeList,DisplayMode),
CloseScreen,0L);
BlankerClientMsg.bcm_Message.mn_Node.ln_Type=NT_MESSAGE;
BlankerClientMsg.bcm_Message.mn_Node.ln_Pri=0;
BlankerClientMsg.bcm_Message.mn_Length=sizeof(struct BlankerClientMsg);
BlankerClientMsg.bcm_Message.mn_ReplyPort=FINDPROCPORT;
BlankerClientMsg.bcm_Screen=BlankerScreen;
BlankerClientMsg.bcm_SigMask=1L<<bsp_ClientSig;
BlankerClientMsg.bcm_Change=Change;
BlankerClientMsg.bcm_Trail=Trail;
BlankerClientMsg.bcm_Cycle=Cycle;
/* try to start Client */
if (BlankerClientPort=CreateBlankerClient(RotorClientProcess,
&BlankerClientMsg))
{
TimeLeft=InitTimeLeft=10L*ClientTimeOut;
AddTool (BlankerClientPort,DeleteBlankerClient,
(LONG)&BlankerClientMsg);
}
}
}
}