home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
fileutil
/
enote.lha
/
src
/
ENote.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-20
|
18KB
|
636 lines
/*** Copyright 1992 by D.W.Reisig. ***/
unsigned char Version[] = "$VER: ENote 1.0 04-May-92 © 1992 D.W.Reisig\n";
unsigned char PrgTitle[] = "ENote 1.0: ";
#include <exec/types.h>
#include <exec/memory.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include "memory.h"
#define COMMENTSIZE 80
#define PUBCLR MEMF_PUBLIC | MEMF_CLEAR
#define CHECK_IOERR -1
#define btst(bitnr,var) ((var)&(1<<(bitnr)))
#define bset(bitnr,var) ((var)|=(1<<(bitnr)))
#define bclr(bitnr,var) ((var)&=~(1<<(bitnr)))
#define bchg(bitnr,var) ((var)^=(1<<(bitnr)))
extern VOID Quit(LONG ReturnValue, LONG Result2);
extern LONG Edit(UBYTE *FileName, struct FileInfoBlock *InfoBlock);
extern struct IntuitionBase *IntuitionBase;
extern struct WBStartup *WBenchMsg;
ULONG StdOut;
UBYTE *ErrMsg, *PrgName;
/*---------------------------------------------------------------------------*/
VOID main(LONG argc, UBYTE *argv[])
{
// static UWORD Pad; // Align FileInfoBlocks if necessary
static struct FileInfoBlock WBInfoBlock, InfoBlock;
static UBYTE NoAccess[] = "Could not access file\n";
UBYTE *FileName;
ULONG FileLock;
LONG EditResult;
if (argc != 0){
StdOut = Output();
PrgName = argv[0];
}
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
if (!IntuitionBase){
ErrMsg = "No Intuition\n";
Quit(RETURN_FAIL, 0);
}
if (argc == 0){
//*** From the Workbench..
ULONG WBLock;
if (WBenchMsg->sm_NumArgs < 2){
ErrMsg = "\nSelect the ENote Icon,\nPress shift,\nAnd double-click another Icon..\n";
Quit(RETURN_ERROR, ERROR_REQUIRED_ARG_MISSING);
}
WBLock = ((struct WBArg *)(WBenchMsg->sm_ArgList)+1)->wa_Lock;
CurrentDir(WBLock);
FileName = ((struct WBArg *)(WBenchMsg->sm_ArgList)+1)->wa_Name;
if (*FileName == '\0'){
//*** Directory selected; one up, so we can find its name..
CurrentDir(ParentDir(WBLock));
if (!Examine(WBLock, &WBInfoBlock)){
ErrMsg = NoAccess;
Quit(RETURN_FAIL, CHECK_IOERR);
}
FileName = WBInfoBlock.fib_FileName;
}
} else{
//*** From the CLI..
if ((argc<2) || ((argc>1)&&(*argv[1]=='?'))){ // No argument or '?'
static UBYTE Usage0[] = "Syntax: ";
static UBYTE Usage1[] = " <file>\nFunction: Edit a filenote\n";
Write(StdOut, Usage0, sizeof(Usage0)-1);
Write(StdOut, argv[0], strlen(argv[0]));
Write(StdOut, Usage1, sizeof(Usage1)-1);
Quit(RETURN_ERROR, ERROR_REQUIRED_ARG_MISSING);
}
FileName = argv[1];
}
//*** Get access to file
FileLock = Lock(FileName, ACCESS_READ);
if (!FileLock){
ErrMsg = NoAccess;
Quit(RETURN_FAIL, CHECK_IOERR);
}
if (!Examine(FileLock, &InfoBlock)){
UnLock(FileLock);
ErrMsg = NoAccess;
Quit(RETURN_FAIL, CHECK_IOERR);
}
UnLock(FileLock);
//*** Edit filenote and bits
EditResult = Edit(FileName, &InfoBlock);
if (EditResult < 0)
Quit(RETURN_FAIL, 0);
if (EditResult > 0){
//*** Store filenote and bits
if (!(SetComment(FileName, InfoBlock.fib_Comment) &&
SetProtection(FileName, InfoBlock.fib_Protection))){
ErrMsg = "Save failed\n";
Quit(RETURN_FAIL, CHECK_IOERR);
}
}
Quit(RETURN_OK, 0);
}
/*---------------------------------------------------------------------------*/
#define MAXWTITLE 40
VOID Quit(LONG ReturnValue, LONG Result2)
{
if (Result2 == CHECK_IOERR)
Result2 = IoErr();
//*** Print any message
if (ErrMsg){
LONG MsgLen = strlen(ErrMsg);
if (StdOut){ // CLI
Write(StdOut, PrgName, strlen(PrgName));
Write(StdOut, ": ", 2);
Write(StdOut, ErrMsg, MsgLen);
} else{ // WB
UBYTE StrBuf[MAXWTITLE+18], *StrPtr;
strcpy(StrBuf, "CON:10/10/630/120/");
strncpy(&StrBuf[18], WBenchMsg->sm_ArgList->wa_Name, MAXWTITLE);
StdOut = Open(StrBuf, MODE_OLDFILE);
if (StdOut){
Write(StdOut, ErrMsg, MsgLen);
if (Result2){
strcpy(StrBuf, "Error ");
StrPtr = &StrBuf[6];
StrPtr += stcl_d(StrPtr, Result2);
*StrPtr++ = '\n';
*StrPtr = '\0';
Write(StdOut, StrBuf, strlen(StrBuf));
}
Delay(100 + 4 * MsgLen);
Close(StdOut);
} else if (IntuitionBase){
DisplayBeep(0);
}
}
}
if (IntuitionBase)
CloseLibrary(IntuitionBase);
((struct Process *)FindTask(0))->pr_Result2 = Result2;
_exit(ReturnValue);
}
/*---------------------------------------------------------------------------*/
UBYTE *NoMem(ULONG Size, ULONG Type)
{
ErrMsg="Not enough memory\n";
return(0);
}
/*****************************************************************************/
extern struct Gadget *MakeStringGadget(ULONG TextWidth, ULONG TextHeight, UBYTE *TextBuf, ULONG TextLen);
extern struct Gadget *MakeBoolGadget(ULONG TextWidth, ULONG TextHeight, UBYTE *Text);
extern VOID ToggleGadget(struct Gadget *Gadget, struct Window *Window);
#define GADGET_H_DIST 10
#define GADGET_V_DIST 6
#define GADTXT_H_DIST 4
#define GADTXT_V_DIST 2
#define PEN_GREY 0
#define PEN_BLACK 1
#define PEN_WHITE 2
#define PEN_BLUE 3
#define NUMGADGETS 11
#define G_STR 10
#define G_CANCEL 9
#define G_SAVE 8
#define G_H 7
#define G_S 6
#define G_P 5
#define G_A 4
#define G_R 3
#define G_W 2
#define G_E 1
#define G_D 0
UBYTE *GtsText[] = {
"D",
"E",
"W",
"R",
"A",
"P",
"S",
"H",
" Save ",
" Cancel ",
""
};
struct Screen WBScreen;
struct NewWindow NewWin;
/*---------------------------------------------------------------------------*/
LONG Edit(UBYTE *FileName, struct FileInfoBlock *InfoBlock)
{
struct Window *Window;
struct Gadget *Gadget[NUMGADGETS];
LONG I;
WORD OverShoot, TextHeight;
WORD Close = 0, FirstActivate = 1;
//*** Get Screen structure for window and font sizes among others
if (!GetScreenData(&WBScreen, sizeof(struct Screen), WBENCHSCREEN, NULL)){
ErrMsg="No Screen\n";
Quit(RETURN_FAIL, 0);
}
//*** Something like Barheight, but Barheight differs between 1.3 and 2.0
TextHeight = WBScreen.RastPort.TxHeight + GADTXT_V_DIST;
//*** NewWindow allocation and initialization
NewWin.DetailPen = -1;
NewWin.BlockPen = -1;
NewWin.IDCMPFlags = IDCMP_ACTIVEWINDOW + IDCMP_GADGETUP + IDCMP_VANILLAKEY;
NewWin.Flags = WFLG_NOCAREREFRESH + WFLG_SMART_REFRESH + WFLG_ACTIVATE + WFLG_DRAGBAR + WFLG_DEPTHGADGET;
NewWin.Type = WBENCHSCREEN;
NewWin.TopEdge = WBScreen.MouseY; // Nice for auto-activation..
NewWin.Height = TextHeight * 3 + GADGET_V_DIST * 3 + 2;
OverShoot = NewWin.TopEdge + NewWin.Height - WBScreen.Height;
if (OverShoot>0){
NewWin.TopEdge -= OverShoot;
if (NewWin.TopEdge < 0)
NewWin.TopEdge = 0;
}
NewWin.Width = WBScreen.RastPort.TxWidth * COMMENTSIZE + 2 * GADTXT_H_DIST + 2 * GADGET_H_DIST;
if (NewWin.Width > WBScreen.Width)
NewWin.Width = WBScreen.Width;
OverShoot = WBScreen.MouseX - NewWin.Width + 1;
if (OverShoot > 0)
NewWin.LeftEdge = OverShoot;
NewWin.MinHeight = NewWin.MaxHeight = NewWin.Height; // No fiddling with our sizes!
NewWin.MinWidth = NewWin.MaxWidth = NewWin.Width;
NewWin.Title = AllocMA(sizeof(PrgTitle) + 1 + strlen(FileName), PUBCLR);
if (!NewWin.Title)
goto Fail;
strcpy(NewWin.Title, PrgTitle);
strcpy(&NewWin.Title[sizeof(PrgTitle)-1], FileName);
//*** Create string gadget for filenote
Gadget[G_STR]=MakeStringGadget(NewWin.Width - 2 * GADGET_H_DIST - 2 * GADTXT_H_DIST, TextHeight,
(UBYTE *)&InfoBlock->fib_Comment, COMMENTSIZE);
if (!Gadget[G_STR])
goto Fail;
Gadget[G_STR]->LeftEdge = GADGET_H_DIST + GADTXT_H_DIST;
Gadget[G_STR]->TopEdge = TextHeight + GADGET_V_DIST + 2; // 2 for thick border
//*** Create BOOL gadget structures
for (I=G_CANCEL; I>=G_D; --I){
Gadget[I]=MakeBoolGadget(strlen(GtsText[I]) * WBScreen.RastPort.TxWidth + 2 * GADTXT_H_DIST,
TextHeight, GtsText[I]);
if (!Gadget[I])
goto Fail;
Gadget[I]->TopEdge = Gadget[G_STR]->TopEdge + TextHeight + GADGET_V_DIST + 1; // 1 for thin border
Gadget[I+1]->NextGadget = Gadget[I];
}
Gadget[G_SAVE]->GadgetID = 1; // Close gadgets
Gadget[G_CANCEL]->GadgetID = 1;
//*** Set BOOL gadgets horizontal locations
Gadget[G_SAVE]->LeftEdge = GADGET_H_DIST;
Gadget[G_CANCEL]->LeftEdge = NewWin.Width - Gadget[G_CANCEL]->Width - GADGET_H_DIST;
Gadget[G_H]->LeftEdge = NewWin.Width/2 - 4 * (Gadget[G_H]->Width + GADGET_H_DIST);
for (I=G_S; I>=G_D; --I)
Gadget[I]->LeftEdge = Gadget[I+1]->LeftEdge + Gadget[I+1]->Width + GADGET_H_DIST;
//*** Check gaget overlap
if ((Gadget[G_SAVE]->LeftEdge + Gadget[G_SAVE]->Width) > Gadget[G_H]->LeftEdge){
ErrMsg = "Font too wide\n";
goto Fail;
}
//*** Set Filebit gadgets activation
for (I=G_H; I>=G_A; --I)
if (btst(I, InfoBlock->fib_Protection))
Gadget[I]->Flags |= GFLG_SELECTED;
for (I=G_R; I>=G_D; --I)
if (!btst(I, InfoBlock->fib_Protection))
Gadget[I]->Flags |= GFLG_SELECTED;
NewWin.FirstGadget = Gadget[G_STR];
//*** Open Window
Window = (struct Window *)OpenWindow(&NewWin);
if (!Window){
ErrMsg = "No window\n";
goto Fail;
}
//*** Handle Window messages
while(!Close){
struct IntuiMessage IntuMsg, *IM;
WaitPort(Window->UserPort);
if (IM = (struct IntuiMsg *)GetMsg(Window->UserPort)){
IntuMsg = *IM;
ReplyMsg((struct Message *)IM);
switch(IntuMsg.Class){
case IDCMP_ACTIVEWINDOW:
if (FirstActivate)
ActivateGadget(Gadget[G_STR], Window, NULL);
FirstActivate=0;
break;
case IDCMP_VANILLAKEY:
switch(IntuMsg.Code){
case 'S':
Gadget[G_SAVE]->Flags |= SELECTED;
Close = 1;
break;
case 'C':
Close = 1;
break;
case 'h':
ToggleGadget(Gadget[G_H], Window);
break;
case 's':
ToggleGadget(Gadget[G_S], Window);
break;
case 'p':
ToggleGadget(Gadget[G_P], Window);
break;
case 'a':
ToggleGadget(Gadget[G_A], Window);
break;
case 'r':
ToggleGadget(Gadget[G_R], Window);
break;
case 'w':
ToggleGadget(Gadget[G_W], Window);
break;
case 'e':
ToggleGadget(Gadget[G_E], Window);
break;
case 'd':
ToggleGadget(Gadget[G_D], Window);
break;
case 'f':
ActivateGadget(Gadget[G_STR], Window, NULL);
break;
default:
DisplayBeep(0);
break;
}
break;
case IDCMP_GADGETUP: /* User perhaps asks to leave */
Close = ((struct Gadget *)IntuMsg.IAddress)->GadgetID;
break;
}
}
}
//*** Set filebits from gadgets
for (I=G_H; I>=G_A; --I)
if (Gadget[I]->Flags & GFLG_SELECTED)
bset(I, InfoBlock->fib_Protection);
else
bclr(I, InfoBlock->fib_Protection);
for (I=G_R; I>=G_D; --I)
if (Gadget[I]->Flags & GFLG_SELECTED)
bclr(I, InfoBlock->fib_Protection);
else
bset(I, InfoBlock->fib_Protection);
//*** Close Window and return status
CloseWindow(Window);
return((Gadget[G_SAVE]->Flags&SELECTED)? 1 : 0);
Fail:
return(-1);
}
/*---------------------------------------------------------------------------*/
struct Gadget *MakeStringGadget(ULONG TextWidth, ULONG TextHeight, UBYTE *TextBuf, ULONG TextLen)
{
//*** Array of coordinates of a border around a gadget with a size of zero.
static WORD BasicXY[] = {
-4, -3, -4, 0, -3, -1, -3, -3, 2, -3, 1, -3, 1, -1, 0, -1, 0, -1, -1, -1,
3, 0, 3, -3, 2, -2, 2, 0, -3, 0, -2, 0, -2, -3, -1, -2, -1, -2, 0, -2
};
//*** Arrays of coordinate elements to be adapted to real gadget size
static WORD VAdapt[] = { 3, 5, 13, 17, 19, 21, 27, 29, 31, 35 };
static WORD HAdapt[] = { 8, 10, 12, 14, 16, 20, 22, 24, 26, 38 };
struct StringInfo *StrInfo;
struct Gadget *Gadget;
struct Border *BorderLT, *BorderRB; // Border Left Top and Border Right Bottom
WORD *XY;
LONG I;
//*** Allocate and initialize StringInfo structure
StrInfo = (struct StringInfo *)AllocMA(sizeof(struct StringInfo), PUBCLR);
if (!StrInfo)
goto Fail;
StrInfo->Buffer = TextBuf;
StrInfo->BufferPos = strlen(TextBuf);
StrInfo->UndoBuffer = AllocMA(TextLen + 2, PUBCLR);
if (!StrInfo->UndoBuffer)
goto Fail;
StrInfo->MaxChars = TextLen;
//*** Allocate and coordinate array's and adapt its contents
XY = (WORD *)AllocMA(sizeof(BasicXY), MEMF_PUBLIC);
if (!XY)
goto Fail;
memcpy((UBYTE *)XY, (UBYTE *)BasicXY, sizeof(BasicXY));
for (I=0; I < sizeof(VAdapt)/2; ++I)
XY[VAdapt[I]] += TextHeight;
for (I=0; I < sizeof(HAdapt)/2; ++I)
XY[HAdapt[I]] += TextWidth;
//*** Allocate and initialize Border structures
BorderLT = (struct Border *)AllocMA(sizeof(struct Border), PUBCLR);
if (!BorderLT)
goto Fail;
BorderLT->XY = XY;
BorderLT->Count = (sizeof(BasicXY)/(2 * sizeof(WORD)))/2;
BorderLT->FrontPen = PEN_WHITE;
BorderLT->DrawMode = JAM2;
BorderRB = (struct Border *)AllocMA(sizeof(struct Border), PUBCLR);
if (!BorderRB)
goto Fail;
BorderRB->XY = &XY[20];
BorderRB->Count = (sizeof(BasicXY)/(2 * sizeof(WORD)))/2;
BorderRB->FrontPen = PEN_BLACK;
BorderRB->DrawMode = JAM2;
BorderRB->NextBorder = BorderLT;
//*** Allocate and initialize string Gadget structure
Gadget = (struct Gadget *)AllocMA(sizeof(struct Gadget), PUBCLR);
if (!Gadget)
goto Fail;
Gadget->SpecialInfo = StrInfo;
Gadget->Flags = GFLG_GADGHCOMP + GFLG_SELECTED;
Gadget->Activation = GACT_TOGGLESELECT;
Gadget->GadgetType = GTYP_STRGADGET;
Gadget->Width = TextWidth;
Gadget->Height = TextHeight;
Gadget->GadgetRender = BorderRB;
return(Gadget);
Fail:
return(0);
}
/*---------------------------------------------------------------------------*/
struct Gadget *MakeBoolGadget(ULONG TextWidth, ULONG TextHeight, UBYTE *Text)
{
struct Gadget *Gadget;
struct IntuiText *IText;
struct Border *BorderLT, *BorderRB; // Border Left Top and Border Right Bottom
WORD *XY;
//*** Allocate and initialize Border coordinates
XY = (WORD *)AllocMA(2 * 5 * 2 * sizeof(WORD), PUBCLR);
if (!XY)
goto Fail;
XY[3] = TextHeight;
XY[4] = 1; XY[5] = TextHeight - 1;
XY[6] = 1;
XY[8] = TextWidth - 1;
XY[10] = TextWidth; XY[11] = TextHeight;
XY[12] = TextWidth;
XY[14] = TextWidth - 1; XY[15] = 1;
XY[16] = TextWidth - 1; XY[17] = TextHeight;
XY[18] = 1; XY[19] = TextHeight;
//*** Allocate and initialize Border structures
BorderLT = (struct Border *)AllocMA(sizeof(struct Border), PUBCLR);
if (!BorderLT)
goto Fail;
BorderLT->XY = XY;
BorderLT->Count = 5;
BorderLT->FrontPen = PEN_WHITE;
BorderLT->DrawMode = JAM2;
BorderRB = (struct Border *)AllocMA(sizeof(struct Border), PUBCLR);
if (!BorderRB)
goto Fail;
BorderRB->XY = &XY[10];
BorderRB->Count = 5;
BorderRB->FrontPen = PEN_BLACK;
BorderRB->DrawMode = JAM2;
BorderRB->NextBorder = BorderLT;
//*** Allocate and initialize IntuiText structures for gadget texts
IText = (struct IntuiText *)AllocMA(sizeof(struct IntuiText), PUBCLR);
if (!IText)
goto Fail;
IText->FrontPen = PEN_BLACK;
IText->DrawMode = JAM2;
IText->LeftEdge = GADTXT_H_DIST;
IText->TopEdge = GADTXT_V_DIST;
IText->IText = Text;
//*** Allocate and initialize BOOL Gadget structure
Gadget = (struct Gadget *)AllocMA(sizeof(struct Gadget), PUBCLR);
if (!Gadget)
goto Fail;
Gadget->Width = TextWidth + 1;
Gadget->Height = TextHeight + 1;
Gadget->Flags = GFLG_GADGHCOMP;
Gadget->Activation = GACT_TOGGLESELECT + GACT_RELVERIFY;
Gadget->GadgetType = GTYP_BOOLGADGET;
Gadget->GadgetRender = BorderRB;
Gadget->GadgetText = IText;
return(Gadget);
Fail:
return(0);
}
/*---------------------------------------------------------------------------*/
/*
* It is not the first time I have troubles with gadgets. I have ALWAYS
* troubles with gadgets. This time gadgets must toggle by our command.
* We must first remove any drawing data from the gadget. No border and
* no text. Now you can toggle the drawing just by complementing. You can
* let Intuition complement by refreshing a selected gadget. Later the
* select flag must be set right. Takes some time to find out.
*/
VOID ToggleGadget(struct Gadget *Gadget, struct Window *Window)
{
UWORD Flags;
Gadget->GadgetText=NULL;
Gadget->GadgetRender=NULL;
Flags = Gadget->Flags;
Gadget->Flags |= SELECTED;
RemoveGadget(Window, Gadget);
AddGadget(Window, Gadget, -1);
RefreshGadgets(Gadget, Window, NULL);
Gadget->Flags = Flags ^ SELECTED;
}
/*---------------------------------------------------------------------------*/