home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Mecomp Multimedia 1
/
Mecomp-CD.iso
/
amiga
/
tools
/
wb
/
lupe
/
source
/
lupe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-14
|
62KB
|
2,416 lines
// Lupe V1.8 - 1995-97 - © Frank Toepper
// a lens
// AmigaOS 3.0+
// Maxon C++
// last changes: 11.Apr.97
#include <string.h>
#include <iostream.h>
#include <ctype.h>
#include <intuition/intuition.h>
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <intuition/gadgetclass.h>
#include <intuition/intuitionbase.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <graphics/scale.h>
#include <devices/inputevent.h>
#include <libraries/commodities.h>
#include <libraries/gadtools.h>
#include <datatypes/pictureclass.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <cybergraphics/cybergraphics.h>
#include <clib/dos_protos.h>
#include <pragma/dos_lib.h>
#include <clib/intuition_protos.h>
#include <pragma/intuition_lib.h>
#include <clib/graphics_protos.h>
#include <pragma/graphics_lib.h>
#include <clib/exec_protos.h>
#include <pragma/exec_lib.h>
#include <clib/commodities_protos.h>
#include <pragma/commodities_lib.h>
#include <clib/gadtools_protos.h>
#include <pragma/gadtools_lib.h>
#include <clib/icon_protos.h>
#include <pragma/icon_lib.h>
#include <clib/cybergraphics_protos.h>
#include <pragma/cybergraphics_lib.h>
#include <clib/wb_protos.h>
#include <pragma/wb_lib.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <pragma/asl_lib.h>
#include <clib/alib_protos.h>
#include <pragma/utility_lib.h>
#include <clib/utility_protos.h>
#include <wbstartup.h>
#pragma header
#include "lupe_cat.h"
#define VERSION "Lupe V1.8"
#define CYBERARRAY_BPP 3
#define MINWIDTH 56
#define MINHEIGHT 30
enum { SAMESCREEN, NEWSCREEN };
UWORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
UWORD scalefac = 5, maxscalefac = 15, minwidth;
UWORD leftoff, topoff, bottomoff, rightoff;
UWORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
UWORD textoff, coordsstringlen, fontX, fontY, scrdepth;
WORD fixedX = 0, fixedY = 0;
ULONG cxsigflag, waitmask = 0, pens[6];
LONG oldx, oldy;
APTR VisualInfo = NULL;
BPTR fh;
struct MsgPort *broker_mp, *userport, *app_mp = NULL;
struct Task *thistask;
struct Window *mywin;
struct Screen *scr = NULL, *tmpscr;
struct Menu *menu = NULL;
struct MenuItem *item;
struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm, *maskbm = NULL;
struct TextFont *screenfont = NULL, *topazfont;
struct InputXpression setoriginix, resetoriginix, showhideix;
struct RastPort *scrrp, destrp, *winrp, maskrp;
struct Library *CxBase, *GadToolsBase, *CyberGfxBase, *IconBase;
struct Library *WorkbenchBase, *AslBase, *LocaleBase, *UtilityBase;
struct GfxBase *GfxBase;
struct AppIcon *appicon = NULL;
struct AppMessage *appmsg;
struct DiskObject *icon = NULL;
UBYTE timesig, showhidesig;
BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE;
BOOL jumpdirect, showhide = TRUE, hide = FALSE, hideonclose = FALSE, grid = FALSE;
BOOL showrgb = FALSE, jumptoactivescreen = FALSE, screentofront = TRUE;
CxObj *broker, *customcxobj;
Object *propgadget;
char pubscreenname[MAXPUBSCREENNAME];
char setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r", showhidekey[50] = "lalt h";
char title[10], dispstring[12], language[20] = "";
char programname[110], iffpath[256] = "ram:Lupe.iff", iffname[110];
char *Template = "CX_PRIORITY=P/N/K, FAST=F/S/K, MAXSCALEFACTOR=M/N/K, SCALEFACTOR=S/N/K, "
"WINLEFT=L/N/K, WINTOP=T/N/K, WINWIDTH=W/N/K, WINHEIGHT=H/N/K, "
"COORDINATES=C/S/K, CROSSHAIR=R/S/K, SETORIGINKEY=O/K, RESETORIGINKEY=K/K, "
"FIXED=D/S/K, SHOWHIDEKEY=SH/K, ICONIFY=I/S/K, ICONIFYONCLOSE=IOC/S/K, "
"GRID=G/S/K, SHOWRGB=RGB/S/K, IFFFILE=IF/K, JUMPTOACTIVESCREEN=JAS/S/K, "
"LANGUAGE=U";
struct BitScaleArgs bsa = {
// Src Koords
0, 0,
innerwidth / scalefac,
innerheight / scalefac,
// Src Faktoren
1, 1,
0, 0,
innerwidth,
innerheight,
// Dest Faktoren
scalefac, scalefac,
// Bitmaps
NULL, NULL,
0,
0, 0,
0, 0
};
struct TextAttr topaz_attr = {
"topaz.font",
8,
0,
FPF_ROMFONT
};
struct NewBroker newbroker = {
NB_VERSION,
"Lupe",
VERSION " © 1995-97 Frank Toepper",
0,
3,
COF_SHOW_HIDE,
0,
NULL,
0
};
extern struct IntuitionBase *IntuitionBase;
// function declarations for menu
BOOL jumpFunc ();
BOOL jumptoactiveFunc ();
BOOL saveFunc ();
BOOL fastFunc ();
BOOL AboutFunc ();
BOOL enableFunc ();
BOOL coordsFunc ();
BOOL crosshairFunc ();
BOOL gridFunc ();
BOOL showrgbFunc ();
BOOL fixedFunc ();
BOOL QuitFunc ();
BOOL hideFunc ();
BOOL hideoncloseFunc ();
//----------------------------------------------
void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
{
*putchdata++ = zeichen;
}
void error (char *formatstring, ...)
{
APTR args = &formatstring + 1;
struct EasyStruct easystruct = {
sizeof (struct EasyStruct),
0,
GetString (TXT_ERROR),
formatstring,
GetString (TXT_OK)
};
if (Cli ())
{
VPrintf (formatstring, (LONG *) args);
FPutC (Output (), '\n');
Flush (Output ());
}
else
{
EasyRequestArgs (NULL, &easystruct, NULL, args);
}
}
//----------------------------------------------
BOOL lockaspublicscreen (struct Screen *screen)
{
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
pubscreenlist = LockPubScreenList ();
if (pubscreenlist)
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == screen)
{
if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
{
UnlockPubScreenList ();
return TRUE;
}
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
return FALSE;
}
int setupscreen (struct Screen *selectedscreen)
{
ULONG id;
jumpdirect = FALSE;
if (selectedscreen)
{
jumpdirect = TRUE;
if (scr)
{
if (VisualInfo)
{
FreeVisualInfo (VisualInfo);
}
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
}
}
if (lockaspublicscreen (selectedscreen))
{
pubscreenlocked = TRUE;
}
else
{
pubscreenlocked = FALSE;
}
scr = selectedscreen;
}
else if (scr)
{
tmpscr = scr->NextScreen;
if (tmpscr)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
pubscreenlocked = FALSE;
}
if (lockaspublicscreen (tmpscr))
{
pubscreenlocked = TRUE;
}
}
else
{
error (GetString (TXT_ERROR_NOOTHERSCREEN));
return SAMESCREEN;
}
scr = tmpscr;
}
else if ((scr = LockPubScreen (NULL)) != 0)
{
pubscreenlocked = TRUE;
}
else
{
error (GetString (TXT_ERROR_LOCKPUBSCREEN));
throw 1;
}
VisualInfo = GetVisualInfoA (scr, NULL);
if (!VisualInfo)
{
error (GetString (TXT_ERROR_VISUALINFO));
throw 2;
}
cybergfxscreen = FALSE;
if (CyberGfxBase)
if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
if (IsCyberModeID (id))
if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
cybergfxscreen = TRUE;
return NEWSCREEN;
}
void CloseDownScreen ()
{
if (VisualInfo)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
}
if (scr && pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
pubscreenlocked = FALSE;
}
}
void getoffsets ()
{
struct DrawInfo *drawinfo;
APTR sizeobject;
ULONG attr;
if (screenfont)
{
CloseFont (screenfont);
screenfont = NULL;
}
hires = (scr->Flags & SCREENHIRES) != 0;
hires ? (rightoff = 18) : (rightoff = 13);
SetAPen (&maskrp, 1);
drawinfo = GetScreenDrawInfo (scr);
if (drawinfo)
{
// dimension of the border
sizeobject = NewObject (NULL, SYSICLASS,
SYSIA_Which, SIZEIMAGE, SYSIA_DrawInfo, drawinfo,
SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES, TAG_END);
if (sizeobject)
{
if (GetAttr (IA_Width, sizeobject, &attr))
{
sizeiw = attr;
rightoff = (UWORD) attr;
}
if (GetAttr (IA_Height, sizeobject, &attr))
{
sizeih = attr;
}
newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
SetAPen (&maskrp, drawinfo->dri_Pens[SHADOWPEN]);
DisposeObject (sizeobject);
}
pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
pens[1] = drawinfo->dri_Pens[FILLPEN];
pens[2] = drawinfo->dri_Pens[TEXTPEN];
pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
pens[4] = drawinfo->dri_Pens[SHINEPEN];
pens[5] = drawinfo->dri_Pens[SHADOWPEN];
FreeScreenDrawInfo (scr, drawinfo);
}
else
{
// default pens
pens[0] = 2;
pens[1] = 3;
pens[2] = 1;
pens[3] = 0;
pens[4] = 2;
pens[5] = 1;
} // if (drawinfo)
scrrp = &scr->RastPort;
topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
leftoff = scr->WBorLeft;
scrbm = scrrp->BitMap;
scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
fontX = topazfont->tf_XSize;
fontY = topazfont->tf_YSize;
minwidth = MINWIDTH;
coordsstringlen = 1;
if (scr->Width > 999)
{
coordsstringlen += 5;
}
else
{
coordsstringlen += 4;
}
if (scr->Height > 999)
{
coordsstringlen += 5;
}
else
{
coordsstringlen += 4;
}
if (coords || showrgb)
{
bottomoff = sizeih;
// center the text in the bottomborder
textoff = (bottomoff + fontY >> 1) - topazfont->tf_Baseline;
minwidth = 0;
if (coords)
{
minwidth = coordsstringlen * (fontX);
}
if (showrgb)
{
minwidth += 13 * (fontX);
}
// SysIHack or height of screenfont <= 8?
if ((bottomoff - 2) >= scr->Font->ta_YSize)
{
screenfont = OpenFont (scr->Font);
if (screenfont)
{
if (!(screenfont->tf_Flags & FPF_PROPORTIONAL))
{
fontX = screenfont->tf_XSize;
fontY = screenfont->tf_YSize;
minwidth = 0;
if (coords)
{
minwidth = coordsstringlen * (fontX);
}
if (showrgb)
{
minwidth += 13 * (fontX);
}
// center the text in the bottomborder
textoff = (bottomoff + fontY >> 1) - screenfont->tf_Baseline;
}
else
{
CloseFont (screenfont);
screenfont = NULL;
}
}
}
} // if (coords
else
{
bottomoff = scr->WBorBottom;
}
}
void setwintitle ()
{
LONG args[] = { (LONG) "Lupe", scalefac };
RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
SetWindowTitles (mywin, title, (STRPTR) ~0);
}
void setmenu ()
{
struct MenuItem *mitem;
if (mywin)
{
ClearMenuStrip (mywin);
mitem = ItemAddress (menu, FULLMENUNUM (0, 2, NOSUB));
if (jumptoactivescreen) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = ItemAddress (menu, FULLMENUNUM (0, 6, NOSUB));
if (enable) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (fixed) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (fast) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (coords) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (crosshair) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (grid) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (showrgb) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = ItemAddress (menu, FULLMENUNUM (0, 16, NOSUB));
if (hideonclose) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
ResetMenuStrip (mywin, menu);
}
}
void setupgrid ()
{
LONG i, j;
if (maskbm)
{
WaitBlit ();
FreeBitMap (maskbm);
maskbm = NULL;
}
if (grid)
{
maskbm = AllocBitMap (innerwidth, innerheight, 1, BMF_CLEAR, destbm);
if (!maskbm)
{
error (GetString (TXT_ERROR_GRIDMASK));
grid = FALSE;
setmenu ();
}
else
{
maskrp.BitMap = maskbm;
for (i = scalefac - 1; i < innerwidth; i += scalefac)
{
RectFill (&maskrp, i, 0, i, innerheight - 1)
}
for (i = scalefac - 1; i < innerheight; i += scalefac)
{
for (j = 0; j <= (innerwidth - scalefac); j += scalefac)
{
RectFill (&maskrp, j, i, j + scalefac - 2, i);
}
}
}
}
}
void allocbm ()
{
if (srcbm)
{
FreeBitMap (srcbm);
srcbm = NULL;
}
if (destbm)
{
FreeBitMap (destbm);
destbm = NULL;
}
winx = mywin->Width;
winy = mywin->Height;
innerwidth = winx - (leftoff + rightoff);
innerheight = winy - (topoff + bottomoff);
sourcewidth = innerwidth / scalefac;
sourceheight = innerheight / scalefac;
if (scalefac > 1)
{
if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, scrbm)))
{
error (GetString (TXT_ERROR_SOURCEBMP));
throw 1;
}
if (!(destbm = AllocBitMap (innerwidth, innerheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, srcbm)))
{
error (GetString (TXT_ERROR_DESTBMP));
throw 2;
}
bsa.bsa_SrcWidth = sourcewidth;
bsa.bsa_SrcHeight = sourceheight;
bsa.bsa_DestWidth = innerwidth;
bsa.bsa_DestHeight = innerheight;
bsa.bsa_SrcBitMap = srcbm;
bsa.bsa_DestBitMap = destbm;
bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
setupgrid ();
destrp.BitMap = destbm;
}
}
void makescreenmenu ()
{
struct NewMenu tmpmenu[] = {
{ NM_SUB, 0, 0, 0, 0, 0 },
{ NM_END, 0, 0, 0, 0, 0 }
};
ULONG lock;
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
if (tmpscr->NextScreen)
{
while ((tmpscr = tmpscr->NextScreen) != 0)
{
(*tmpmenu).nm_Label = tmpscr->DefaultTitle;
pubscreenlist = LockPubScreenList ();
if (pubscreenlist)
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == tmpscr)
{
if (pubscreennode->psn_Node.ln_Name)
{
tmpmenu->nm_Label = pubscreennode->psn_Node.ln_Name;
}
break;
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
if (!tmpmenu->nm_Label)
{
tmpmenu->nm_Label = GetString (TXT_UNNAMED);
}
tmpmenu->nm_UserData = tmpscr;
// each item single created
*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
if (*itempointer)
{
itempointer = &(*itempointer)->NextItem;
}
else
{
error (GetString (TXT_ERROR_SCREENMENUITEM));
}
}
}
else
{
tmpmenu->nm_Label = GetString (TXT_NOOTHERSCREEN);
*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
if (*itempointer)
{
(*itempointer)->Flags |= HIGHNONE;
itempointer = &(*itempointer)->NextItem;
}
else
{
error (GetString (TXT_ERROR_SCREENMENU));
}
}
UnlockIBase (lock);
if (!LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
{
error (GetString (TXT_ERROR_LAYOUTMENU));
throw 1;
}
}
void freescreenmenu (struct MenuItem *menuitem)
{
if (menuitem)
{
freescreenmenu (menuitem->NextItem);
FreeMenus ((struct Menu *) menuitem);
}
}
void openwin ()
{
struct NewMenu standardmenu[] = {
{ NM_TITLE, GetString (TXT_PROJECT), 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_JUMP), GetString (KEY_JUMP), 0, 0, jumpFunc },
{ NM_ITEM, GetString (TXT_JUMPTOSCREEN), 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_JUMPTOACTIVESCREEN), GetString (KEY_JUMPTOACTIVESCREEN), CHECKIT | MENUTOGGLE, 0, jumptoactiveFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_SAVEIFF), GetString (KEY_SAVEIFF), 0, 0, saveFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_ENABLE), GetString (KEY_ENABLE), CHECKIT | MENUTOGGLE, 0, enableFunc },
{ NM_ITEM, GetString (TXT_FIXED), GetString (KEY_FIXED), CHECKIT | MENUTOGGLE, 0, fixedFunc },
{ NM_ITEM, GetString (TXT_FAST), GetString (KEY_FAST), CHECKIT | MENUTOGGLE, 0, fastFunc },
{ NM_ITEM, GetString (TXT_COORDINATES), GetString (KEY_COORDINATES), CHECKIT | MENUTOGGLE, 0, coordsFunc },
{ NM_ITEM, GetString (TXT_CROSSHAIR), GetString (KEY_CROSSHAIR), CHECKIT | MENUTOGGLE, 0, crosshairFunc },
{ NM_ITEM, GetString (TXT_GRID), GetString (KEY_GRID), CHECKIT | MENUTOGGLE, 0, gridFunc },
{ NM_ITEM, GetString (TXT_SHOWRGB), GetString (KEY_SHOWRGB), CHECKIT | MENUTOGGLE, 0, showrgbFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_ABOUT), GetString (KEY_ABOUT), 0, 0, AboutFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, GetString (TXT_ICONIFYONCLOSE), GetString (KEY_ICONIFYONCLOSE), CHECKIT | MENUTOGGLE, 0, hideoncloseFunc },
{ NM_ITEM, GetString (TXT_ICONIFY), GetString (KEY_ICONIFY), 0, 0, hideFunc },
{ NM_ITEM, GetString (TXT_QUIT), GetString (KEY_QUIT), 0, 0, QuitFunc },
{ NM_END, 0, 0, 0, 0, 0 }
};
ULONG lock;
WORD bw, rh;
struct Rectangle zoom = {
minwidth + leftoff + rightoff,
MINHEIGHT + topoff + bottomoff + sizeih,
9999, 9999
};
if (!mywin)
{
if (hires)
{
bw = rh = 2;
}
else
{
bw = rh = 1;
}
if (screentofront)
{
// first bring the screen to front
// -> screen order in menu correct
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
UnlockIBase (lock);
if (tmpscr != scr)
{
if (jumpdirect)
{
ScreenToFront (scr);
}
else
{
ScreenToBack (tmpscr);
}
}
}
else
{
// auto jump
screentofront = TRUE;
}
menu = CreateMenusA (standardmenu, NULL);
if (!menu)
{
error (GetString (TXT_ERROR_MENU));
throw (1);
}
makescreenmenu ();
propgadget = (Object *) NewObject (NULL, PROPGCLASS,
PGA_Freedom, FREEVERT,
ICA_TARGET, ICTARGET_IDCMP,
PGA_NewLook, TRUE,
PGA_Borderless, newlook,
PGA_Total, maxscalefac,
PGA_Visible, 1,
PGA_Top, scalefac - 1,
GA_RelRight, bw - sizeiw + 3,
GA_Top, topoff + rh,
GA_Width, sizeiw - bw - bw - 4,
GA_RelHeight, -topoff - sizeih - rh - rh,
GA_RightBorder, TRUE,
TAG_DONE);
if (!propgadget)
{
error (GetString (TXT_ERROR_PROPGADGET));
throw (2);
}
if (innerwidth < minwidth)
{
innerwidth = minwidth;
}
mywin = OpenWindowTags (NULL,
WA_Flags, WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET
| WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH
| WFLG_NEWLOOKMENUS | WFLG_REPORTMOUSE | WFLG_SIZEBRIGHT
| ((coords || showrgb) ? WFLG_SIZEBBOTTOM : 0),
WA_AutoAdjust, 1,
WA_MaxHeight, 9999,
WA_MaxWidth, 9999,
WA_MinHeight, MINHEIGHT + topoff + bottomoff,
WA_MinWidth, minwidth + leftoff + rightoff,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE
| IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY
| IDCMP_REFRESHWINDOW,
WA_InnerHeight, innerheight,
WA_InnerWidth, innerwidth,
WA_Left, winleft,
WA_Gadgets, propgadget,
WA_Top, wintop,
pubscreenlocked ? WA_PubScreen : WA_CustomScreen, scr,
WA_Zoom, &zoom,
TAG_DONE);
if (!mywin)
{
error (GetString (TXT_ERROR_WINDOW));
throw (3);
}
// shit patches
leftoff = mywin->BorderLeft;
bottomoff = mywin->BorderBottom;
SetMenuStrip (mywin, menu);
setmenu ();
setwintitle ();
userport = mywin->UserPort;
winrp = mywin->RPort;
if (screenfont)
{
SetFont (winrp, screenfont);
}
else
{
SetFont (winrp, topazfont);
}
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
waitmask |= 1 << userport->mp_SigBit;
}
}
void closewin ()
{
if (mywin)
{
if (menu)
{
ClearMenuStrip (mywin);
}
wintop = mywin->TopEdge;
winleft = mywin->LeftEdge;
waitmask &= ~(1 << userport->mp_SigBit);
CloseWindow (mywin);
mywin = NULL;
userport = NULL;
jump = TRUE;
}
if (menu)
{
freescreenmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
FreeMenus (menu);
menu = NULL;
}
if (propgadget)
{
DisposeObject (propgadget);
propgadget = NULL;
}
if (srcbm)
{
FreeBitMap (srcbm);
srcbm = NULL;
}
if (destbm)
{
FreeBitMap (destbm);
destbm = NULL;
}
if (maskbm)
{
FreeBitMap (maskbm);
maskbm = NULL;
}
}
BOOL screen_is_still_open ()
{
tmpscr = IntuitionBase->FirstScreen;
while (tmpscr)
{
if (tmpscr == scr)
{
return TRUE;
}
tmpscr = tmpscr->NextScreen;
}
return FALSE;
}
void freeappicon ()
{
if (appicon)
{
RemoveAppIcon (appicon);
appicon = NULL;
}
if (app_mp)
{
waitmask &= ~(1 << app_mp->mp_SigBit);
DeleteMsgPort (app_mp);
app_mp = NULL;
}
if (icon)
{
FreeDiskObject (icon);
icon = NULL;
}
}
void showwindow ()
{
if (!mywin)
{
if (!screen_is_still_open ())
{
scr = NULL;
}
setupscreen (scr);
getoffsets ();
openwin ();
allocbm ();
freeappicon ();
}
}
void hidewindow ()
{
closewin ();
CloseDownScreen ();
freeappicon ();
if (Cli ())
{
GetProgramName (programname, 108);
}
else
{
strncpy (programname, thistask->tc_Node.ln_Name, 108);
}
icon = GetDiskObject ("ENV:sys/def_Lupe");
if (!icon)
{
icon = GetDiskObject (programname);
if (!icon)
{
icon = GetDefDiskObject (WBTOOL);
}
}
if (icon)
{
app_mp = CreateMsgPort ();
if (app_mp)
{
appicon = AddAppIcon (1, 0, "Lupe", app_mp, NULL, icon, NULL);
if (appicon)
{
waitmask |= 1 << app_mp->mp_SigBit;
}
}
}
}
//- refresh ------------------------------------
void printcoords (LONG x, LONG y)
{
if (coords)
{
LONG args[] = {x - originX, y - originY};
memset (dispstring, ' ', coordsstringlen);
RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, dispstring);
dispstring[strlen (dispstring)] = ' ';
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
Move (winrp, leftoff, mywin->Height - textoff);
Text (winrp, dispstring, coordsstringlen);
}
mywin->Flags |= SIZEGADGET;
}
}
void printrgb (LONG x, LONG y)
{
ULONG colorreg, colors[3], apen, textlen, cybercolor;
if (showrgb)
{
colorreg = ReadPixel (scrrp, x, y);
if (cybergfxscreen)
{
cybercolor = ReadRGBPixel (scrrp, x, y);
colors[0] = (cybercolor >> 16) & 0xff;
colors[1] = (cybercolor >> 8) & 0xff;
colors[2] = cybercolor & 0xff;
}
else
{
GetRGB32 (scr->ViewPort.ColorMap, colorreg, 1, colors);
colors[0] &= 0xff;
colors[1] &= 0xff;
colors[2] &= 0xff;
}
RawDoFmt ("%3ld,%3ld,%3ld", colors, (void (*)()) Putchar, dispstring);
textlen = TextLength (winrp, dispstring, 11);
apen = GetAPen (winrp);
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
Move (winrp, innerwidth - textlen, mywin->Height - textoff);
Text (winrp, dispstring, 11);
SetAPen (winrp, pens[5]);
Move (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - 2);
Draw (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY);
Draw (winrp, innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - fontY);
SetAPen (winrp, pens[4]);
Move (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1);
Draw (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - 1);
Draw (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - 1);
if (cybergfxscreen)
{
FillPixelArray (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
fontX - 1, fontY - 2, cybercolor);
}
else
{
SetAPen (winrp, colorreg);
RectFill (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - 2);
}
}
mywin->Flags |= SIZEGADGET;
SetAPen (winrp, apen);
} // if (showrgb)
}
LONG adjustX (LONG &x)
{
LONG xoff = 0;
x -= sourcewidth >> 1;
if (x < 0)
{
xoff = x;
x = 0;
}
else if (x > (scr->Width - sourcewidth))
{
xoff = -(scr->Width - sourcewidth - x);
x = scr->Width - sourcewidth;
}
return xoff;
}
LONG adjustY (LONG &y)
{
LONG yoff = 0;
y -= sourceheight >> 1;
if (y < 0)
{
yoff = y;
y = 0;
}
else if (y > (scr->Height - sourceheight))
{
yoff = -(scr->Height - sourceheight - y);
y = scr->Height - sourceheight;
}
return yoff;
}
void refresh ()
{
LONG x, y, xoff, yoff;
if (mywin)
{
// set the coordinates
if (enable)
{
if (fixed)
{
x = fixedX;
y = fixedY;
}
else
{
x = scr->MouseX;
y = scr->MouseY;
}
oldx = x;
oldy = y;
}
else
{
x = oldx;
y = oldy;
}
printcoords (x, y);
printrgb (x, y);
xoff = adjustX (x);
yoff = adjustY (y);
// calculate the crosshair
if (crosshair)
{
xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac - 1 >> 1);
yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac - 1 >> 1);
}
if (scalefac > 1)
{
// blit and scale
BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
BitMapScale (&bsa);
// draw the grid
if (grid)
{
SetDrMd (&destrp, JAM1);
BltTemplate (maskbm->Planes[0], 0, maskbm->BytesPerRow, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac);
}
// draw the crosshair
if (crosshair)
{
SetDrMd (&destrp, COMPLEMENT);
RectFill (&destrp, xoff, 0, xoff, sourceheight * scalefac - 1);
RectFill (&destrp, 0, yoff, sourcewidth * scalefac - 1, yoff);
}
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
}
mywin->Flags |= SIZEGADGET;
}
else // 1:1
{
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
// draw the crosshair in 1:1
if (crosshair)
{
SetDrMd (winrp, COMPLEMENT);
RectFill (winrp, leftoff + xoff, topoff, leftoff + xoff, topoff + innerheight - 1);
RectFill (winrp, leftoff, topoff + yoff, leftoff + innerwidth - 1, topoff + yoff);
SetDrMd (winrp, JAM2);
}
}
mywin->Flags |= SIZEGADGET;
}
if (!fast)
{
SetSignal (0, 1 << timesig);
}
}
}
//----------------------------------------------
void CxFunction (CxMsg *cxm, CxObj *co)
{
struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
if (origin)
{
if (MatchIX (ie, &setoriginix))
{
originX = scr->MouseX;
originY = scr->MouseY;
DisposeCxMsg (cxm);
return;
}
if (MatchIX (ie, &resetoriginix))
{
originX = originY = 0;
DisposeCxMsg (cxm);
return;
}
}
if (showhide)
{
if (MatchIX (ie, &showhideix))
{
Signal (thistask, 1 << showhidesig);
}
}
if ((ie->ie_Class == IECLASS_TIMER) || fast)
{
Signal (thistask, 1 << timesig);
}
}
void initbroker ()
{
LONG errorcode;
broker_mp = CreateMsgPort ();
if (!broker_mp)
{
error (GetString (TXT_ERROR_COMMODITYMP));
throw (1);
}
newbroker.nb_Port = broker_mp;
newbroker.nb_Descr = GetString (TXT_DESCRIPTION),
cxsigflag = 1 << broker_mp->mp_SigBit;
broker = CxBroker (&newbroker, &errorcode);
if (!broker)
{
if (errorcode == CBERR_SYSERR)
{
error (GetString (TXT_ERROR_COMMODITYBROKER));
}
throw (2);
}
customcxobj = CxCustom (CxFunction, 0);
if (!customcxobj)
{
error (GetString (TXT_ERROR_COMMODITYCUSTOM));
throw (3);
}
AttachCxObj (broker, customcxobj);
if (CxObjError (customcxobj))
{
error (GetString (TXT_ERROR_COMMODITYBROKER));
throw (4);
}
if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
{
origin = FALSE;
error (GetString (TXT_ERROR_HOTKEY), "'Set Origin'");
}
if (ParseIX (showhidekey, &showhideix))
{
showhide = FALSE;
error (GetString (TXT_ERROR_HOTKEY), "'Show/Hide Window'");
}
ActivateCxObj (broker, 1);
}
void reopenwin ()
{
closewin ();
getoffsets ();
openwin ();
allocbm ();
}
void setpropgad ()
{
allocbm ();
SetAttrs (propgadget, PGA_Top, scalefac - 1);
RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
setwintitle ();
}
BOOL menupick (UWORD code)
{
static BOOL (*func)();
while ((code != MENUNULL) && !jump)
{
item = ItemAddress (menu, code);
if (SUBNUM (code) != NOSUB)
{
if (GTMENUITEM_USERDATA (item)) // 'no other screen'-submenu == 0
{
setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item));
reopenwin ();
}
}
else
{
func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
if (func () == FALSE)
{
return FALSE;
}
}
if (!jump) code = item->NextSelect;
}
return TRUE;
}
BOOL vanillakey (UWORD code)
{
BOOL returnvalue = TRUE;
code = ToUpper (code);
if (code == ToUpper (*GetString (KEY_JUMP)))
{
returnvalue = jumpFunc ();
}
else if (code == ToUpper (*GetString (KEY_JUMPTOACTIVESCREEN)))
{
jumptoactivescreen = !jumptoactivescreen;
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_SAVEIFF)))
{
returnvalue = saveFunc ();
}
else if (code == ToUpper (*GetString (KEY_ENABLE)))
{
enable = !enable;
ActivateCxObj (broker, enable);
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_FIXED)))
{
fixed = !fixed;
fixedX = scr->MouseX;
fixedY = scr->MouseY;
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_FAST)))
{
fast = !fast;
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_COORDINATES)))
{
coords = !coords;
reopenwin ();
}
else if (code == ToUpper (*GetString (KEY_CROSSHAIR)))
{
crosshair = !crosshair;
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_GRID)))
{
grid = !grid;
setupgrid ();
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_SHOWRGB)))
{
showrgb = !showrgb;
reopenwin ();
}
else if (code == ToUpper (*GetString (KEY_ABOUT)))
{
returnvalue = AboutFunc ();
}
else if (code == ToUpper (*GetString (KEY_ICONIFYONCLOSE)))
{
hideonclose = !hideonclose;
setmenu ();
}
else if (code == ToUpper (*GetString (KEY_ICONIFY)))
{
returnvalue = hideFunc ();
}
else if (code == ToUpper (*GetString (KEY_QUIT)))
{
returnvalue = FALSE;
}
else switch (code)
{
case 27: // ESC
if (hideonclose)
{
hidewindow ();
jump = TRUE;
}
else
{
returnvalue = FALSE;
}
break;
case '+':
if (scalefac < maxscalefac)
{
scalefac++;
setpropgad ();
}
break;
case '-':
if (scalefac > 1)
{
scalefac--;
setpropgad ();
}
break;
}
return returnvalue;
}
void rawkey (UWORD code, UWORD qualifier)
{
switch (code)
{
// up
case 76:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY -= sourceheight - 1;
if (fixedY < 0)
{
fixedY = 0;
}
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = 0;
}
else if (fixedY)
{
fixedY--;
}
break;
// down
case 77:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY += sourceheight - 1;
if (fixedY > (scr->Height - 1))
{
fixedY = scr->Height - 1;
}
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = scr->Height - 1;
}
else if (fixedY < (scr->Height - 1))
{
fixedY++;
}
break;
// right
case 78:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX += sourcewidth - 1;
if (fixedX > (scr->Width - 1))
{
fixedX = scr->Width - 1;
}
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = scr->Width - 1;
}
else if (fixedX < (scr->Width - 1))
{
fixedX++;
}
break;
// left
case 79:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX -= sourcewidth - 1;
if (fixedX < 0)
{
fixedX = 0;
}
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = 0;
}
else if (fixedX)
{
fixedX--;
}
break;
}
}
void processmsg ()
{
struct IntuiMessage *intuimsg = NULL, m;
CxMsg *msg;
BOOL cont = TRUE, fixedmove = FALSE, app_clicked = FALSE;
LONG sigmask, msgid, msgtype;;
ULONG lock;
waitmask |= (1 << timesig) | (1 << showhidesig) | cxsigflag | SIGBREAKF_CTRL_C;
while (cont)
{
sigmask = Wait (waitmask);
if (sigmask & cxsigflag)
{
while ((msg = (CxMsg *) GetMsg (broker_mp)) != 0)
{
msgid = CxMsgID (msg);
msgtype = CxMsgType (msg);
ReplyMsg ((struct Message *) msg);
switch (msgtype)
{
case CXM_COMMAND:
switch (msgid)
{
case CXCMD_APPEAR:
showwindow ();
break;
case CXCMD_DISAPPEAR:
hidewindow ();
break;
case CXCMD_DISABLE:
ActivateCxObj (broker, 0);
enable = FALSE;
setmenu ();
break;
case CXCMD_ENABLE:
ActivateCxObj (broker, 1);
enable = TRUE;
setmenu ();
break;
case CXCMD_UNIQUE:
showwindow ();
break;
case CXCMD_KILL:
cont = FALSE;
break;
}
}
} // while ((msg
}
if (userport)
{
if (sigmask & (1 << userport->mp_SigBit))
{
jump = FALSE;
while ((intuimsg = (struct IntuiMessage *) GetMsg (userport)) != 0)
{
CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
ReplyMsg ((struct Message *) intuimsg);
switch (m.Class)
{
case IDCMP_CLOSEWINDOW:
if (hideonclose)
{
hidewindow ();
}
else
{
cont = FALSE;
}
break;
case IDCMP_NEWSIZE:
allocbm ();
break;
case IDCMP_IDCMPUPDATE:
ULONG h;
GetAttr (PGA_Top, propgadget, &h);
if (++h != scalefac)
{
scalefac = h;
allocbm ();
setwintitle ();
setmenu ();
}
break;
case IDCMP_MENUPICK:
cont = menupick (m.Code);
break;
case IDCMP_ACTIVEWINDOW:
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
printcoords (oldx, oldy);
printrgb (oldx, oldy);
ClearMenuStrip (mywin);
freescreenmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
makescreenmenu ();
SetMenuStrip (mywin, menu);
break;
case IDCMP_INACTIVEWINDOW:
SetAPen (winrp, pens[2]);
SetBPen (winrp, pens[3]);
printcoords (oldx, oldy);
printrgb (oldx, oldy);
break;
case IDCMP_MOUSEBUTTONS:
if (fixed)
{
if (m.Code == SELECTDOWN)
{
fixedmove = TRUE;
}
else
{
fixedmove = FALSE;
}
}
break;
case IDCMP_MOUSEMOVE:
if (fixedmove)
{
fixedX = scr->MouseX;
fixedY = scr->MouseY;
}
break;
case IDCMP_VANILLAKEY:
cont = vanillakey (m.Code);
break;
case IDCMP_RAWKEY:
rawkey (m.Code, m.Qualifier);
break;
case IDCMP_REFRESHWINDOW:
refresh ();
break;
}
if (jump)
{
break;
}
} // while (intuimsg
}
} // if (userport)
if (app_mp)
{
if (sigmask & (1 << app_mp->mp_SigBit))
{
app_clicked = FALSE;
while ((appmsg = (struct AppMessage *) GetMsg (app_mp)) != 0)
{
ReplyMsg ((struct Message *) appmsg);
app_clicked = TRUE;
}
if (app_clicked)
{
showwindow ();
}
}
}
if ((sigmask & (1 << showhidesig)) && cont)
{
if (mywin)
{
hidewindow ();
}
else
{
showwindow ();
}
}
if ((sigmask & (1 << timesig)) && cont)
{
if (mywin)
{
// refresh only if we living on the active screen
lock = LockIBase (0);
tmpscr = IntuitionBase->ActiveScreen;
UnlockIBase (lock);
if (scr == tmpscr)
{
refresh ();
}
else if (jumptoactivescreen)
{
setupscreen (tmpscr);
screentofront = FALSE;
reopenwin ();
}
}
}
if (sigmask & SIGBREAKF_CTRL_C)
{
cont = FALSE;
}
} // while (cont)
}
//- iff save -----------------------------------
BOOL openfilereq ()
{
APTR request;
request = AllocAslRequestTags (ASL_FileRequest,
ASLFR_InitialHeight, scr->Height / 2,
ASLFR_Screen, scr,
ASLFR_SleepWindow, TRUE,
ASLFR_Window, mywin,
ASLFR_TitleText, GetString (TXT_SAVEIFF),
ASLFR_InitialDrawer, iffpath,
ASLFR_InitialFile, iffname,
ASLFR_DoSaveMode, TRUE,
ASLFR_RejectIcons, TRUE,
ASLFR_Screen, OpenWorkBench (),
TAG_DONE);
if (request)
{
if (AslRequest (request, NULL))
{
strncpy (iffpath, ((struct FileRequester *) request)->fr_Drawer, 255);
strncpy (iffname, ((struct FileRequester *) request)->fr_File, 108);
FreeAslRequest (request);
return TRUE;
}
}
return FALSE;
}
void write (register __d4 APTR buffer, register __d5 LONG size)
{
if (Write (fh, buffer, size) != size)
{
throw (1);
}
}
ULONG compressline (register __a3 UBYTE *src, register __a4 UBYTE *dest, ULONG size)
{
register UBYTE x, y, *tmp, *deststart;
deststart = dest;
while (size > 1)
{
x = 0;
y = *src++;
if (y == *src)
{
size--;
while (size && (x < 127) && (*src == y))
{
size--;
x++;
src++;
}
*dest++ = -x;
*dest++ = y;
}
else
{
tmp = dest++;
while (size && (x < 128) && (*src != y))
{
size--;
x++;
*dest++ = y;
y = *src++;
}
*tmp = x - 1;
src--;
}
}
if (size)
{
*dest++ = 0;
*dest++ = *src;
}
return dest - deststart;
}
void savetruecolor ()
{
UWORD bpr = ((innerwidth >> 3) + 2) & 0xfffe, byteoff, i, j;
UBYTE *mem, *mem2, *offset, r, g, b;
ULONG packlen;
register UWORD x, y;
struct BitMap *bm = NULL;
BOOL ownbitmap = FALSE;
if (GetBitMapAttr (destbm, BMA_FLAGS) & PIXFMT_RGB24)
{
bm = destbm;
}
else
{
bm = AllocBitMap (innerwidth, innerheight, 24, BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24, 0);
if (!bm)
{
error (GetString (TXT_ERROR_ALLOCBITMAPSAVE));
throw (1);
}
ownbitmap = TRUE;
BltBitMap (destbm, 0, 0, bm, 0, 0, innerwidth, innerheight, ABNC | ABC, ~0, NULL);
}
mem = (UBYTE *) AllocVec (bpr * 24, 0);
if (!mem)
{
throw (2);
}
mem2 = (UBYTE *) AllocVec (bpr << 1, 0);
if (!mem2)
{
throw (3);
}
for (i = 0; i < destbm->Rows; i++)
{
memset (mem, 0, bpr * 24);
offset = bm->Planes[0] + i * bpr * 24;
for (j = 0, y = 7; j < (bpr * 24); j++, y--)
{
r = *(offset + j++);
g = *(offset + j++);
b = *(offset + j);
if (y > 7) y = 7;
byteoff = j / 24;
for (x = 0; x < 8; x++)
{
mem[x*bpr+byteoff] |= ((r >> x) & 1u) << y;
mem[(x+8)*bpr+byteoff] |= ((g >> x) & 1u) << y;
mem[(x+16)*bpr+byteoff] |= ((b >> x) & 1u) << y;
}
}
for (j = 0; j < (bpr * 24); j += bpr)
{
packlen = compressline (&mem[j], mem2, bpr);
write (mem2, packlen);
}
RectFill (winrp, leftoff, i + topoff, innerwidth + leftoff - 1, i + topoff);
}
FreeVec (mem);
FreeVec (mem2);
if (ownbitmap && bm)
{
FreeBitMap (bm);
}
}
void saveiff ()
{
ULONG len, bodylen, packlen, vpmodeid, colors[3];;
UWORD i, j, depth;
UBYTE cmap[3], *mem;
struct BitMapHeader bh;
struct DisplayInfo di;
char header[] = "FORM....ILBMANNO";
char anno[] = "Written by " VERSION "\0";
try
{
// save header
depth = GetBitMapAttr (destbm, BMA_DEPTH);
write (header, strlen (header));
len = (strlen (anno) + 2) & 0xfe;
write (&len, 4);
write (anno, len);
write ("BMHD", 4);
len = sizeof (struct BitMapHeader);
write (&len, 4);
bh.bmh_Width = innerwidth;
bh.bmh_Height = innerheight;
bh.bmh_Left = bh.bmh_Top = 0;
bh.bmh_Depth = cybergfxscreen ? 24 : depth;
bh.bmh_Masking = 0;
bh.bmh_Compression = 1;
bh.bmh_Pad = 0;
bh.bmh_Transparent = 0;
vpmodeid = GetVPModeID (&scr->ViewPort);
if (GetDisplayInfoData (NULL, (UBYTE *) &di, sizeof (struct DisplayInfo), DTAG_DISP, vpmodeid))
{
bh.bmh_XAspect = di.Resolution.x;
bh.bmh_YAspect = di.Resolution.y;
}
else
{
bh.bmh_XAspect = bh.bmh_YAspect = 0;
}
bh.bmh_PageWidth = innerwidth;
bh.bmh_PageHeight = innerheight;
write (&bh, len);
write ("CAMG", 4);
len = 4;
write (&len, 4);
write (&vpmodeid, 4);
// no "CMAP" in true color
if (!cybergfxscreen)
{
write ("CMAP", 4);
len = 3 * (1 << depth);
write (&len, 4);
for (i = 0; i < (1 << depth); i++)
{
GetRGB32 (scr->ViewPort.ColorMap, i, 1, colors);
cmap[0] = colors[0] & 0xff;
cmap[1] = colors[1] & 0xff;
cmap[2] = colors[2] & 0xff;
write (cmap, 3);
}
}
write ("BODY....", 8);
bodylen = Seek (fh, 0, OFFSET_CURRENT) - 4;
if (cybergfxscreen)
{
savetruecolor ();
}
else
{
mem = (UBYTE *) AllocVec (destbm->BytesPerRow << 1, 0);
if (mem)
{
if (GetBitMapAttr (destbm, BMA_FLAGS) & BMF_INTERLEAVED)
{
// interleaved
for (i = 0, len = 0; i < (destbm->Rows * depth); i++, len += destbm->BytesPerRow / depth)
{
packlen = compressline (destbm->Planes[0] + len, mem, destbm->BytesPerRow / depth);
write (mem, packlen);
if (!(i % depth))
{
RectFill (winrp, leftoff, i / depth + topoff, innerwidth + leftoff - 1, i / depth + topoff);
}
}
}
else
{
len = 0;
for (i = 0; i < destbm->Rows; i++)
{
for (j = 0; j < depth; j++)
{
packlen = compressline (destbm->Planes[j] + len, mem, destbm->BytesPerRow);
write (mem, packlen);
}
len += destbm->BytesPerRow;
RectFill (winrp, leftoff, i + topoff, innerwidth + leftoff - 1, i + topoff);
}
}
FreeVec (mem);
}
else
{
throw (3);
}
} // if (cybergfxscreen)
if (Seek (fh, 0, OFFSET_CURRENT) & 1)
{
*cmap = 0x80;
write (cmap, 1);
}
len = Seek (fh, 4, OFFSET_BEGINNING) - 8;
write (&len, 4);
Seek (fh, bodylen, OFFSET_BEGINNING);
len = len - bodylen + 4;
write (&len, 4);
}
catch (int) { }
}
//- menu ---------------------------------------
BOOL fixedFunc ()
{
if (!fixed && (item->Flags & CHECKED))
{
fixed = TRUE;
fixedX = scr->MouseX;
fixedY = scr->MouseY;
}
else if (fixed && !(item->Flags & CHECKED))
{
fixed = FALSE;
}
return TRUE;
}
BOOL fastFunc ()
{
fast = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL crosshairFunc ()
{
crosshair = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL AboutFunc ()
{
static struct EasyStruct es_about = {
20, 0,
"Lupe",
"%s%s%s%s",
"%s"
};
char *era_about[] = {
VERSION " (" __DATE__ ")\n\n",
GetString (TXT_ABOUT_WRITTENBY),
"\n"
" Frank Toepper\n"
" Maxim Gorki Straße 5A\n"
" Greifswald\n"
" 17491\n"
" GERMANY\n\n"
"E-Mail:\n"
" toepper@rz.uni-greifswald.de\n"
"WWW:\n"
" http://www.user.fh-stralsund.de/~rwermke/di.html\n\n",
GetString (TXT_ABOUT_PD),
"Ok"
};
EasyRequestArgs (NULL, &es_about, NULL, era_about);
return TRUE;
}
BOOL jumpFunc ()
{
if (setupscreen (NULL) == NEWSCREEN)
{
reopenwin ();
}
return TRUE;
}
BOOL jumptoactiveFunc ()
{
jumptoactivescreen = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL saveFunc ()
{
BPTR dirlock, olddirlock;
ULONG reg;
if (scalefac == 1)
{
LONG x = oldx, y = oldy;
if (!(destbm = AllocBitMap (innerwidth, innerheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, 0)))
{
error (GetString (TXT_ERROR_ALLOCBITMAPSAVE));
return TRUE;
}
adjustX (x);
adjustY (y);
BltBitMap (scrbm, x, y, destbm, 0, 0, innerwidth, innerheight, ABNC | ABC, ~0, NULL);
}
if (openfilereq ())
{
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
dirlock = Lock (iffpath, SHARED_LOCK);
if (dirlock)
{
olddirlock = CurrentDir (dirlock);
fh = Open (iffname, MODE_NEWFILE);
if (fh)
{
mywin->Flags &= ~SIZEGADGET;
reg = GetAPen (winrp);
SetAPen (winrp, 0);
saveiff ();
Close (fh);
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
SetAPen (winrp, reg);
mywin->Flags |= SIZEGADGET;
}
else
{
error (GetString (TXT_ERROR_CREATE), iffname);
}
CurrentDir (olddirlock);
UnLock (dirlock);
}
else
{
error (GetString (TXT_ERROR_LOCK), iffpath);
}
}
if ((scalefac == 1) && destbm)
{
FreeBitMap (destbm);
destbm = NULL;
}
return TRUE;
}
BOOL coordsFunc ()
{
if (!coords && (item->Flags & CHECKED))
{
coords = TRUE;
}
else if (coords && !(item->Flags & CHECKED))
{
coords = FALSE;
}
else
{
return TRUE; // nothing changed
}
reopenwin ();
return TRUE;
}
BOOL gridFunc ()
{
grid = (item->Flags & CHECKED) != 0;
setupgrid ();
return TRUE;
}
BOOL showrgbFunc ()
{
if (!showrgb && (item->Flags & CHECKED))
{
showrgb = TRUE;
}
else if (showrgb && !(item->Flags & CHECKED))
{
showrgb = FALSE;
}
else
{
return TRUE; // nothing changed
}
reopenwin ();
return TRUE;
}
BOOL enableFunc ()
{
if (item->Flags & CHECKED)
{
ActivateCxObj (broker, 1);
enable = TRUE;
}
else if (!(item->Flags & CHECKED))
{
ActivateCxObj (broker, 0);
enable = FALSE;
}
return TRUE;
}
BOOL hideoncloseFunc ()
{
hideonclose = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL hideFunc ()
{
hidewindow ();
jump = TRUE;
return TRUE;
}
BOOL QuitFunc ()
{
return FALSE;
}
//- args ---------------------------------------
BOOL argbool (char **argv, char *name, BOOL def)
{
char *value;
value = (char *) FindToolType ((UBYTE **) argv, name);
if (value)
{
if (MatchToolValue (value, "YES") || MatchToolValue (value, "ON")) return TRUE;
if (MatchToolValue (value, "OFF") || MatchToolValue (value, "NO")) return FALSE;
}
return def;
}
LONG argint (char **argv, UBYTE *name, LONG def)
{
LONG returnvalue;
APTR value;
value = FindToolType ((UBYTE **) argv, name);
if (value)
{
if (StrToLong ((UBYTE *) value, &returnvalue))
{
return returnvalue;
}
}
return def;
}
void argstring (char *result, char **argv, char *name, size_t size = 49)
{
char *value;
value = FindToolType ((UBYTE **) argv, name);
if (value)
{
strncpy (result, value, size);
}
}
void readargs ()
{
// first time always the tooltypes will be evaluated
// if we started from Cli the tooltypes can be overloaded
char **argv;
struct DiskObject *programicon;
struct RDArgs * rdargs;
struct DrawInfo *drawinfo;
LONG a[21];
long *args = a;
wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
// make the window as square as possible
drawinfo = GetScreenDrawInfo (scr);
if (drawinfo)
{
innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
FreeScreenDrawInfo (scr, drawinfo);
}
if (Cli ())
{
GetProgramName (programname, 108);
}
else
{
strcpy (programname, thistask->tc_Node.ln_Name);
}
IconBase = OpenLibrary ("icon.library", 37);
if (IconBase)
{
programicon = GetDiskObject (programname);
if (programicon)
{
argv = programicon->do_ToolTypes;
newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
fast = argbool (argv, "Fast", fast);
maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
scalefac = argint (argv, "ScaleFactor", scalefac);
winleft = argint (argv, "WinLeft", winleft);
wintop = argint (argv, "WinTop", wintop);
innerheight = argint (argv, "WinHeight", innerheight);
innerwidth = argint (argv, "WinWidth", innerwidth);
coords = argbool (argv, "Coordinates", coords);
crosshair = argbool (argv, "Crosshair", crosshair);
argstring (setoriginkey, argv, "SetOriginKey");
argstring (resetoriginkey, argv, "ResetOriginKey");
fixed = argbool (argv, "Fixed", fixed);
argstring (showhidekey, argv, "ShowHideKey");
hide = argbool (argv, "Iconify", hide);
hideonclose = argbool (argv, "IconifyOnClose", hideonclose);
grid = argbool (argv, "Grid", grid);
showrgb = argbool (argv, "ShowRGB", showrgb);
argstring (iffpath, argv, "IFFFile", 255);
jumptoactivescreen = argbool (argv, "JumpToActiveScreen", jumptoactivescreen);
argstring (language, argv, "LANGUAGE", 20);
FreeDiskObject (programicon);
}
CloseLibrary (IconBase);
}
if (Cli ())
{
memset (args, '\0', 21 * sizeof (LONG));
args[1] = fast;
args[8] = coords;
args[9] = crosshair;
args[12] = fixed;
args[14] = hide;
args[15] = hideonclose;
args[16] = grid;
args[17] = showrgb;
args[19] = jumptoactivescreen;
rdargs = ReadArgs (Template, args, NULL);
if (rdargs)
{
if (*args) newbroker.nb_Pri = *args;
args++;
fast = *args++;
if (*args) maxscalefac = *(LONG *) *args;
if (*++args) scalefac = *(LONG *) *args;
if (*++args) winleft = *(LONG *) *args;
if (*++args) wintop = *(LONG *) *args;
if (*++args) innerwidth = *(LONG *) *args;
if (*++args) innerheight = *(LONG *) *args;
args++;
coords = *args++;
crosshair = *args++;
if (*args) strncpy (setoriginkey, (char *) *args, 49);
if (*++args) strncpy (resetoriginkey, (char *) *args, 49);
args++;
fixed = *args++;
if (*args) strncpy (showhidekey, (char *) *args, 49);
args++;
hide = *args++;
hideonclose = *args++;
grid = *args++;
showrgb = *args++;
if (*args) strncpy (iffpath, (char *) *args, 255);
args++;
jumptoactivescreen = *args++ != 0;
if (*args) strncpy (language, (char *) *args, 19);
FreeArgs (rdargs);
}
}
if (maxscalefac < 5) maxscalefac = 5;
// not lower than innerheight or innerwidth
// otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
// can go to 0 -> 'AllocBitMap ()' failed
if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
if (scalefac > maxscalefac) scalefac = maxscalefac;
if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
char *str;
str = strrchr (iffpath, '/');
if (str)
{
strncpy (iffname, str + 1, 108);
*str = '\0';
}
else if ((str = strrchr (iffpath, ':')) != 0)
{
strncpy (iffname, ++str, 108);
*str = '\0';
}
else
{
strncpy (iffname, iffpath, 108);
iffpath[0] = '\0';
}
}
//- main ---------------------------------------
struct Library *openlib (char *libname, ULONG ver)
{
struct Library *lib;
lib = OpenLibrary (libname, ver);
if (!lib)
{
error (GetString (TXT_ERROR_LIBRARY), libname, ver);
throw (1);
}
return lib;
}
void main ()
{
try
{
CxBase = openlib ("commodities.library", 37);
GfxBase = (struct GfxBase *) openlib ("graphics.library", 39);
GadToolsBase = openlib ("gadtools.library", 37);
WorkbenchBase = openlib ("workbench.library", 37);
AslBase = openlib ("asl.library", 37);
UtilityBase = openlib ("utility.library", 37);
CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
LocaleBase = OpenLibrary ("locale.library", 38);
InitRastPort (&destrp);
SetAPen (&destrp, 0);
InitRastPort (&maskrp);
SetDrMd (&maskrp, COMPLEMENT);
thistask = FindTask (NULL);
if ((topazfont = OpenFont (&topaz_attr)) != 0)
{
try
{
setupscreen (NULL); // needed before readargs ()
readargs ();
OpenlupeCatalog (0, language[0] ? language : 0);
getoffsets ();
if (hide)
{
hidewindow ();
}
else
{
openwin ();
allocbm ();
}
if ((timesig = AllocSignal (-1L)) != -1)
{
if ((showhidesig = AllocSignal (-1L)) != -1)
{
try
{
initbroker ();
processmsg ();
}
catch (int) { };
if (broker)
{
DeleteCxObjAll (broker);
broker = NULL;
}
if (broker_mp)
{
DeleteMsgPort (broker_mp);
broker_mp = NULL;
}
FreeSignal (showhidesig);
}
else
{
error (GetString (TXT_ERROR_SIGNAL));
}
FreeSignal (timesig);
}
else
{
error (GetString (TXT_ERROR_SIGNAL));
}
} // try
catch (int) { }
closewin ();
CloseDownScreen ();
freeappicon ();
CloseFont (topazfont);
if (screenfont)
{
CloseFont (screenfont);
}
}
else
{
error (GetString (TXT_ERROR_FONT));
}
CloselupeCatalog ();
if (LocaleBase)
{
CloseLibrary (LocaleBase);
}
if (CyberGfxBase)
{
CloseLibrary (CyberGfxBase);
}
CloseLibrary (UtilityBase);
CloseLibrary (AslBase);
CloseLibrary (WorkbenchBase);
CloseLibrary (GadToolsBase);
CloseLibrary ((struct Library *) GfxBase);
CloseLibrary (CxBase);
}
catch (int) { }
}