home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 4
/
CDPD_IV.bin
/
fish
/
931-950
/
ff946
/
priman
/
priman.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-22
|
71KB
|
1,830 lines
/*
Task Priority Manager
Copyright 1993 Barry McConnell
bmccnnll@unix1.tcd.ie
*/
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <intuition/screens.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <libraries/commodities.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <stdio.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/diskfont.h>
#include <proto/asl.h>
#include <proto/icon.h>
#include <proto/commodities.h>
#include <proto/wb.h>
#include <clib/alib_protos.h>
#define WINDOWIDCMP IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE | BUTTONIDCMP | LISTVIEWIDCMP | RAWKEY
#define MaxTasks 256 /* talk about a very loaded system... */
#define MaxHotkey 20
#define ScrollBarWidth 16
#define LISTGAD 1
#define SLIDERGAD 2
#define BREAKGAD 3
#define KILLGAD 4
#define SETTINGSGAD 5
#define GFONTGAD 6
#define LFONTGAD 7
#define GBOXGAD 8
#define LBOXGAD 9
#define CONFIRMGAD 10
#define ICONIFYGAD 11
#define SAVEGAD 12
#define USEGAD 13
#define CANCELGAD 14
#define COMGAD 15
#define POPUPGAD 16
#define HOTKEYGAD 17
#define PRIORITYGAD 18
#define OPEN_MAIN 1
#define CLOSE_MAIN 2
#define REDRAW_MAIN 3
#define UPDATE 4
#define OPEN_SETTINGS 5
#define CLOSE_SETTINGS 6
#define NEW_FONT 7
#define QUIT 8
#define LOCK_ERROR 100
#define VISINFO_ERROR 101
#define FONT_ERROR 102
#define GADGET_ERROR 103
#define MAIN_ERROR 104
#define TASK_ERROR 105
#define SETTINGS_ERROR 106
#define CX_ERROR 107
#define ALL_OKAY 200
void __regargs __chkabort(void) {} /* turn off SAS/C v6 CTRL-C checking */
struct listType /* standard Node type with extra space to store the original task structure, so we can find it again */
{
struct Node mainNode;
struct Task *mainTask;
};
extern struct ExecBase *SysBase;
static UBYTE *version = "$VER: PriMan 1.1 (29.09.93)";
int error = 0; /* for passing an error or command between procedures */
UWORD osver = 0; /* Kickstart version */
struct EasyStruct about = /* And the user thought he was getting full online help... */
{
sizeof(struct EasyStruct),
0,
"About PriMan",
"Task Priority Manager v1.1\nFreely Distributable\nCopyright 1993 Barry McConnell\nbmccnnll@unix1.tcd.ie",
"Okay"
};
struct EasyStruct badFilter =
{
sizeof(struct EasyStruct),
0,
"PriMan warning",
"Invalid hotkey -- suggest you change it",
"Okay"
};
UWORD __chip waitPointer[] =
{
0x0000, 0x0000,
0x0400, 0x07c0,
0x0000, 0x07c0,
0x0100, 0x0380,
0x0000, 0x07e0,
0x07c0, 0x1ff8,
0x1ff0, 0x3fec,
0x3ff8, 0x7fde,
0x3ff8, 0x7fbe,
0x7ffc, 0xff7f,
0x7efc, 0xffff,
0x7ffc, 0xffff,
0x3ff8, 0x7ffe,
0x3ff8, 0x7ffe,
0x1ff0, 0x3ffc,
0x07c0, 0x1ff8,
0x0000, 0x07e0,
0x0000, 0x0000,
};
/*
Display a busy pointer in the current window, and prevent user from clicking on any gadgets.
*/
void busyPointer(struct Window *mainWindow, struct Window *setWindow, struct Requester *req1, struct Requester *req2)
{
mainWindow -> UserData = (BYTE *)(mainWindow -> MinWidth << 16 | mainWindow -> MinHeight); /* sneaky!! */
WindowLimits(mainWindow, mainWindow -> Width, mainWindow -> Height, mainWindow -> Width, mainWindow -> Height);
InitRequester(req1);
Request(req1, mainWindow);
if (osver < 39)
SetPointer(mainWindow, waitPointer, 16, 16, -6, 0);
else
SetWindowPointer(mainWindow, WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_END);
if (setWindow)
{
InitRequester(req2);
Request(req2, setWindow);
if (osver < 39)
SetPointer(setWindow, waitPointer, 16, 16, -6, 0);
else
SetWindowPointer(setWindow, WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_END);
}
}
/*
Restore the pointer to normal.
*/
void normalPointer(struct Window *mainWindow, struct Window *setWindow, struct Requester *req1, struct Requester *req2)
{
ClearPointer(mainWindow);
EndRequest(req1, mainWindow);
WindowLimits(mainWindow, (LONG)(mainWindow -> UserData) >> 16, (LONG)(mainWindow -> UserData) & 0xffff, ~0, ~0); /* restore limits */
if (setWindow)
{
ClearPointer(setWindow);
EndRequest(req2, setWindow);
}
}
/*
Join a task name and its priority together. Extra spaces are placed between the
two components to make the string an exact length. If the task has an appropriate
CLI number, that will be added in before its name. The task name will be truncated
if there is not enough room to fit it (and its name) in length. There must be
length+1 bytes free in dest, because of the \0 char.
*/
void createString(struct Task *task, char *dest, int length)
{
int numLen, cli, i = 0, j = 0;
char digits[5], clitext[11];
char *name;
APTR bstr;
BYTE maxlen = -1; /* normally won't be used */
numLen = sprintf(digits, "%d", task -> tc_Node.ln_Pri); /* saves me writing an integer -> ASCII routine */
if (((task -> tc_Node.ln_Type) == NT_PROCESS) && (cli = ((struct Process *)task) -> pr_TaskNum)) /* is it a process with a CLI attached? */
{
sprintf(clitext, "CLI #%d: ", cli);
for (; (i < length - numLen - 1) && clitext[i]; i++) /* might have to disard some of the characters */
dest[i] = clitext[i];
bstr = BADDR(((struct CommandLineInterface *)(BADDR(((struct Process *)task) -> pr_CLI))) -> cli_CommandName);
name = (char *)(bstr)+1;
maxlen = *((BYTE *)bstr);
}
else
name = task -> tc_Node.ln_Name;
for (; (i < length - numLen - 1) && name[j] && maxlen; i++, j++, maxlen--)
dest[i] = name[j];
do
dest[i++] = ' ';
while (i < length - numLen);
j = 0;
do
dest[i++] = digits[j];
while (digits[j++]);
}
/*
Join together a font name up to the ".", and its size.
*/
void fontString(struct TextAttr *font, char *dest)
{
int i = 0;
while (!((font -> ta_Name)[i] == '.'))
*(dest++) = (font -> ta_Name)[i++];
sprintf(dest, " %d", font -> ta_YSize);
}
/*
Compare two strings. Like "strcmp" but case-insensitive.
*/
int Compare(char *s, char *t)
{
for (; ((*s & ~32) == (*t & ~32)) && *s; s++, t++) /* sorry, K&R ;-) */
;
return (*s & ~32) - (*t & ~32);
}
/*
Safely close a window that might have a shared IDCMP.
*/
void CloseWindowSafely(struct Window *window)
{
struct IntuiMessage *msg;
struct Node *succ;
Forbid(); /* keep out of race conditions with Intuition */
msg = (struct IntuiMessage *)window -> UserPort -> mp_MsgList.lh_Head; /* going to look at waiting messages for this window */
while (succ = msg -> ExecMessage.mn_Node.ln_Succ)
{
if (msg -> IDCMPWindow == window) /* referring to us? */
{
Remove((struct Node *)msg);
ReplyMsg((struct Message *)msg);
}
msg = (struct IntuiMessage *)succ; /* we aren't relying on a freed pointer */
}
window -> UserPort = NULL; /* to stop Intuition freeing it */
ModifyIDCMP(window, NULL); /* we don't want any more messages here */
Permit();
CloseWindow(window);
}
/*
Close a window (if it's open) and free up its gadget list.
*/
void FreeWindow(struct Window **window, struct Gadget *glist)
{
if (*window)
{
CloseWindowSafely(*window);
FreeGadgets(glist);
*window = NULL;
}
}
/*
Remember the co-ordinates of the main window before closing it.
*/
void GetPos(struct Window *window, WORD *winLeft, WORD *winTop, WORD *winWidth, WORD *winHeight)
{
if (window)
{
*winLeft = window -> LeftEdge;
*winTop = window -> TopEdge;
*winWidth = window -> Width;
*winHeight = window -> Height;
}
}
/*
Perform all the necessary stuff before opening any windows.
*/
void setup(struct TextFont **propFont, struct TextFont **monoFont,
struct TextAttr *propName, struct TextAttr *monoName,
struct Screen **myScreen, void **visInfo,
WORD *height, WORD *sysWidth, WORD *sysHeight)
{
struct TextExtent fontSize;
if ((*myScreen) = LockPubScreen(NULL))
{
if ((*visInfo) = GetVisualInfo(*myScreen, TAG_END))
{
if (!propName -> ta_YSize || propName -> ta_Name[0] == ' ') /* invalid font structure */
{
propName -> ta_YSize = (*myScreen) -> Font -> ta_YSize;
strcpy(propName -> ta_Name, (*myScreen) -> Font -> ta_Name);
}
if (!monoName -> ta_YSize || monoName -> ta_Name[0] == ' ')
{
monoName -> ta_YSize = GfxBase -> DefaultFont -> tf_YSize;
strcpy(monoName -> ta_Name, GfxBase -> DefaultFont -> tf_Message.mn_Node.ln_Name);
}
if ((*propFont = OpenDiskFont(propName)) && (*monoFont = OpenDiskFont(monoName)))
{
FontExtent(*propFont, &fontSize); /* figure out pixel size of fonts */
*height = fontSize.te_Height;
FontExtent(*monoFont, &fontSize);
*sysHeight = fontSize.te_Height;
*sysWidth = fontSize.te_Width;
}
else
{
error = FONT_ERROR;
FreeVisualInfo(*visInfo);
UnlockPubScreen(NULL, *myScreen);
if (*propFont) /* and it was monoFont that failed to open */
CloseFont(*propFont);
}
}
else
{
error = VISINFO_ERROR;
UnlockPubScreen(NULL, *myScreen);
}
}
else
error = LOCK_ERROR;
}
/*
Free any resources used by setup()
*/
void free(struct TextFont **propFont, struct TextFont *monoFont, void *visInfo, struct Screen *myScreen)
{
if (*propFont)
{
CloseFont(*propFont);
CloseFont(monoFont);
FreeVisualInfo(visInfo);
UnlockPubScreen(NULL, myScreen);
*propFont = NULL;
}
}
/*
Set up the Commodity interface
*/
void setupCommodity(char *hotkey, struct MsgPort *port, struct Window *mainWindow, struct Window *setWindow,
struct NewBroker *newBroker, CxObj **broker, CxObj **filter, CxObj **sender, CxObj **translate)
{
LONG brokerError;
if (*broker = CxBroker(newBroker, &brokerError))
{
if (*filter = CxFilter(hotkey))
{
AttachCxObj(*broker, *filter);
if (*sender = CxSender(port, 1))
{
AttachCxObj(*filter, *sender);
if (*translate = CxTranslate(NULL))
{
AttachCxObj(*filter, *translate);
ActivateCxObj(*broker, 1);
if (CxObjError(*filter) == COERR_BADFILTER)
EasyRequest(NULL, &badFilter, NULL, NULL);
}
else
error = CX_ERROR;
}
else
error = CX_ERROR;
}
else
error = CX_ERROR;
}
else
error = brokerError == CBERR_DUP ? ALL_OKAY : CX_ERROR; /* already running? */
}
/*
Layout the gadgets for the main window, and open it.
*/
void openMainWindow(struct Window **mainWindow, struct Screen *myScreen, struct Gadget **mainGads,
struct Gadget **listGad, struct Gadget **sliderGad,
struct Gadget **breakGad, struct Gadget **killGad,
struct TextFont *propFont, struct TextAttr *propName, struct TextAttr *monoName,
struct MsgPort *port, void *visInfo, int height, int sysHeight, int sysWidth, int *taskLength,
WORD *windowTop, WORD winLeft, WORD winTop, WORD *winWidth, WORD *winHeight)
{
struct RastPort myRast;
WORD buttonText, listWidth, buttonWidth, minWidth, minHeight;
struct NewGadget myGad;
struct Gadget *prevGad;
struct Image blank = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
InitRastPort(&myRast); /* dummy RastPort for getting string lengths */
myRast.Font = propFont;
buttonText = TextLength(&myRast, "Settings...", 11) + INTERWIDTH * 2;
*windowTop = (myScreen -> WBorTop) + myScreen -> Font -> ta_YSize + 1 + INTERHEIGHT;
listWidth = sysWidth * 7 + ScrollBarWidth + INTERWIDTH * 3 + (osver < 39 ? 4 : 0); /* full width of a small window (a bug in 2.x clips 4 pixels too early) */
buttonWidth = buttonText * 3 + INTERWIDTH * 4; /* width of buttons and spacing */
minWidth = buttonWidth > listWidth ? buttonWidth : listWidth; /* choose between them */
minHeight = *windowTop + sysHeight * (osver < 39 ? 5 : 3) + height + INTERHEIGHT * 8 + 2; /* small ListView (1 or 2 elements) */
if (*winWidth < minWidth) /* so, which is it to be? */
*winWidth = minWidth;
if (*winWidth > myScreen -> Width)
*winWidth = myScreen -> Width;
if (*winHeight < minHeight)
*winHeight = minHeight;
if (*winHeight > myScreen -> Height)
*winHeight = myScreen -> Height;
*taskLength = (*winWidth - ScrollBarWidth - INTERWIDTH * 3 - (osver < 39 ? 4 : 0)) / sysWidth;
*mainGads = NULL; /* begin laying out gadgets for main window */
prevGad = CreateContext(mainGads);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge = *windowTop;
myGad.ng_Width = *winWidth - INTERWIDTH * 2;
myGad.ng_Height = *winHeight - *windowTop - sysHeight - height - INTERHEIGHT * 7 - 2;
myGad.ng_GadgetText = NULL;
myGad.ng_TextAttr = monoName;
myGad.ng_GadgetID = LISTGAD;
myGad.ng_Flags = NULL;
myGad.ng_VisualInfo = visInfo;
prevGad = *listGad = CreateGadget(LISTVIEW_KIND, prevGad, &myGad,
GTLV_Labels, NULL,
GTLV_ShowSelected, NULL,
TAG_END);
if (!(*mainWindow || osver < 39)) /* if possible, silently adjust its height for perfect spacing */
{
*winHeight += (*listGad) -> Height - myGad.ng_Height; /* A bug in 2.x doesn't give the correct value */
myGad.ng_Height = (*listGad) -> Height; /* ListView may have ended up smaller */
}
myGad.ng_LeftEdge += sysWidth * 4 + INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = *winWidth - INTERWIDTH - myGad.ng_LeftEdge;
myGad.ng_Height = sysHeight + INTERHEIGHT;
myGad.ng_GadgetID = SLIDERGAD;
prevGad = *sliderGad = CreateGadget(SLIDER_KIND, prevGad, &myGad,
GTSL_Min, -25,
GTSL_Max, 25,
GTSL_Level, 0,
GTSL_LevelFormat, "%4ld",
GTSL_MaxLevelLen, 4,
GTSL_LevelPlace, PLACETEXT_LEFT,
GA_RelVerify, TRUE,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = buttonText;
myGad.ng_Height = height + INTERHEIGHT;
myGad.ng_GadgetText = "Break";
myGad.ng_TextAttr = propName;
myGad.ng_GadgetID = BREAKGAD;
prevGad = *breakGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge += buttonText + (*winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
myGad.ng_GadgetText = "Kill";
myGad.ng_GadgetID = KILLGAD;
prevGad = *killGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge += buttonText + (*winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
myGad.ng_GadgetText = "Settings...";
myGad.ng_GadgetID = SETTINGSGAD;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
if (prevGad)
{
if (*mainWindow) /* it may already be open and just needs updating */
{
blank.Width = *winWidth - INTERWIDTH * 3 / 2; /* don't blank borders */
blank.Height = *winHeight - *windowTop - INTERHEIGHT * 2 - 2;
EraseImage((*mainWindow) -> RPort, &blank, INTERWIDTH, *windowTop);
RefreshWindowFrame(*mainWindow); /* because it's probably a mess by now... */
AddGList(*mainWindow, *mainGads, ~0, -1, NULL);
RefreshGList(*mainGads, *mainWindow, NULL, -1);
}
else
*mainWindow = OpenWindowTags(NULL, WA_Title, "Task Priority Manager",
WA_Gadgets, *mainGads,
WA_Left, winLeft,
WA_Top, winTop,
WA_Width, *winWidth,
WA_Height, *winHeight,
WA_MinWidth, minWidth,
WA_MinHeight, minHeight,
WA_MaxWidth, ~0,
WA_MaxHeight, ~0,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBBottom, TRUE,
WA_Activate, TRUE,
WA_RMBTrap, TRUE,
WA_PubScreen, myScreen,
TAG_END);
if (*mainWindow) /* either just opened, or else we added the gadget list above */
{
(*mainWindow) -> UserPort = port;
ModifyIDCMP(*mainWindow, WINDOWIDCMP);
GT_RefreshWindow(*mainWindow, NULL);
}
else
{
error = MAIN_ERROR;
FreeGadgets(*mainGads);
}
}
else
{
error = GADGET_ERROR;
FreeGadgets(*mainGads);
}
}
/*
Layout the gadgets for the settings window, and open it.
*/
void openSettingsWindow(struct Window *mainWindow, struct Window **setWindow, struct Screen *myScreen,
struct Gadget **setGads, struct Gadget **propFontGad, struct Gadget **monoFontGad,
struct Gadget **confirmGad, struct Gadget **iconifyGad,
struct Gadget **comGad, struct Gadget **popupGad,
struct Gadget **hotkeyGad, struct Gadget **priorityGad,
struct TextFont *propFont, struct TextAttr *propName, struct TextAttr *monoName,
int height, int sysHeight, int sysWidth, int workbench,
int *newPropFont, int *newMonoFont,
struct MsgPort *port, void *visInfo,
WORD windowTop, WORD *tempPropSize, WORD *tempMonoSize,
WORD confirm, WORD *tempConfirm, WORD iconify, WORD *tempIconify,
WORD commodity, WORD *tempCommodity, WORD popup, WORD *tempPopup,
char *hotkey, BYTE *priority,
char *propString, char *monoString, char *tempPropName, char *tempMonoName)
{
struct RastPort myRast;
struct NewGadget myGad;
struct Gadget *prevGad;
WORD fontText, comText, priText, cancelText, size, button, text, max, comStart, comEnd; /* various dimensions */
*newPropFont = *newMonoFont = 0;
*tempConfirm = confirm; /* so we can restore it if the user clicks "Cancel" */
*tempIconify = iconify;
*tempCommodity = commodity;
*tempPopup = popup;
fontString(propName, propString); /* initial setting for the text box */
fontString(monoName, monoString);
strcpy(tempPropName, propName -> ta_Name); /* initial setting for the font requester */
strcpy(tempMonoName, monoName -> ta_Name);
*tempPropSize = propName -> ta_YSize;
*tempMonoSize = monoName -> ta_YSize;
InitRastPort(&myRast);
myRast.Font = propFont;
size = osver < 39 ? 11 : (height > 10 ? height : 11); /* final size of button */
button = height > size ? (height - size) / 2 : 0; /* amount button needs to be moved below text */
text = size > height ? (size - height) / 2 : 0; /* amount text needs to be moved below button */
max = height > size ? height : size; /* spacing between them */
fontText = TextLength(&myRast, "Gadget Font...", 14) + INTERWIDTH * 2;
comText = TextLength(&myRast, "Commodity Options", 17);
priText = TextLength(&myRast, "Priority", 8);
cancelText = TextLength(&myRast, "Cancel", 6) + INTERWIDTH * 2;
*setGads = NULL;
prevGad = CreateContext(setGads);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge = windowTop;
myGad.ng_Width = fontText;
myGad.ng_Height = height + INTERHEIGHT;
myGad.ng_GadgetText = "Gadget Font...";
myGad.ng_GadgetID = GFONTGAD;
myGad.ng_TextAttr = propName;
myGad.ng_Flags = NULL;
myGad.ng_VisualInfo = visInfo;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
myGad.ng_LeftEdge += fontText + INTERWIDTH;
myGad.ng_Width = mainWindow -> Width - myGad.ng_LeftEdge - INTERWIDTH;
myGad.ng_GadgetText = NULL;
myGad.ng_GadgetID = GBOXGAD;
prevGad = *propFontGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Border, TRUE,
GTTX_Text, propString,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = fontText;
myGad.ng_GadgetText = "List Font...";
myGad.ng_GadgetID = LFONTGAD;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
myGad.ng_LeftEdge += fontText + INTERWIDTH;
myGad.ng_Width = mainWindow -> Width - myGad.ng_LeftEdge - INTERWIDTH;
myGad.ng_GadgetText = NULL;
myGad.ng_GadgetID = LBOXGAD;
prevGad = *monoFontGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Border, TRUE,
GTTX_Text, monoString,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT + button; /* want checkbox and text centered */
myGad.ng_Width = 26;
myGad.ng_Height = size;
myGad.ng_GadgetID = CONFIRMGAD;
prevGad = *confirmGad = CreateGadget(CHECKBOX_KIND, prevGad, &myGad,
GTCB_Scaled, TRUE, /* new in 3.0 */
GTCB_Checked, confirm,
TAG_END);
myGad.ng_LeftEdge += myGad.ng_Width + INTERWIDTH;
myGad.ng_TopEdge += text - button;
myGad.ng_Width = NULL; /* let it figure it out for itself... */
myGad.ng_Height = height;
myGad.ng_GadgetID = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Confirm actions",
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += max + INTERHEIGHT - text + button;
myGad.ng_Width = 26;
myGad.ng_Height = size;
myGad.ng_GadgetID = ICONIFYGAD;
prevGad = *iconifyGad = CreateGadget(CHECKBOX_KIND, prevGad, &myGad,
GTCB_Scaled, TRUE,
GTCB_Checked, iconify,
GA_Disabled, !workbench, /* because we won't know where to get the image from */
TAG_END);
myGad.ng_LeftEdge += myGad.ng_Width + INTERWIDTH;
myGad.ng_TopEdge += text - button;
myGad.ng_Width = NULL;
myGad.ng_Height = height;
myGad.ng_GadgetID = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Iconify when closed",
TAG_END);
myGad.ng_LeftEdge = (mainWindow -> Width - comText) / 2; /* centred */
myGad.ng_TopEdge += max + INTERHEIGHT * 2 - text;
myGad.ng_Width = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Commodity Options",
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH * 2;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT * 2 + button;
myGad.ng_Width = 26;
myGad.ng_Height = size;
myGad.ng_GadgetID = COMGAD;
comStart = myGad.ng_TopEdge - button;
prevGad = *comGad = CreateGadget(CHECKBOX_KIND, prevGad, &myGad,
GTCB_Scaled, TRUE,
GTCB_Checked, commodity,
TAG_END);
myGad.ng_LeftEdge += myGad.ng_Width + INTERWIDTH;
myGad.ng_TopEdge += text - button;
myGad.ng_Width = NULL;
myGad.ng_Height = height;
myGad.ng_GadgetID = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Install as a Commodity",
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH * 2;
myGad.ng_TopEdge += max + INTERHEIGHT - text + button;
myGad.ng_Width = 26;
myGad.ng_Height = size;
myGad.ng_GadgetID = POPUPGAD;
prevGad = *popupGad = CreateGadget(CHECKBOX_KIND, prevGad, &myGad,
GTCB_Scaled, TRUE,
GTCB_Checked, popup,
GA_Disabled, !commodity,
TAG_END);
myGad.ng_LeftEdge += myGad.ng_Width + INTERWIDTH;
myGad.ng_TopEdge += text - button;
myGad.ng_Width = NULL;
myGad.ng_Height = height;
myGad.ng_GadgetID = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Popup when launched",
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH * 2;
myGad.ng_TopEdge += max - text + INTERHEIGHT * 3 / 2 + 1;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Hotkey",
TAG_END);
myGad.ng_LeftEdge += priText + INTERWIDTH;
myGad.ng_TopEdge -= INTERHEIGHT / 2 + 1;
myGad.ng_Width = mainWindow -> Width - priText - INTERWIDTH * 5;
myGad.ng_Height = height + INTERHEIGHT + 2;
myGad.ng_GadgetID = HOTKEYGAD;
prevGad = *hotkeyGad = CreateGadget(STRING_KIND, prevGad, &myGad,
GTST_String, hotkey,
GTST_MaxChars, MaxHotkey,
GA_Disabled, !commodity,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH * 2;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT * 3 / 2 + 1;
myGad.ng_Width = NULL,
myGad.ng_Height = height;
myGad.ng_GadgetID = NULL;
prevGad = CreateGadget(TEXT_KIND, prevGad, &myGad,
GTTX_Text, "Priority",
TAG_END);
myGad.ng_LeftEdge += priText + INTERWIDTH;
myGad.ng_TopEdge -= INTERHEIGHT / 2 + 1;
myGad.ng_Width = priText + INTERWIDTH; /* for lack of a better width... */
myGad.ng_Height = height + INTERHEIGHT + 2;
myGad.ng_GadgetID = PRIORITYGAD;
prevGad = *priorityGad = CreateGadget(INTEGER_KIND, prevGad, &myGad,
GTIN_Number, *priority,
GTIN_MaxChars, 4, /* e.g., -128 */
GA_Disabled, !commodity,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT * 3;
myGad.ng_Width = cancelText;
myGad.ng_Height = height + INTERHEIGHT;
myGad.ng_GadgetText = "Save";
myGad.ng_GadgetID = SAVEGAD;
comEnd = myGad.ng_TopEdge;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
GA_Disabled, !workbench, /* nowhere to write out the settings! */
TAG_END);
myGad.ng_LeftEdge += cancelText + (mainWindow -> Width - INTERWIDTH *2 - cancelText * 3) / 2;
myGad.ng_GadgetText = "Use";
myGad.ng_GadgetID = USEGAD;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
myGad.ng_LeftEdge += cancelText + (mainWindow -> Width - INTERWIDTH *2 - cancelText * 3) / 2;
myGad.ng_GadgetText = "Cancel";
myGad.ng_GadgetID = CANCELGAD;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
if (prevGad)
{
if (*setWindow = OpenWindowTags(NULL, WA_Title, "PriMan Settings",
WA_Gadgets, *setGads,
WA_Left, mainWindow -> LeftEdge,
WA_Top, mainWindow -> TopEdge + windowTop - INTERHEIGHT,
WA_Width, mainWindow -> Width,
WA_Height, myGad.ng_TopEdge + myGad.ng_Height + INTERHEIGHT + 2,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_Activate, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_PubScreen, myScreen,
TAG_END))
{
(*setWindow) -> UserPort = port;
ModifyIDCMP(*setWindow, WINDOWIDCMP);
DrawBevelBox((*setWindow) -> RPort, INTERWIDTH, comStart - INTERHEIGHT,
mainWindow -> Width - INTERWIDTH * 2, comEnd - comStart - INTERHEIGHT,
GTBB_Recessed, TRUE,
GT_VisualInfo, visInfo,
TAG_END);
GT_RefreshWindow(*setWindow, NULL);
}
else
{
error = SETTINGS_ERROR;
FreeGadgets(*setGads);
}
}
else
{
error = GADGET_ERROR;
FreeGadgets(*setGads);
}
}
/*
Generate the task list, and place it in the main window's ListView.
*/
void createList(struct List *taskList, struct Remember **memoryKey, struct Window *mainWindow, int taskLength,
struct Gadget *listGad, struct Gadget *sliderGad, struct Gadget *breakGad, struct Gadget *killGad)
{
struct Task *taskArray[MaxTasks]; /* one kilobyte worth of pointers should be enough! */
int taskCount;
struct Node *execNode;
struct listType *taskNode;
GT_SetGadgetAttrs(listGad, mainWindow, NULL,
GTLV_Labels, ~0,
TAG_END);
FreeRemember(memoryKey, TRUE); /* can't hurt even if it's NULL */
taskArray[0] = FindTask(NULL); /* us */
taskCount = 1; /* first element was this task */
Disable(); /* going to walk Exec's task list */
for (execNode = SysBase -> TaskReady.lh_Head; execNode -> ln_Succ && taskCount < MaxTasks; execNode = execNode -> ln_Succ)
taskArray[taskCount++] = (struct Task *)execNode;
for (execNode = SysBase -> TaskWait.lh_Head; execNode -> ln_Succ && taskCount < MaxTasks; execNode = execNode -> ln_Succ)
taskArray[taskCount++] = (struct Task *)execNode;
Enable();
taskList -> lh_Head = (struct Node *) &(taskList -> lh_Tail);
taskList -> lh_Tail = NULL;
taskList -> lh_TailPred = (struct Node *) &(taskList -> lh_Head);
while (taskCount-- > 0 && !error)
{
if ((taskNode = AllocRemember(memoryKey, sizeof(struct listType), MEMF_ANY))
&& (taskNode -> mainNode.ln_Name = AllocRemember(memoryKey, taskLength + 1, MEMF_ANY)))
{
if (taskArray[taskCount] -> tc_State > 1 && taskArray[taskCount] -> tc_State < 5) /* task hasn't gone away in the meantime */
{
createString(taskArray[taskCount], taskNode -> mainNode.ln_Name, taskLength);
taskNode -> mainNode.ln_Pri = taskArray[taskCount] -> tc_Node.ln_Pri;
taskNode -> mainTask = taskArray[taskCount];
for (execNode = taskList -> lh_Head; (execNode -> ln_Succ) && Compare(execNode -> ln_Name, taskNode -> mainNode.ln_Name) < 0; execNode = execNode -> ln_Succ)
;
Insert(taskList, (struct Node *)taskNode, execNode -> ln_Pred);
}
}
else
{
error = TASK_ERROR;
FreeRemember(memoryKey, TRUE);
}
}
if (!error)
{
GT_SetGadgetAttrs(listGad, mainWindow, NULL,
GTLV_Labels, taskList,
GTLV_Selected, ~0,
TAG_END);
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
GT_SetGadgetAttrs(breakGad, mainWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
GT_SetGadgetAttrs(killGad, mainWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
}
}
/*
Process an input event from the main window.
*/
void handleMainWindow(ULONG class, WORD code, struct Gadget *selectedGad,
struct Window *mainWindow, struct Window *setWindow, struct Gadget *mainGads,
WORD *winLeft, WORD *winTop, WORD *winWidth, WORD *winHeight,
struct Gadget *listGad, struct Gadget *sliderGad,
struct Gadget *breakGad, struct Gadget *killGad,
int *pos, int *wide, WORD confirm,
struct Node **current, struct List *taskList, int taskLength)
{
struct Task *currentTask;
struct List windowList;
struct Remember *windowKey;
struct Node *node;
struct Screen *screen;
struct Window *window;
struct Requester req1, req2;
ULONG ibase;
int button;
struct EasyStruct suicide = /* Dream on... */
{
sizeof(struct EasyStruct),
0,
"PriMan suicide",
"You can't do that!!",
"Whoops"
};
struct EasyStruct lost = /* Oi! Where did that task go? */
{
sizeof(struct EasyStruct),
0,
"PriMan trouble",
"Task was not found!",
"Okay"
};
struct EasyStruct signal =
{
sizeof(struct EasyStruct),
0,
"PriMan warning",
"Really signal `%s'\nwith Ctrl-C?",
"Signal|Cancel"
};
struct EasyStruct kill =
{
sizeof(struct EasyStruct),
0,
"PriMan warning",
"Really remove `%s'?",
"Remove|Cancel"
};
struct EasyStruct close =
{
sizeof(struct EasyStruct),
0,
"PriMan query",
"Close windows belonging\nto this task?",
"Yes|No"
};
switch (class)
{
case IDCMP_CLOSEWINDOW:
error = CLOSE_MAIN;
break;
case IDCMP_NEWSIZE:
error = REDRAW_MAIN;
GetPos(mainWindow, winLeft, winTop, winWidth, winHeight);
RemoveGList(mainWindow, mainGads, -1);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(mainWindow);
GT_EndRefresh(mainWindow, TRUE);
break;
case GADGETUP:
switch (selectedGad -> GadgetID)
{
case LISTGAD:
*pos = code;
for (*current = taskList -> lh_Head; code > 0; *current = (*current) -> ln_Succ, code --) /* find selected task */
;
if (*wide = ((*current) -> ln_Pri < -25 || (*current) -> ln_Pri > 25)) /* wide or narrow scale? */
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL,
GTSL_Min, -128,
GTSL_Max, 127,
TAG_END);
else
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL,
GTSL_Min, -25,
GTSL_Max, 25,
TAG_END);
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL, /* update slider gadget to new task's priority */
GTSL_Level, (*current) -> ln_Pri,
GA_Disabled, FALSE,
TAG_END);
GT_SetGadgetAttrs(breakGad, mainWindow, NULL,
GA_Disabled, FALSE,
TAG_END);
GT_SetGadgetAttrs(killGad, mainWindow, NULL,
GA_Disabled, FALSE,
TAG_END);
break;
case SLIDERGAD:
currentTask = ((struct listType *)(*current)) -> mainTask;
if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4) /* not a valid task */
{
busyPointer(mainWindow, setWindow, &req1, &req2);
EasyRequest(NULL, &lost, NULL, NULL);
normalPointer(mainWindow, setWindow, &req1, &req2);
error = UPDATE;
}
else
{
SetTaskPri(currentTask, (WORD)code);
GT_SetGadgetAttrs(listGad, mainWindow, NULL,
GTLV_Labels, ~0,
TAG_END);
createString(currentTask, (*current) -> ln_Name, taskLength);
(*current) -> ln_Pri = (WORD)code;
GT_SetGadgetAttrs(listGad, mainWindow, NULL,
GTLV_Labels, taskList,
GTLV_Selected, *pos, /* only required under 2.0 */
TAG_END);
}
break;
case BREAKGAD:
case KILLGAD:
if (!(*pos == -1))
{
busyPointer(mainWindow, setWindow, &req1, &req2);
currentTask = ((struct listType *)(*current)) -> mainTask;
if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4) /* not a valid task */
{
EasyRequest(NULL, &lost, NULL, NULL);
error = UPDATE;
}
else
if (currentTask == FindTask(NULL))
EasyRequest(NULL, &suicide, NULL, NULL);
else
{
if (confirm)
button = EasyRequest(NULL, (selectedGad -> GadgetID == BREAKGAD) ? &signal : &kill, NULL, currentTask -> tc_Node.ln_Name);
if (button || !confirm) /* user clicked "Okay" */
{
Disable();
if (currentTask -> tc_State >= 2 && currentTask -> tc_State <= 4) /* paranoid! */
{
if (selectedGad -> GadgetID == BREAKGAD)
{
Signal(currentTask, SIGBREAKF_CTRL_C);
Enable();
Delay(25); /* allow time for task to exit */
}
else
{
SetTaskPri(currentTask, -128); /* we don't want it doing anything behind our backs... */
Enable();
windowList.lh_Head = (struct Node *) &windowList.lh_Tail;
windowList.lh_Tail = NULL;
windowList.lh_TailPred = (struct Node *) &windowList.lh_Head;
windowKey = NULL;
ibase = LockIBase(NULL); /* going to look at all screens & windows in system */
for (screen = IntuitionBase -> FirstScreen; screen; screen = screen -> NextScreen)
for (window = screen -> FirstWindow; window; window = window -> NextWindow)
if (window -> UserPort && (struct Task *)(window -> UserPort -> mp_SigTask) == currentTask)
if (node = AllocRemember(&windowKey, sizeof(struct Node), MEMF_ANY))
{
node -> ln_Name = (char *)window; /* okay, so it's not really a name... */
AddTail(&windowList, node);
}
UnlockIBase(ibase); /* hopefully nothing will sneakily close any of the windows we took a note of */
if (windowList.lh_Head -> ln_Succ) /* something got added to the list */
if (EasyRequest(NULL, &close, NULL, NULL)) /* shall we close these windows? */
for (node = windowList.lh_Head; node -> ln_Succ; node = node -> ln_Succ)
CloseWindowSafely((struct Window *)(node -> ln_Name));
Disable();
if (currentTask -> tc_State >= 2 && currentTask -> tc_State <= 4) /* _really_ paranoid! */
RemTask(currentTask); /* BLAM! */
Enable();
FreeRemember(&windowKey, TRUE);
}
}
error = UPDATE;
}
}
normalPointer(mainWindow, setWindow, &req1, &req2);
}
break;
case SETTINGSGAD:
error = OPEN_SETTINGS;
break;
}
break;
case RAWKEY:
switch (code)
{
case 64:
case 68: /* Space or Return keys */
error = UPDATE;
break;
case 66: /* Tab key */
if (!(*pos == -1)) /* don't change the scale of a disabled slider */
{
if ((*current) -> ln_Pri > -26 && (*current) -> ln_Pri < 26) /* don't want to end up off the scale! */
{
if (*wide = 1 - *wide)
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL,
GTSL_Min, -128,
GTSL_Max, 127,
TAG_END);
else
GT_SetGadgetAttrs(sliderGad, mainWindow, NULL,
GTSL_Min, -25,
GTSL_Max, 25,
TAG_END);
}
}
break;
case 69: /* Escape key */
error = QUIT;
break;
case 95: /* Help key */
busyPointer(mainWindow, setWindow, &req1, &req2);
EasyRequest(NULL, &about, NULL, NULL);
normalPointer(mainWindow, setWindow, &req1, &req2);
break;
}
break;
}
}
/*
Process an input event from the settings window.
*/
void handleSettingsWindow(ULONG class, WORD code, struct MsgPort *port, struct Gadget *selectedGad,
struct Window *mainWindow, struct Window *setWindow,
WORD *tempPropSize, WORD *tempMonoSize, WORD *confirm, WORD *tempConfirm,
WORD *iconify, WORD *tempIconify, WORD iconLeft, WORD iconTop,
WORD *commodity, WORD *tempCommodity, WORD *popup, WORD *tempPopup,
char *hotkey, BYTE *priority,
struct FontRequester *propFontReq, struct FontRequester *monoFontReq,
struct Gadget *propFontGad, struct Gadget *monoFontGad,
struct Gadget *popupGad, struct Gadget *hotkeyGad, struct Gadget *priorityGad,
struct TextAttr *propName, struct TextAttr *monoName,
char *propString, char *monoString, char *tempPropName, char *tempMonoName,
char *myName, WORD windowTop, int *newPropFont, int *newMonoFont,
struct NewBroker *newBroker, CxObj **broker, CxObj **filter, CxObj **sender, CxObj **translate)
{
struct DiskObject *myIcon;
struct Requester req1, req2;
char **oldTools, **currentTool, *newTools[20], empty[16][MAXFONTNAME + 10], *string;
int oldPos, newPos;
switch (class)
{
case IDCMP_CLOSEWINDOW:
error = CLOSE_SETTINGS;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(setWindow);
GT_EndRefresh(setWindow, TRUE);
break;
case GADGETUP:
switch (selectedGad -> GadgetID)
{
case CONFIRMGAD:
*tempConfirm = (selectedGad -> Flags) & GFLG_SELECTED;
break;
case ICONIFYGAD:
*tempIconify = (selectedGad -> Flags) & GFLG_SELECTED;
break;
case COMGAD:
*tempCommodity = (selectedGad -> Flags) & GFLG_SELECTED;
GT_SetGadgetAttrs(popupGad, setWindow, NULL,
GA_Disabled, !*tempCommodity,
TAG_END);
GT_SetGadgetAttrs(hotkeyGad, setWindow, NULL,
GA_Disabled, !*tempCommodity,
TAG_END);
GT_SetGadgetAttrs(priorityGad, setWindow, NULL,
GA_Disabled, !*tempCommodity,
TAG_END);
break;
case POPUPGAD:
*tempPopup = (selectedGad -> Flags) & GFLG_SELECTED;
break;
case GFONTGAD:
busyPointer(mainWindow, setWindow, &req1, &req2);
if (*newPropFont = AslRequestTags(propFontReq, ASL_Hail, "Select Gadget Font",
ASL_FuncFlags, NULL,
ASL_LeftEdge, setWindow -> LeftEdge,
ASL_TopEdge, setWindow -> TopEdge + windowTop - INTERHEIGHT,
ASL_FontName, tempPropName,
ASL_FontHeight, *tempPropSize,
TAG_END))
{
fontString(&(propFontReq -> fo_Attr), propString);
GT_SetGadgetAttrs(propFontGad, setWindow, NULL,
GTTX_Text, propString,
TAG_END);
strcpy(tempPropName, propFontReq -> fo_Attr.ta_Name);
*tempPropSize = propFontReq -> fo_Attr.ta_YSize;
}
normalPointer(mainWindow, setWindow, &req1, &req2);
break;
case LFONTGAD:
busyPointer(mainWindow, setWindow, &req1, &req2);
if (*newMonoFont = AslRequestTags(monoFontReq, ASL_Hail, "Select Task List Font",
ASL_FuncFlags, FONF_FIXEDWIDTH,
ASL_LeftEdge, setWindow -> LeftEdge,
ASL_TopEdge, setWindow -> TopEdge + windowTop - INTERHEIGHT,
ASL_FontName, tempMonoName,
ASL_FontHeight, *tempMonoSize,
TAG_END))
{
fontString(&(monoFontReq -> fo_Attr), monoString);
GT_SetGadgetAttrs(monoFontGad, setWindow, NULL,
GTTX_Text, monoString,
TAG_END);
strcpy(tempMonoName, monoFontReq -> fo_Attr.ta_Name);
*tempMonoSize = monoFontReq -> fo_Attr.ta_YSize;
}
normalPointer(mainWindow, setWindow, &req1, &req2);
break;
case SAVEGAD:
case USEGAD:
busyPointer(mainWindow, setWindow, &req1, &req2); /* there may be a delay writing out to disk */
error = CLOSE_SETTINGS;
strcpy(hotkey, ((struct StringInfo *)hotkeyGad -> SpecialInfo) -> Buffer);
if (*commodity && *tempCommodity) /* going to stick around */
{
SetFilter(*filter, hotkey); /* just in case it changed... */
if (CxObjError(*filter) == COERR_BADFILTER)
EasyRequest(NULL, &badFilter, NULL, NULL);
}
else if (*tempCommodity) /* and it wasn't already a commodity */
setupCommodity(hotkey, port, mainWindow, setWindow,
newBroker, broker, filter, sender, translate);
else /* may or may not have been a commodity, but it's not wanted anyway... */
{
DeleteCxObjAll(*broker);
*broker = NULL;
}
*confirm = *tempConfirm;
*iconify = *tempIconify;
*commodity = *tempCommodity;
*popup = *tempPopup;
*priority = ((struct StringInfo *)priorityGad -> SpecialInfo) -> LongInt;
if (*newPropFont && (strcmp((propFontReq -> fo_Attr).ta_Name, propName -> ta_Name)
|| !((propFontReq -> fo_Attr).ta_YSize == propName -> ta_YSize)))
{
strcpy(propName -> ta_Name, (propFontReq -> fo_Attr).ta_Name);
propName -> ta_YSize = (propFontReq -> fo_Attr).ta_YSize;
error = NEW_FONT;
}
if (*newMonoFont && (strcmp((monoFontReq -> fo_Attr).ta_Name, monoName -> ta_Name)
|| !((monoFontReq -> fo_Attr).ta_YSize == monoName -> ta_YSize)))
{
strcpy(monoName -> ta_Name, (monoFontReq -> fo_Attr).ta_Name);
monoName -> ta_YSize = (monoFontReq -> fo_Attr).ta_YSize;
error = NEW_FONT;
}
if (selectedGad -> GadgetID == SAVEGAD)
{
if (myIcon = GetDiskObject(myName));
{
currentTool = oldTools = myIcon -> do_ToolTypes; /* existing ToolTypes */
oldPos = newPos = 0;
while (string = currentTool[oldPos++])
if (strncmp(string, "COMMODITY", 9) && strncmp(string, "CX_POPUP", 8)
&& strncmp(string, "CX_POPKEY", 9) && strncmp(string, "CX_PRIORITY", 11)
&& strncmp(string, "LEFT", 4) && strncmp(string, "TOP", 3)
&& strncmp(string, "WIDTH", 5) && strncmp(string, "HEIGHT", 6)
&& strncmp(string, "GADFONT", 7) && strncmp(string, "GADSIZE", 7)
&& strncmp(string, "LISTFONT", 8) && strncmp(string, "LISTSIZE", 8)
&& strncmp(string, "ICONLEFT", 8) && strncmp(string, "ICONTOP", 7)
&& strncmp(string, "CONFIRM", 7) && strncmp(string, "ICONIFY", 7)) /* get rid of our ones */
newTools[newPos++] = string;
sprintf(empty[0], "COMMODITY=%s", *commodity ? "YES" : "NO");
sprintf(empty[1], "CX_POPUP=%s", *popup ? "YES" : "NO");
sprintf(empty[2], "CX_POPKEY=%s", hotkey);
sprintf(empty[3], "CX_PRIORITY=%d", *priority);
sprintf(empty[4], "LEFT=%d", mainWindow -> LeftEdge);
sprintf(empty[5], "TOP=%d", mainWindow -> TopEdge);
sprintf(empty[6], "WIDTH=%d", mainWindow -> Width);
sprintf(empty[7], "HEIGHT=%d", mainWindow -> Height);
sprintf(empty[8], "GADFONT=%s", propName -> ta_Name);
sprintf(empty[9], "GADSIZE=%d", propName -> ta_YSize);
sprintf(empty[10], "LISTFONT=%s", monoName -> ta_Name);
sprintf(empty[11], "LISTSIZE=%d", monoName -> ta_YSize);
sprintf(empty[12], "ICONLEFT=%d", iconLeft);
sprintf(empty[13], "ICONTOP=%d", iconTop);
sprintf(empty[14], "CONFIRM=%s", *confirm ? "YES" : "NO");
sprintf(empty[15], "ICONIFY=%s", *iconify ? "YES" : "NO");
for (oldPos = 0; oldPos < 16;)
newTools[newPos++] = empty[oldPos++]; /* write out our ones at end */
newTools[newPos] = NULL; /* end of list */
myIcon -> do_ToolTypes = newTools;
PutDiskObject(myName, myIcon);
myIcon -> do_ToolTypes = oldTools; /* restore original pointer before freeing memory */
FreeDiskObject(myIcon);
}
}
normalPointer(mainWindow, setWindow, &req1, &req2);
break;
case CANCELGAD:
error = CLOSE_SETTINGS;
break;
}
break;
case RAWKEY:
switch (code)
{
case 69: /* Escape key */
error = QUIT;
break;
case 95: /* Help key */
busyPointer(mainWindow, setWindow, &req1, &req2);
EasyRequest(NULL, &about, NULL, NULL);
normalPointer(mainWindow, setWindow, &req1, &req2);
break;
}
break;
}
}
/*
The main loop. Wait for messages to arrive at our port, and call relevant procedures.
*/
void handleMessages(int argc, char *argv[])
{
struct FontRequester *propFontReq, *monoFontReq;
struct DiskObject *myIcon = NULL, *wbIcon = NULL;
struct AppIcon *appIcon = NULL;
struct MsgPort *port;
struct Screen *myScreen = NULL;
struct Window *mainWindow = NULL, *setWindow = NULL, *window;
struct TextFont *propFont = NULL, *monoFont = NULL;
struct Message *message;
struct IntuiMessage *imsg;
struct List taskList;
struct Remember *memoryKey = 0;
struct Node *current;
struct Gadget *mainGads = 0, *setGads = 0, *selectedGad,
*listGad = 0, *sliderGad = 0, *breakGad = 0, *killGad = 0,
*propFontGad = 0, *monoFontGad = 0, *confirmGad, *iconifyGad,
*comGad, *popupGad = 0, *hotkeyGad = 0, *priorityGad = 0;
struct TextAttr propName = { " ", 0, 0, 0 },
monoName = { " ", 0, 0, 0 };
CxObj *broker = NULL, *filter, *sender, *translate;
void *visInfo = NULL;
int workbench = FALSE, /* started from Workbench? */
taskLength = 0, pos, newPropFont, newMonoFont, wide = 0;
UBYTE **tools;
BYTE priority;
ULONG class;
WORD winLeft, winTop, winWidth, winHeight, iconLeft, iconTop, commodity, popup, confirm, iconify = FALSE,
height, sysHeight, sysWidth, code,
tempCommodity, tempPopup, tempConfirm, tempIconify, tempPropSize, tempMonoSize, windowTop = 0;
char *myName = NULL, /* to be filled in from WBStartup message */
hotkey[MaxHotkey + 1],
propString[MAXFONTNAME + 4], monoString[MAXFONTNAME + 4], /* three characters for the size, plus one for the NULL at the end */
tempPropName[MAXFONTNAME + 1], tempMonoName[MAXFONTNAME + 1];
struct NewBroker newBroker =
{
NB_VERSION,
"PriMan",
"PriMan v1.1 by Barry McConnell",
"Task priority manager",
NBU_UNIQUE | NBU_NOTIFY,
COF_SHOW_HIDE,
0, 0, 0
};
osver = SysBase -> LibNode.lib_Version; /* running under 2.0, 3.0, ...? */
port = CreateMsgPort();
tools = ArgArrayInit(argc, argv);
winLeft = (WORD)ArgInt(tools, "LEFT", 150);
winTop = (WORD)ArgInt(tools, "TOP", 50);
winWidth = (WORD)ArgInt(tools, "WIDTH", 220);
winHeight = (WORD)ArgInt(tools, "HEIGHT", 270);
propName.ta_YSize = (UWORD)ArgInt(tools, "GADSIZE", 0);
monoName.ta_YSize = (UWORD)ArgInt(tools, "LISTSIZE", 0);
iconLeft = (WORD)ArgInt(tools, "ICONLEFT", 0);
iconTop = (WORD)ArgInt(tools, "ICONTOP", 0);
priority = (BYTE)ArgInt(tools, "CX_PRIORITY", 0);
strcpy(propName.ta_Name, ArgString(tools, "GADFONT", " "));
strcpy(monoName.ta_Name, ArgString(tools, "LISTFONT", " "));
strncpy(hotkey, ArgString(tools, "CX_POPKEY", "alt p"), MaxHotkey);
confirm = (ArgString(tools, "CONFIRM", "Y")[0] & ~32) != 'N';
commodity = (ArgString(tools, "COMMODITY", "Y")[0] & ~32) !='N';
popup = (ArgString(tools, "CX_POPUP", "Y")[0] & ~32) != 'N';
if (!argc) /* started from Workbench? */
{
myName = ((struct WBStartup *)argv) -> sm_ArgList -> wa_Name;
if (myIcon = GetDiskObject(myName)); /* read in .info file */
{
wbIcon = GetDefDiskObject(WBTOOL);
wbIcon -> do_Gadget.Flags = myIcon -> do_Gadget.Flags;
wbIcon -> do_Gadget.Width = myIcon -> do_Gadget.Width;
wbIcon -> do_Gadget.Height = myIcon -> do_Gadget.Height;
wbIcon -> do_CurrentX = iconLeft;
wbIcon -> do_CurrentY = iconTop;
wbIcon -> do_Gadget.GadgetRender = myIcon -> do_Gadget.GadgetRender;
wbIcon -> do_Gadget.SelectRender = myIcon -> do_Gadget.SelectRender;
wbIcon -> do_Type = NULL;
workbench = TRUE;
iconify = (ArgString(tools, "ICONIFY", "N")[0] & ~32) == 'Y';
}
}
newBroker.nb_Port = port;
newBroker.nb_Pri = priority;
if (commodity)
setupCommodity(hotkey, port, mainWindow, setWindow, &newBroker, &broker, &filter, &sender, &translate);
if (!error)
error = !popup && (iconify || commodity) ? CLOSE_MAIN : OPEN_MAIN;
propFontReq = AllocAslRequest(ASL_FontRequest, NULL);
monoFontReq = AllocAslRequest(ASL_FontRequest, NULL);
while (error < 100) /* i.e. no _real_ error */
{
if (!error) /* nothing left to process? */
{
window = NULL; /* assume it's not from GadTools */
WaitPort(port);
if (message = GetMsg(port))
{
if (((struct AppMessage *)message) -> am_Type == MTYPE_APPICON && ((struct AppMessage *)message) -> am_ID == 42) /* user clicked on AppIcon? */
error = OPEN_MAIN;
else
switch (class = CxMsgType((CxMsg *)message))
{
case CXM_COMMAND:
switch (CxMsgID((CxMsg *)message))
{
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
error = OPEN_MAIN;
break;
case CXCMD_DISAPPEAR:
error = CLOSE_MAIN;
break;
case CXCMD_KILL:
error = QUIT;
break;
}
break;
case CXM_IEVENT: /* user pressed hotkey */
error = OPEN_MAIN;
break;
default: /* must have been from GadTools */
if (imsg = GT_FilterIMsg((struct IntuiMessage *)message))
{
class = imsg -> Class;
selectedGad = imsg -> IAddress;
code = imsg -> Code;
window = imsg -> IDCMPWindow;
GT_PostFilterIMsg(imsg);
}
break;
}
ReplyMsg(message);
if (window && class != IDCMP_INTUITICKS) /* we get this often and don't want to waste time on it */
{
if (window == mainWindow)
handleMainWindow(class, code, selectedGad, mainWindow, setWindow, mainGads,
&winLeft, &winTop, &winWidth, &winHeight,
listGad, sliderGad, breakGad, killGad,
&pos, &wide, confirm,
¤t, &taskList, taskLength);
else if (window == setWindow)
{
handleSettingsWindow(class, code, port, selectedGad, mainWindow, setWindow,
&tempPropSize, &tempMonoSize, &confirm, &tempConfirm,
&iconify, &tempIconify, iconLeft, iconTop,
&commodity, &tempCommodity, &popup, &tempPopup, hotkey, &priority,
propFontReq, monoFontReq, propFontGad, monoFontGad,
popupGad, hotkeyGad, priorityGad, &propName, &monoName,
propString, monoString, tempPropName, tempMonoName,
myName, windowTop, &newPropFont, &newMonoFont,
&newBroker, &broker, &filter, &sender, &translate);
if (error >= 100) /* abort immediately */
{
FreeWindow(&mainWindow, mainGads);
FreeWindow(&setWindow, setGads);
FreeRemember(&memoryKey, TRUE);
free(&propFont, monoFont, visInfo, myScreen);
}
}
}
}
}
switch (error)
{
case OPEN_MAIN:
error = 0;
if (appIcon)
{
RemoveAppIcon(appIcon);
appIcon = NULL;
}
if (mainWindow)
{
WindowToFront(mainWindow);
if (setWindow)
{
WindowToFront(setWindow);
ActivateWindow(setWindow);
}
else
ActivateWindow(mainWindow);
}
else
{
setup(&propFont, &monoFont, &propName, &monoName,
&myScreen, &visInfo, &height, &sysWidth, &sysHeight);
if (!error)
{
openMainWindow(&mainWindow, myScreen, &mainGads,
&listGad, &sliderGad, &breakGad, &killGad,
propFont, &propName, &monoName,
port, visInfo, height, sysHeight, sysWidth, &taskLength,
&windowTop, winLeft, winTop, &winWidth, &winHeight);
if (!error)
error = UPDATE;
}
}
break;
case OPEN_SETTINGS:
error = 0;
if (setWindow) /* already open? */
{
WindowToFront(setWindow);
ActivateWindow(setWindow);
}
else
openSettingsWindow(mainWindow, &setWindow, myScreen,
&setGads, &propFontGad, &monoFontGad, &confirmGad, &iconifyGad,
&comGad, &popupGad, &hotkeyGad, &priorityGad,
propFont, &propName, &monoName, height, sysHeight, sysWidth, workbench,
&newPropFont, &newMonoFont, port, visInfo,
windowTop, &tempPropSize, &tempMonoSize,
confirm, &tempConfirm, iconify, &tempIconify,
commodity, &tempCommodity, popup, &tempPopup, hotkey, &priority,
propString, monoString, tempPropName, tempMonoName);
break;
case CLOSE_MAIN:
if (!(iconify || commodity))
error = QUIT;
else
{
error = 0;
GetPos(mainWindow, &winLeft, &winTop, &winWidth, &winHeight);
FreeWindow(&mainWindow, mainGads);
FreeWindow(&setWindow, setGads);
FreeRemember(&memoryKey, TRUE);
free(&propFont, monoFont, visInfo, myScreen);
if (iconify)
appIcon = AddAppIcon(42, NULL, "PriMan", port, NULL, wbIcon, TAG_END);
}
break;
case REDRAW_MAIN:
error = 0;
FreeGadgets(mainGads);
openMainWindow(&mainWindow, myScreen, &mainGads,
&listGad, &sliderGad, &breakGad, &killGad,
propFont, &propName, &monoName,
port, visInfo, height, sysHeight, sysWidth, &taskLength,
&windowTop, winLeft, winTop, &winWidth, &winHeight);
if (!error)
error = UPDATE;
break;
case UPDATE:
error = 0;
createList(&taskList, &memoryKey, mainWindow, taskLength,
listGad, sliderGad, breakGad, killGad);
pos = -1;
break;
case CLOSE_SETTINGS:
error = 0;
FreeWindow(&setWindow, setGads);
break;
case NEW_FONT:
GetPos(mainWindow, &winLeft, &winTop, &winWidth, &winHeight);
FreeWindow(&setWindow, setGads);
FreeWindow(&mainWindow, mainGads);
free(&propFont, monoFont, visInfo, myScreen);
error = OPEN_MAIN;
break;
case QUIT:
error = ALL_OKAY;
FreeWindow(&mainWindow, mainGads);
FreeWindow(&setWindow, setGads);
FreeRemember(&memoryKey, TRUE);
free(&propFont, monoFont, visInfo, myScreen);
break;
}
}
DeleteCxObjAll(broker);
FreeAslRequest(propFontReq);
FreeAslRequest(monoFontReq);
if (appIcon)
RemoveAppIcon(appIcon);
if (wbIcon)
FreeDiskObject(wbIcon);
if (myIcon)
FreeDiskObject(myIcon);
ArgArrayDone();
Forbid();
while (message = GetMsg(port)) /* clean up */
ReplyMsg(message);
DeleteMsgPort(port);
Permit();
}
/*
Open all libraries, and display any error messages.
*/
void main(int argc, char *argv[])
{
struct EasyStruct errorMessage =
{
sizeof(struct EasyStruct),
0,
"PriMan fatal error",
"%s",
"Okay"
};
if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))
{
if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
{
if (GadToolsBase = OpenLibrary("gadtools.library", 37))
{
if (IconBase = OpenLibrary("icon.library", 37))
{
if (CxBase = OpenLibrary("commodities.library", 37))
{
handleMessages(argc, argv);
if (error)
{
switch (error)
{
case LOCK_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't lock default public screen");
break;
case VISINFO_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't get VisualInfo for this screen");
break;
case FONT_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't open your selected fonts");
break;
case GADGET_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't create list of gadgets\n(Out of memory?)");
break;
case MAIN_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't open main window\n(Out of memory?)");
break;
case TASK_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't create list of tasks\n(Out of memory?)");
break;
case SETTINGS_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't open settings window\n(Out of memory?)");
break;
case CX_ERROR:
EasyRequest(NULL, &errorMessage, NULL, "Can't set up Commodity interface\n");
break;
}
}
CloseLibrary(CxBase);
}
CloseLibrary(IconBase);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
}