// Lupe V1.0 - June 1995 - © Frank Toepper // a simple lens // AmigaOS 3.0 #include <intuition/intuition.h> #include <intuition/imageclass.h> #include <intuition/icclass.h> #include <intuition/gadgetclass.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 <graphics/displayinfo.h> #include <graphics/gfxmacros.h> #include <clib/intuition_protos.h> #include <clib/graphics_protos.h> #include <clib/exec_protos.h> #include <clib/commodities_protos.h> #include <clib/gadtools_protos.h> #include <wbstartup.h> #pragma header #define MAXSCALEFAC 20 ULONG innerwidth = 200, innerheight = 100, scalefac = MAXSCALEFAC / 2; ULONG cxsigflag, scrdepth; LONG waitmask = 0; UWORD leftoff, topoff, bottomoff, rightoff; WORD sizeiw, sizeih, winx, winy, winleft = 0, wintop; BYTE timesig; APTR VisualInfo; struct MsgPort *broker_mp, *userport; struct Task *thistask; struct Window *mywin = NULL; struct Screen *scr = NULL; struct Menu *menu; struct MenuItem *item; struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm; BOOL hires, newlook, jump = FALSE, mm = TRUE; CxObj *broker, *customcxobj; Object *propgadget; char pubscreenname[MAXPUBSCREENNAME]; struct Library *CxBase, *GfxBase, *GadToolsBase; extern struct ExecBase *SysBase; BOOL jumpFunc (); BOOL mmFunc (); BOOL AboutFunc (); BOOL QuitFunc (); struct EasyStruct es_about = { 20, 0, "Lupe", "%s%s%s\n\n%s\n%s\n%s\n%s\n%s\n%s\n\n%s\n%s\n\n%s", "%s" }; char *era_about[] = { "Lupe V1.0 (", __DATE__, ")", "written by:", " Frank Toepper", " Maxim Gorki Strasse 5A", " Greifswald", " 17491", " GERMANY", "EMail:", " toepper@rz.uni-greifswald.de", "This program is Public Domain", "Ok" }; struct NewBroker newbroker = { NB_VERSION, "Lupe", "Lupe V1.0", "A Simple Lens", 3, 0, 0, NULL, 0 }; 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 }; int setupscreen () { struct Screen *tmpscr; if (scr) { if (NextPubScreen (scr, pubscreenname)) { if ((tmpscr = LockPubScreen (pubscreenname)) != scr) { FreeVisualInfo (VisualInfo); UnlockPubScreen (NULL, scr); scr = tmpscr; } else return 1; } } else if (!(scr = LockPubScreen (NULL))) return 2; if (!(VisualInfo = GetVisualInfoA (scr, NULL))) return 3; return 0L; } void CloseDownScreen () { if (VisualInfo) { FreeVisualInfo (VisualInfo); VisualInfo = NULL; } if (scr) { UnlockPubScreen (NULL, scr); scr = NULL; } } void getoffsets () { struct DrawInfo *drawinfo; APTR sizeobject; ULONG attr; hires = !(scr->Flags & SCREENHIRES); hires ? (rightoff = 18) : (rightoff = 13); if (drawinfo = GetScreenDrawInfo (scr)) { if (sizeobject = NewObject (NULL, SYSICLASS, SYSIA_Which, SIZEIMAGE, SYSIA_DrawInfo, drawinfo, SYSIA_Size, hires ? SYSISIZE_HIRES : SYSISIZE_MEDRES)) { 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); DisposeObject (sizeobject); } FreeScreenDrawInfo (scr, drawinfo); } topoff = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1; leftoff = scr->WBorLeft; bottomoff = scr->WBorBottom; scrbm = &scr->BitMap; scrdepth = scr->BitMap.Depth; } int allocbm () { if (destbm) FreeBitMap (destbm); if (srcbm) FreeBitMap (srcbm); winx = mywin->Width; winy = mywin->Height; innerwidth = winx - (leftoff + rightoff); innerheight = winy - (topoff + bottomoff); if (!(srcbm = AllocBitMap (innerwidth / scalefac, innerheight / scalefac, scrdepth, BMF_CLEAR, scrbm))) return 1; if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, scrbm))) return 2; bsa.bsa_SrcWidth = innerwidth / scalefac; bsa.bsa_SrcHeight = innerheight / scalefac; bsa.bsa_DestWidth = innerwidth; bsa.bsa_DestHeight = innerheight; bsa.bsa_SrcBitMap = srcbm; bsa.bsa_DestBitMap = destbm; bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac; return 0; } BOOL openwin () { WORD bw, rh; struct Rectangle zoom = { 60 + leftoff + rightoff, 30 + topoff + bottomoff + sizeih, -1, -1 }; struct NewMenu newmenu[] = { { NM_TITLE, "Project", 0, 0, 0, 0, }, { NM_ITEM, "Jump", "J", 0, 0, jumpFunc, }, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, }, { NM_ITEM, "MouseMove", "M", (mm ? CHECKED : 0) | CHECKIT, 0, mmFunc, }, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, }, { NM_ITEM, "About", "A", 0, 0, AboutFunc, }, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, }, { NM_ITEM, "Quit", "Q", 0, 0, QuitFunc, }, }; if (hires) bw = rh = 2; else bw = rh = 1; if (menu = CreateMenusA (newmenu, NULL)) { if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE)) { if (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, GA_RelVerify, 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 (mywin = OpenWindowTags (NULL, WA_Activate, 1, WA_CloseGadget, 1, WA_DepthGadget, 1, WA_DragBar, 1, WA_SizeBRight, 1, WA_SizeGadget, 1, WA_AutoAdjust, 1, WA_SimpleRefresh, 1, WA_ReportMouse, 1, WA_NewLookMenus, 1, WA_MaxHeight, -1, WA_MaxWidth, -1, WA_MinHeight, 30 + topoff + bottomoff, WA_MinWidth, 60 + leftoff + rightoff, WA_IDCMP, CLOSEWINDOW | IDCMPUPDATE | NEWSIZE | MENUPICK | MOUSEMOVE, WA_Height, innerheight + topoff + bottomoff, WA_Width, innerwidth + leftoff + rightoff, WA_Left, winleft, WA_Gadgets, propgadget, WA_Top, wintop, WA_Title, "Lupe", WA_PubScreen, scr, WA_Zoom, &zoom, TAG_DONE)) { SetMenuStrip (mywin, menu); userport = mywin->UserPort; ScreenToFront (scr); return TRUE; } } } } return FALSE; } void closewin () { ClearMenuStrip (mywin); CloseWindow (mywin); FreeMenus (menu); DisposeObject (propgadget); if (srcbm) FreeBitMap (srcbm); if (destbm) FreeBitMap (destbm); srcbm = NULL; destbm = NULL; } void refresh () { LONG x, y; x = scr->MouseX - innerwidth / scalefac / 2; y = scr->MouseY - innerheight / scalefac / 2; if (x < 0) x = 0; if (x > (scr->Width - innerwidth / scalefac)) x = scr->Width - innerwidth / scalefac; if (y < 0) y = 0; if (y > (scr->Height - innerheight / scalefac)) y = scr->Height - innerheight / scalefac; BltBitMap (scrbm, x, y, srcbm, 0, 0, innerwidth / scalefac, innerheight / scalefac, ABNC | ABC, ~0, NULL); WaitBlit (); if (scalefac) { BitMapScale (&bsa); WaitBlit (); if ((winx == mywin->Width) && (winy == mywin->Height)) BltBitMapRastPort (destbm, 0, 0, mywin->RPort, leftoff, topoff, innerwidth, innerheight, ABNC | ABC); } else BltBitMapRastPort (srcbm, 0, 0, mywin->RPort, leftoff, topoff, innerwidth, innerheight, ABNC | ABC); WaitBlit (); } void CxFunction (CxMsg *cxm, CxObj *co) { struct InputEvent *ie; ie = (struct InputEvent *) CxMsgData (cxm); if ((ie->ie_Class == IECLASS_TIMER) || ((ie->ie_Class == IECLASS_RAWMOUSE) && mm)) Signal (thistask, 1 << timesig); } BOOL initbroker () { if (broker_mp = CreateMsgPort ()) { newbroker.nb_Port = broker_mp; cxsigflag = 1L << broker_mp->mp_SigBit; if (broker = CxBroker (&newbroker, NULL)) { if (customcxobj = CxCustom (CxFunction, 0L)) { if (!CxObjError (customcxobj)) { AttachCxObj (broker, customcxobj); ActivateCxObj (broker, 1L); return TRUE; } } } } return FALSE; } void processmsg () { struct IntuiMessage *intuimsg = NULL, m; CxMsg *msg; BOOL cont = TRUE; LONG sigmask, msgid, msgtype;; UWORD code; static BOOL (*func)(); waitmask = (1 << userport->mp_SigBit) | (1 << timesig) | cxsigflag | SIGBREAKF_CTRL_C; while (cont) { sigmask = Wait (waitmask); if (sigmask & cxsigflag) { while (msg = (CxMsg *) GetMsg (broker_mp)) { msgid = CxMsgID (msg); msgtype = CxMsgType (msg); ReplyMsg ((struct Message *) msg); switch (msgtype) { case CXM_COMMAND: switch (msgid) { case CXCMD_DISABLE: ActivateCxObj (broker, 0L); break; case CXCMD_ENABLE: ActivateCxObj (broker, 1L); break; case CXCMD_UNIQUE: case CXCMD_KILL: cont = FALSE; break; } } } } if (sigmask & (1 << userport->mp_SigBit)) { jump = FALSE; while (intuimsg = (struct IntuiMessage *) GetMsg (userport)) { CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage)); ReplyMsg ((struct Message *) intuimsg); switch (m.Class) { case CLOSEWINDOW: cont = FALSE; break; case NEWSIZE: if (allocbm ()) cont = FALSE; break; case IDCMPUPDATE: ULONG h; GetAttr (PGA_Top, propgadget, &h); if (++h != scalefac) { scalefac = h; if (allocbm ()) cont = FALSE; } break; case MENUPICK: code = m.Code; while ((code != MENUNULL) && cont && !jump) { item = ItemAddress (menu, code); func = (BOOL (*)()) GTMENUITEM_USERDATA (item); cont = func (); if (!jump) code = item->NextSelect; } break; } } } if (sigmask & (1 << timesig)) { refresh (); } if (sigmask & SIGBREAKF_CTRL_C) { cont = FALSE; } } } BOOL mmFunc () { if ((mm == FALSE) && (item->Flags & CHECKED)) mm = TRUE; else if (mm && !(item->Flags & CHECKED)) mm = FALSE; return TRUE; } BOOL AboutFunc () { EasyRequestArgs (NULL, &es_about, NULL, era_about); return TRUE; } BOOL jumpFunc () { int returnvalue; if (!(returnvalue = setupscreen ())) { waitmask &= ~(1 << userport->mp_SigBit); wintop = mywin->TopEdge; winleft = mywin->LeftEdge; closewin (); getoffsets (); if (!openwin ()) return FALSE; waitmask |= 1 << userport->mp_SigBit; if (allocbm ()) return FALSE; jump = TRUE; return TRUE; } else if (returnvalue == 1) return TRUE; // kein anderer Pubscreen return FALSE; } BOOL QuitFunc () { return FALSE; } void main () { if (CxBase = OpenLibrary ("commodities.library", 37)) { if (GfxBase = OpenLibrary ("graphics.library", 39)) { if (GadToolsBase = OpenLibrary ("gadtools.library", 37)) { if (!setupscreen ()) { getoffsets (); wintop = topoff; if (scr->Height > 300) innerheight <<= 1; if (openwin ()) { if (!allocbm ()) { if ((timesig = AllocSignal (-1L)) != -1) { thistask = SysBase->ThisTask; if (initbroker ()) { processmsg (); DeleteCxObjAll (broker); } FreeSignal (timesig); } } closewin (); } CloseDownScreen (); } CloseLibrary (GadToolsBase); } CloseLibrary (GfxBase); } CloseLibrary (CxBase); } }