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 >
C/C++ Source or Header  |  1997-04-14  |  62KB  |  2,416 lines

  1. // Lupe V1.8 - 1995-97 - © Frank Toepper
  2. // a lens
  3. // AmigaOS 3.0+
  4. // Maxon C++
  5. // last changes: 11.Apr.97
  6.  
  7. #include <string.h>
  8. #include <iostream.h>
  9. #include <ctype.h>
  10. #include <intuition/intuition.h>
  11. #include <intuition/imageclass.h>
  12. #include <intuition/icclass.h>
  13. #include <intuition/gadgetclass.h>
  14. #include <intuition/intuitionbase.h>
  15. #include <exec/exec.h>
  16. #include <dos/dos.h>
  17. #include <graphics/scale.h>
  18. #include <devices/inputevent.h>
  19. #include <libraries/commodities.h>
  20. #include <libraries/gadtools.h>
  21. #include <datatypes/pictureclass.h>
  22. #include <graphics/displayinfo.h>
  23. #include <graphics/gfxmacros.h>
  24. #include <graphics/gfxbase.h>
  25. #include <cybergraphics/cybergraphics.h>
  26. #include <clib/dos_protos.h>
  27. #include <pragma/dos_lib.h>
  28. #include <clib/intuition_protos.h>
  29. #include <pragma/intuition_lib.h>
  30. #include <clib/graphics_protos.h>
  31. #include <pragma/graphics_lib.h>
  32. #include <clib/exec_protos.h>
  33. #include <pragma/exec_lib.h>
  34. #include <clib/commodities_protos.h>
  35. #include <pragma/commodities_lib.h>
  36. #include <clib/gadtools_protos.h>
  37. #include <pragma/gadtools_lib.h>
  38. #include <clib/icon_protos.h>
  39. #include <pragma/icon_lib.h>
  40. #include <clib/cybergraphics_protos.h>
  41. #include <pragma/cybergraphics_lib.h>
  42. #include <clib/wb_protos.h>
  43. #include <pragma/wb_lib.h>
  44. #include <libraries/asl.h>
  45. #include <clib/asl_protos.h>
  46. #include <pragma/asl_lib.h>
  47. #include <clib/alib_protos.h>
  48. #include <pragma/utility_lib.h>
  49. #include <clib/utility_protos.h>
  50. #include <wbstartup.h>
  51.  
  52. #pragma header
  53.  
  54. #include "lupe_cat.h"
  55.  
  56. #define VERSION "Lupe V1.8"
  57.  
  58. #define CYBERARRAY_BPP 3
  59.  
  60. #define MINWIDTH 56
  61. #define MINHEIGHT 30
  62.  
  63. enum { SAMESCREEN, NEWSCREEN };
  64.  
  65. UWORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
  66. UWORD scalefac = 5, maxscalefac = 15, minwidth;
  67. UWORD leftoff, topoff, bottomoff, rightoff;
  68. UWORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
  69. UWORD textoff, coordsstringlen, fontX, fontY, scrdepth;
  70. WORD fixedX = 0, fixedY = 0;
  71. ULONG cxsigflag, waitmask = 0, pens[6];
  72. LONG oldx, oldy;
  73. APTR VisualInfo = NULL;
  74. BPTR fh;
  75. struct MsgPort *broker_mp, *userport, *app_mp = NULL;
  76. struct Task *thistask;
  77. struct Window *mywin;
  78. struct Screen *scr = NULL, *tmpscr;
  79. struct Menu *menu = NULL;
  80. struct MenuItem *item;
  81. struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm, *maskbm = NULL;
  82. struct TextFont *screenfont = NULL, *topazfont;
  83. struct InputXpression setoriginix, resetoriginix, showhideix;
  84. struct RastPort *scrrp, destrp, *winrp, maskrp;
  85. struct Library *CxBase, *GadToolsBase, *CyberGfxBase, *IconBase;
  86. struct Library *WorkbenchBase, *AslBase, *LocaleBase, *UtilityBase;
  87. struct GfxBase *GfxBase;
  88. struct AppIcon *appicon = NULL;
  89. struct AppMessage *appmsg;
  90. struct DiskObject *icon = NULL;
  91. UBYTE timesig, showhidesig;
  92. BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
  93. BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE;
  94. BOOL jumpdirect, showhide = TRUE, hide = FALSE, hideonclose = FALSE, grid = FALSE;
  95. BOOL showrgb = FALSE, jumptoactivescreen = FALSE, screentofront = TRUE;
  96. CxObj *broker, *customcxobj;
  97. Object *propgadget;
  98. char pubscreenname[MAXPUBSCREENNAME];
  99. char setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r", showhidekey[50] = "lalt h";
  100. char title[10], dispstring[12], language[20] = "";
  101. char programname[110], iffpath[256] = "ram:Lupe.iff", iffname[110];
  102. char *Template = "CX_PRIORITY=P/N/K, FAST=F/S/K, MAXSCALEFACTOR=M/N/K, SCALEFACTOR=S/N/K, "
  103.                  "WINLEFT=L/N/K, WINTOP=T/N/K, WINWIDTH=W/N/K, WINHEIGHT=H/N/K, "
  104.                  "COORDINATES=C/S/K, CROSSHAIR=R/S/K, SETORIGINKEY=O/K, RESETORIGINKEY=K/K, "
  105.                  "FIXED=D/S/K, SHOWHIDEKEY=SH/K, ICONIFY=I/S/K, ICONIFYONCLOSE=IOC/S/K, "
  106.                  "GRID=G/S/K, SHOWRGB=RGB/S/K, IFFFILE=IF/K, JUMPTOACTIVESCREEN=JAS/S/K, "
  107.                  "LANGUAGE=U";
  108.  
  109. struct BitScaleArgs bsa = {
  110.    // Src Koords
  111.    0, 0,
  112.    innerwidth / scalefac,
  113.    innerheight / scalefac,
  114.    // Src Faktoren
  115.    1, 1,
  116.    0, 0,
  117.    innerwidth,
  118.    innerheight,
  119.    // Dest Faktoren
  120.    scalefac, scalefac,
  121.    // Bitmaps
  122.    NULL, NULL,
  123.    0,
  124.    0, 0,
  125.    0, 0
  126. };
  127.  
  128. struct TextAttr topaz_attr = {
  129.    "topaz.font",
  130.    8,
  131.    0,
  132.    FPF_ROMFONT
  133. };
  134.  
  135. struct NewBroker newbroker = {
  136.    NB_VERSION,
  137.    "Lupe",
  138.    VERSION " © 1995-97 Frank Toepper",
  139.    0,
  140.    3,
  141.    COF_SHOW_HIDE,
  142.    0,
  143.    NULL,
  144.    0
  145. };
  146.  
  147. extern struct IntuitionBase *IntuitionBase;
  148.  
  149. // function declarations for menu
  150. BOOL jumpFunc ();
  151. BOOL jumptoactiveFunc ();
  152. BOOL saveFunc ();
  153. BOOL fastFunc ();
  154. BOOL AboutFunc ();
  155. BOOL enableFunc ();
  156. BOOL coordsFunc ();
  157. BOOL crosshairFunc ();
  158. BOOL gridFunc ();
  159. BOOL showrgbFunc ();
  160. BOOL fixedFunc ();
  161. BOOL QuitFunc ();
  162. BOOL hideFunc ();
  163. BOOL hideoncloseFunc ();
  164.  
  165. //----------------------------------------------
  166.  
  167. void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
  168. {
  169.    *putchdata++ = zeichen;
  170. }
  171.  
  172. void error (char *formatstring, ...)
  173. {
  174.  APTR args = &formatstring + 1;
  175.  struct EasyStruct easystruct = {
  176.     sizeof (struct EasyStruct),
  177.     0,
  178.     GetString (TXT_ERROR),
  179.     formatstring,
  180.     GetString (TXT_OK)
  181.  };
  182.  
  183.    if (Cli ())
  184.    {
  185.       VPrintf (formatstring, (LONG *) args);
  186.       FPutC (Output (), '\n');
  187.       Flush (Output ());
  188.    }
  189.    else
  190.    {
  191.       EasyRequestArgs (NULL, &easystruct, NULL, args);
  192.    }
  193. }
  194.  
  195. //----------------------------------------------
  196.  
  197. BOOL lockaspublicscreen (struct Screen *screen)
  198. {
  199.  struct List *pubscreenlist;
  200.  struct PubScreenNode *pubscreennode;
  201.  
  202.    pubscreenlist = LockPubScreenList ();
  203.    if (pubscreenlist)
  204.    {
  205.       pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  206.       while (pubscreennode)
  207.       {
  208.          if (pubscreennode->psn_Screen == screen)
  209.          {
  210.             if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
  211.             {
  212.                UnlockPubScreenList ();
  213.                return TRUE;
  214.             }
  215.          }
  216.          pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  217.       }
  218.       UnlockPubScreenList ();
  219.    }
  220.    return FALSE;
  221. }
  222.  
  223. int setupscreen (struct Screen *selectedscreen)
  224. {
  225.  ULONG id;
  226.  
  227.    jumpdirect = FALSE;
  228.    if (selectedscreen)
  229.    {
  230.       jumpdirect = TRUE;
  231.       if (scr)
  232.       {
  233.          if (VisualInfo)
  234.          {
  235.             FreeVisualInfo (VisualInfo);
  236.          }
  237.          if (pubscreenlocked)
  238.          {
  239.             UnlockPubScreen (NULL, scr);
  240.          }
  241.       }
  242.       if (lockaspublicscreen (selectedscreen))
  243.       {
  244.          pubscreenlocked = TRUE;
  245.       }
  246.       else
  247.       {
  248.          pubscreenlocked = FALSE;
  249.       }
  250.       scr = selectedscreen;
  251.    }
  252.    else if (scr)
  253.    {
  254.       tmpscr = scr->NextScreen;
  255.       if (tmpscr)
  256.       {
  257.          FreeVisualInfo (VisualInfo);
  258.          VisualInfo = NULL;
  259.          if (pubscreenlocked)
  260.          {
  261.             UnlockPubScreen (NULL, scr);
  262.             pubscreenlocked = FALSE;
  263.          }
  264.          if (lockaspublicscreen (tmpscr))
  265.          {
  266.             pubscreenlocked = TRUE;
  267.          }
  268.       }
  269.       else
  270.       {
  271.          error (GetString (TXT_ERROR_NOOTHERSCREEN));
  272.          return SAMESCREEN;
  273.       }
  274.       scr = tmpscr;
  275.    }
  276.    else if ((scr = LockPubScreen (NULL)) != 0)
  277.    {
  278.       pubscreenlocked = TRUE;
  279.    }
  280.    else
  281.    {
  282.       error (GetString (TXT_ERROR_LOCKPUBSCREEN));
  283.       throw 1;
  284.    }
  285.    VisualInfo = GetVisualInfoA (scr, NULL);
  286.    if (!VisualInfo)
  287.    {
  288.       error (GetString (TXT_ERROR_VISUALINFO));
  289.       throw 2;
  290.    }
  291.    cybergfxscreen = FALSE;
  292.    if (CyberGfxBase)
  293.       if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
  294.          if (IsCyberModeID (id))
  295.             if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
  296.                cybergfxscreen = TRUE;
  297.    return NEWSCREEN;
  298. }
  299.  
  300. void CloseDownScreen ()
  301. {
  302.    if (VisualInfo)
  303.    {
  304.       FreeVisualInfo (VisualInfo);
  305.       VisualInfo = NULL;
  306.    }
  307.    if (scr && pubscreenlocked)
  308.    {
  309.       UnlockPubScreen (NULL, scr);
  310.       pubscreenlocked = FALSE;
  311.    }
  312. }
  313.  
  314. void getoffsets ()
  315. {
  316.  struct DrawInfo *drawinfo;
  317.  APTR sizeobject;
  318.  ULONG attr;
  319.  
  320.    if (screenfont)
  321.    {
  322.       CloseFont (screenfont);
  323.       screenfont = NULL;
  324.    }
  325.    hires = (scr->Flags & SCREENHIRES) != 0;
  326.    hires ? (rightoff = 18) : (rightoff = 13);
  327.    SetAPen (&maskrp, 1);
  328.    drawinfo = GetScreenDrawInfo (scr);
  329.    if (drawinfo)
  330.    {
  331.       // dimension of the border
  332.       sizeobject = NewObject (NULL, SYSICLASS,
  333.        SYSIA_Which, SIZEIMAGE, SYSIA_DrawInfo, drawinfo,
  334.        SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES, TAG_END);
  335.       if (sizeobject)
  336.       {
  337.          if (GetAttr (IA_Width, sizeobject, &attr))
  338.          {
  339.             sizeiw = attr;
  340.             rightoff =  (UWORD) attr;
  341.          }
  342.          if (GetAttr (IA_Height, sizeobject, &attr))
  343.          {
  344.             sizeih = attr;
  345.          }
  346.          newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
  347.          SetAPen (&maskrp, drawinfo->dri_Pens[SHADOWPEN]);
  348.          DisposeObject (sizeobject);
  349.       }
  350.       pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
  351.       pens[1] = drawinfo->dri_Pens[FILLPEN];
  352.       pens[2] = drawinfo->dri_Pens[TEXTPEN];
  353.       pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
  354.       pens[4] = drawinfo->dri_Pens[SHINEPEN];
  355.       pens[5] = drawinfo->dri_Pens[SHADOWPEN];
  356.       FreeScreenDrawInfo (scr, drawinfo);
  357.    }
  358.    else
  359.    {
  360.       // default pens
  361.       pens[0] = 2;
  362.       pens[1] = 3;
  363.       pens[2] = 1;
  364.       pens[3] = 0;
  365.       pens[4] = 2;
  366.       pens[5] = 1;
  367.    }  // if (drawinfo)
  368.    scrrp = &scr->RastPort;
  369.    topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
  370.    leftoff = scr->WBorLeft;
  371.    scrbm = scrrp->BitMap;
  372.    scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
  373.    fontX = topazfont->tf_XSize;
  374.    fontY = topazfont->tf_YSize;
  375.    minwidth = MINWIDTH;
  376.    coordsstringlen = 1;
  377.    if (scr->Width > 999)
  378.    {
  379.       coordsstringlen += 5;
  380.    }
  381.    else
  382.    {
  383.       coordsstringlen += 4;
  384.    }
  385.    if (scr->Height > 999)
  386.    {
  387.       coordsstringlen += 5;
  388.    }
  389.    else
  390.    {
  391.       coordsstringlen += 4;
  392.    }
  393.    if (coords || showrgb)
  394.    {
  395.       bottomoff = sizeih;
  396.       // center the text in the bottomborder
  397.       textoff = (bottomoff + fontY >> 1) - topazfont->tf_Baseline;
  398.       minwidth = 0;
  399.       if (coords)
  400.       {
  401.          minwidth = coordsstringlen * (fontX);
  402.       }
  403.       if (showrgb)
  404.       {
  405.          minwidth += 13 * (fontX);
  406.       }
  407.       // SysIHack or height of screenfont <= 8?
  408.       if ((bottomoff - 2) >= scr->Font->ta_YSize)
  409.       {
  410.          screenfont = OpenFont (scr->Font);
  411.          if (screenfont)
  412.          {
  413.             if (!(screenfont->tf_Flags & FPF_PROPORTIONAL))
  414.             {
  415.                fontX = screenfont->tf_XSize;
  416.                fontY = screenfont->tf_YSize;
  417.                minwidth = 0;
  418.                if (coords)
  419.                {
  420.                   minwidth = coordsstringlen * (fontX);
  421.                }
  422.                if (showrgb)
  423.                {
  424.                   minwidth += 13 * (fontX);
  425.                }
  426.                // center the text in the bottomborder
  427.                textoff = (bottomoff + fontY >> 1) - screenfont->tf_Baseline;
  428.             }
  429.             else
  430.             {
  431.                CloseFont (screenfont);
  432.                screenfont = NULL;               
  433.             }
  434.          }
  435.       }
  436.    }  // if (coords
  437.    else
  438.    {
  439.       bottomoff = scr->WBorBottom;
  440.    }
  441. }
  442.  
  443. void setwintitle ()
  444. {
  445.  LONG args[] = { (LONG) "Lupe", scalefac };
  446.  
  447.    RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
  448.    SetWindowTitles (mywin, title, (STRPTR) ~0);
  449. }
  450.  
  451. void setmenu ()
  452. {
  453.  struct MenuItem *mitem;
  454.  
  455.    if (mywin)
  456.    {
  457.       ClearMenuStrip (mywin);
  458.  
  459.       mitem = ItemAddress (menu, FULLMENUNUM (0, 2, NOSUB));
  460.       if (jumptoactivescreen) mitem->Flags |= CHECKED;
  461.       else mitem->Flags &= ~CHECKED;
  462.  
  463.       mitem = ItemAddress (menu, FULLMENUNUM (0, 6, NOSUB));
  464.       if (enable) mitem->Flags |= CHECKED;
  465.       else mitem->Flags &= ~CHECKED;
  466.  
  467.       mitem = mitem->NextItem;
  468.       if (fixed) mitem->Flags |= CHECKED;
  469.       else mitem->Flags &= ~CHECKED;
  470.  
  471.       mitem = mitem->NextItem;
  472.       if (fast) mitem->Flags |= CHECKED;
  473.       else mitem->Flags &= ~CHECKED;
  474.  
  475.       mitem = mitem->NextItem;
  476.       if (coords) mitem->Flags |= CHECKED;
  477.       else mitem->Flags &= ~CHECKED;
  478.  
  479.       mitem = mitem->NextItem;
  480.       if (crosshair) mitem->Flags |= CHECKED;
  481.       else mitem->Flags &= ~CHECKED;
  482.  
  483.       mitem = mitem->NextItem;
  484.       if (grid) mitem->Flags |= CHECKED;
  485.       else mitem->Flags &= ~CHECKED;
  486.  
  487.       mitem = mitem->NextItem;
  488.       if (showrgb) mitem->Flags |= CHECKED;
  489.       else mitem->Flags &= ~CHECKED;
  490.  
  491.       mitem = ItemAddress (menu, FULLMENUNUM (0, 16, NOSUB));
  492.       if (hideonclose) mitem->Flags |= CHECKED;
  493.       else mitem->Flags &= ~CHECKED;
  494.  
  495.       ResetMenuStrip (mywin, menu);
  496.    }
  497. }
  498.  
  499. void setupgrid ()
  500. {
  501.  LONG i, j;
  502.  
  503.    if (maskbm)
  504.    {
  505.       WaitBlit ();
  506.       FreeBitMap (maskbm);
  507.       maskbm = NULL;
  508.    }
  509.    if (grid)
  510.    {
  511.       maskbm = AllocBitMap (innerwidth, innerheight, 1, BMF_CLEAR, destbm);
  512.       if (!maskbm)
  513.       {
  514.          error (GetString (TXT_ERROR_GRIDMASK));
  515.          grid = FALSE;
  516.          setmenu ();
  517.       }
  518.       else
  519.       {
  520.          maskrp.BitMap = maskbm;
  521.          for (i = scalefac - 1; i < innerwidth; i += scalefac)
  522.          {
  523.             RectFill (&maskrp, i, 0, i, innerheight - 1)
  524.          }
  525.          for (i = scalefac - 1; i < innerheight; i += scalefac)
  526.          {
  527.             for (j = 0; j <= (innerwidth - scalefac); j += scalefac)
  528.             {
  529.                RectFill (&maskrp, j, i, j + scalefac - 2, i);
  530.             }
  531.          }
  532.       }
  533.    }
  534. }
  535.  
  536. void allocbm ()
  537. {
  538.    if (srcbm)
  539.    {
  540.       FreeBitMap (srcbm);
  541.       srcbm = NULL;
  542.    }
  543.    if (destbm)
  544.    {
  545.       FreeBitMap (destbm);
  546.       destbm = NULL;
  547.    }
  548.    winx = mywin->Width;
  549.    winy = mywin->Height;
  550.    innerwidth = winx - (leftoff + rightoff);
  551.    innerheight = winy - (topoff + bottomoff);
  552.    sourcewidth = innerwidth / scalefac;
  553.    sourceheight = innerheight / scalefac;
  554.    if (scalefac > 1)
  555.    {
  556.       if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, scrbm)))
  557.       {
  558.          error (GetString (TXT_ERROR_SOURCEBMP));
  559.          throw 1;
  560.       }
  561.       if (!(destbm = AllocBitMap (innerwidth, innerheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, srcbm)))
  562.       {
  563.          error (GetString (TXT_ERROR_DESTBMP));
  564.          throw 2;
  565.       }
  566.       bsa.bsa_SrcWidth = sourcewidth;
  567.       bsa.bsa_SrcHeight = sourceheight;
  568.       bsa.bsa_DestWidth = innerwidth;
  569.       bsa.bsa_DestHeight = innerheight;
  570.       bsa.bsa_SrcBitMap = srcbm;
  571.       bsa.bsa_DestBitMap = destbm;
  572.       bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
  573.       setupgrid ();
  574.       destrp.BitMap = destbm;
  575.    }
  576. }
  577.  
  578. void makescreenmenu ()
  579. {
  580.  struct NewMenu tmpmenu[] = {
  581.   { NM_SUB, 0, 0, 0, 0, 0 },
  582.   { NM_END, 0, 0, 0, 0, 0 }
  583.  };
  584.  ULONG lock;
  585.  struct List *pubscreenlist;
  586.  struct PubScreenNode *pubscreennode;
  587.  struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
  588.  
  589.    lock = LockIBase (0);
  590.    tmpscr = IntuitionBase->FirstScreen;
  591.    if (tmpscr->NextScreen)
  592.    {
  593.       while ((tmpscr = tmpscr->NextScreen) != 0)
  594.       {
  595.          (*tmpmenu).nm_Label = tmpscr->DefaultTitle;
  596.          pubscreenlist = LockPubScreenList ();
  597.          if (pubscreenlist)
  598.          {
  599.             pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  600.             while (pubscreennode)
  601.             {
  602.                if (pubscreennode->psn_Screen == tmpscr)
  603.                {
  604.                   if (pubscreennode->psn_Node.ln_Name)
  605.                   {
  606.                      tmpmenu->nm_Label = pubscreennode->psn_Node.ln_Name;
  607.                   }
  608.                   break;
  609.                }
  610.                pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  611.             }
  612.             UnlockPubScreenList ();
  613.          }
  614.          if (!tmpmenu->nm_Label)
  615.          {
  616.             tmpmenu->nm_Label = GetString (TXT_UNNAMED);
  617.          }
  618.          tmpmenu->nm_UserData = tmpscr;
  619.          // each item single created
  620.          *itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
  621.          if (*itempointer)
  622.          {
  623.             itempointer = &(*itempointer)->NextItem;
  624.          }
  625.          else
  626.          {
  627.             error (GetString (TXT_ERROR_SCREENMENUITEM));
  628.          }
  629.       }
  630.    }
  631.    else
  632.    {
  633.       tmpmenu->nm_Label = GetString (TXT_NOOTHERSCREEN);
  634.       *itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
  635.       if (*itempointer)
  636.       {
  637.          (*itempointer)->Flags |= HIGHNONE;
  638.          itempointer = &(*itempointer)->NextItem;
  639.       }
  640.       else
  641.       {
  642.          error (GetString (TXT_ERROR_SCREENMENU));
  643.       }
  644.    }
  645.    UnlockIBase (lock);
  646.    if (!LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
  647.    {
  648.       error (GetString (TXT_ERROR_LAYOUTMENU));
  649.       throw 1;
  650.    }
  651. }
  652.  
  653. void freescreenmenu (struct MenuItem *menuitem)
  654. {
  655.    if (menuitem)
  656.    {
  657.       freescreenmenu (menuitem->NextItem);
  658.       FreeMenus ((struct Menu *) menuitem);
  659.    }
  660. }
  661.  
  662. void openwin ()
  663.  struct NewMenu standardmenu[] = {
  664.    { NM_TITLE, GetString (TXT_PROJECT), 0, 0, 0, 0 },
  665.    {  NM_ITEM, GetString (TXT_JUMP), GetString (KEY_JUMP), 0, 0, jumpFunc },
  666.    {  NM_ITEM, GetString (TXT_JUMPTOSCREEN), 0, 0, 0, 0 },
  667.    {  NM_ITEM, GetString (TXT_JUMPTOACTIVESCREEN), GetString (KEY_JUMPTOACTIVESCREEN), CHECKIT | MENUTOGGLE, 0, jumptoactiveFunc },
  668.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
  669.    {  NM_ITEM, GetString (TXT_SAVEIFF), GetString (KEY_SAVEIFF), 0, 0, saveFunc },
  670.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
  671.    {  NM_ITEM, GetString (TXT_ENABLE), GetString (KEY_ENABLE), CHECKIT | MENUTOGGLE, 0, enableFunc },
  672.    {  NM_ITEM, GetString (TXT_FIXED), GetString (KEY_FIXED), CHECKIT | MENUTOGGLE, 0, fixedFunc },
  673.    {  NM_ITEM, GetString (TXT_FAST), GetString (KEY_FAST), CHECKIT | MENUTOGGLE, 0, fastFunc },
  674.    {  NM_ITEM, GetString (TXT_COORDINATES), GetString (KEY_COORDINATES), CHECKIT | MENUTOGGLE, 0, coordsFunc },
  675.    {  NM_ITEM, GetString (TXT_CROSSHAIR), GetString (KEY_CROSSHAIR), CHECKIT | MENUTOGGLE, 0, crosshairFunc },
  676.    {  NM_ITEM, GetString (TXT_GRID), GetString (KEY_GRID), CHECKIT | MENUTOGGLE, 0, gridFunc },
  677.    {  NM_ITEM, GetString (TXT_SHOWRGB), GetString (KEY_SHOWRGB), CHECKIT | MENUTOGGLE, 0, showrgbFunc },
  678.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
  679.    {  NM_ITEM, GetString (TXT_ABOUT), GetString (KEY_ABOUT), 0, 0, AboutFunc },
  680.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
  681.    {  NM_ITEM, GetString (TXT_ICONIFYONCLOSE), GetString (KEY_ICONIFYONCLOSE), CHECKIT | MENUTOGGLE, 0, hideoncloseFunc },
  682.    {  NM_ITEM, GetString (TXT_ICONIFY), GetString (KEY_ICONIFY), 0, 0, hideFunc },
  683.    {  NM_ITEM, GetString (TXT_QUIT), GetString (KEY_QUIT), 0, 0, QuitFunc },
  684.    {  NM_END, 0, 0, 0, 0, 0 }
  685.  };
  686.  ULONG lock;
  687.  WORD bw, rh;
  688.  struct Rectangle zoom = {
  689.     minwidth + leftoff + rightoff,
  690.     MINHEIGHT + topoff + bottomoff + sizeih,
  691.     9999, 9999
  692.  };
  693.  
  694.    if (!mywin)
  695.    {
  696.       if (hires)
  697.       {
  698.          bw = rh = 2;
  699.       }
  700.       else
  701.       {
  702.          bw = rh = 1;
  703.       }
  704.       if (screentofront)
  705.       {
  706.          // first bring the screen to front
  707.          //  -> screen order in menu correct
  708.          lock = LockIBase (0);
  709.          tmpscr = IntuitionBase->FirstScreen;
  710.          UnlockIBase (lock);
  711.          if (tmpscr != scr)
  712.          {
  713.             if (jumpdirect)
  714.             {
  715.                ScreenToFront (scr);
  716.             }
  717.             else
  718.             {
  719.                ScreenToBack (tmpscr);
  720.             }
  721.          }
  722.       }
  723.       else
  724.       {
  725.          // auto jump
  726.          screentofront = TRUE;
  727.       }
  728.       menu = CreateMenusA (standardmenu, NULL);
  729.       if (!menu)
  730.       {
  731.          error (GetString (TXT_ERROR_MENU));
  732.          throw (1);
  733.       }
  734.       makescreenmenu ();
  735.       propgadget = (Object *) NewObject (NULL, PROPGCLASS,
  736.         PGA_Freedom,     FREEVERT,
  737.         ICA_TARGET,      ICTARGET_IDCMP,
  738.         PGA_NewLook,     TRUE,
  739.         PGA_Borderless,  newlook,
  740.         PGA_Total,       maxscalefac,
  741.         PGA_Visible,     1,
  742.         PGA_Top,         scalefac - 1,
  743.         GA_RelRight,     bw - sizeiw + 3,
  744.         GA_Top,          topoff + rh,
  745.         GA_Width,        sizeiw - bw - bw - 4,
  746.         GA_RelHeight,    -topoff - sizeih - rh - rh,
  747.         GA_RightBorder,  TRUE,
  748.         TAG_DONE);
  749.       if (!propgadget)
  750.       {
  751.          error (GetString (TXT_ERROR_PROPGADGET));
  752.          throw (2);
  753.       }
  754.       if (innerwidth < minwidth)
  755.       {
  756.          innerwidth = minwidth;
  757.       }
  758.       mywin = OpenWindowTags (NULL,
  759.         WA_Flags,          WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET
  760.                             | WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH
  761.                             | WFLG_NEWLOOKMENUS | WFLG_REPORTMOUSE | WFLG_SIZEBRIGHT
  762.                             | ((coords || showrgb) ? WFLG_SIZEBBOTTOM : 0),
  763.         WA_AutoAdjust,     1,
  764.         WA_MaxHeight,      9999,
  765.         WA_MaxWidth,       9999,
  766.         WA_MinHeight,      MINHEIGHT + topoff + bottomoff,
  767.         WA_MinWidth,       minwidth + leftoff + rightoff,
  768.         WA_IDCMP,          IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE
  769.                             | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW
  770.                             | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
  771.                             | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY
  772.                             | IDCMP_REFRESHWINDOW,
  773.         WA_InnerHeight,    innerheight,
  774.         WA_InnerWidth,     innerwidth,
  775.         WA_Left,           winleft,
  776.         WA_Gadgets,        propgadget,
  777.         WA_Top,            wintop,
  778.         pubscreenlocked ? WA_PubScreen : WA_CustomScreen, scr,
  779.         WA_Zoom,           &zoom,
  780.         TAG_DONE);
  781.       if (!mywin)
  782.       {
  783.          error (GetString (TXT_ERROR_WINDOW));
  784.          throw (3);
  785.       }
  786.       // shit patches
  787.       leftoff = mywin->BorderLeft;
  788.       bottomoff = mywin->BorderBottom;
  789.       SetMenuStrip (mywin, menu);
  790.       setmenu ();
  791.       setwintitle ();
  792.       userport = mywin->UserPort;
  793.       winrp = mywin->RPort;
  794.       if (screenfont)
  795.       {
  796.          SetFont (winrp, screenfont);
  797.       }
  798.       else
  799.       {
  800.          SetFont (winrp, topazfont);
  801.       }
  802.       SetAPen (winrp, pens[0]);
  803.       SetBPen (winrp, pens[1]);
  804.       waitmask |= 1 << userport->mp_SigBit;
  805.    }
  806. }
  807.  
  808. void closewin ()
  809. {
  810.    if (mywin)
  811.    {
  812.       if (menu)
  813.       {
  814.          ClearMenuStrip (mywin);
  815.       }
  816.       wintop = mywin->TopEdge;
  817.       winleft = mywin->LeftEdge;
  818.       waitmask &= ~(1 << userport->mp_SigBit);
  819.       CloseWindow (mywin);
  820.       mywin = NULL;
  821.       userport = NULL;
  822.       jump = TRUE;
  823.    }
  824.    if (menu)
  825.    {
  826.       freescreenmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  827.       FreeMenus (menu);
  828.       menu = NULL;
  829.    }
  830.    if (propgadget)
  831.    {
  832.       DisposeObject (propgadget);
  833.       propgadget = NULL;
  834.    }
  835.    if (srcbm)
  836.    {
  837.       FreeBitMap (srcbm);
  838.       srcbm = NULL;
  839.    }
  840.    if (destbm)
  841.    {
  842.       FreeBitMap (destbm);
  843.       destbm = NULL;
  844.    }
  845.    if (maskbm)
  846.    {
  847.       FreeBitMap (maskbm);
  848.       maskbm = NULL;
  849.    }
  850. }
  851.  
  852. BOOL screen_is_still_open ()
  853. {
  854.    tmpscr = IntuitionBase->FirstScreen;
  855.    while (tmpscr)
  856.    {
  857.       if (tmpscr == scr)
  858.       {
  859.          return TRUE;
  860.       }
  861.       tmpscr = tmpscr->NextScreen;
  862.    }
  863.    return FALSE;
  864. }
  865.  
  866. void freeappicon ()
  867. {
  868.    if (appicon)
  869.    {
  870.       RemoveAppIcon (appicon);
  871.       appicon = NULL;
  872.    }
  873.    if (app_mp)
  874.    {
  875.       waitmask &= ~(1 << app_mp->mp_SigBit);
  876.       DeleteMsgPort (app_mp);
  877.       app_mp = NULL;
  878.    }
  879.    if (icon)
  880.    {
  881.       FreeDiskObject (icon);
  882.       icon = NULL;
  883.    }
  884. }
  885.  
  886. void showwindow ()
  887. {
  888.    if (!mywin)
  889.    {
  890.       if (!screen_is_still_open ())
  891.       {
  892.          scr = NULL;
  893.       }
  894.       setupscreen (scr);
  895.       getoffsets ();
  896.       openwin ();
  897.       allocbm ();
  898.       freeappicon ();
  899.    }
  900. }
  901.  
  902. void hidewindow ()
  903. {
  904.    closewin ();
  905.    CloseDownScreen ();
  906.  
  907.    freeappicon ();
  908.  
  909.    if (Cli ())
  910.    {
  911.       GetProgramName (programname, 108);
  912.    }
  913.    else
  914.    {
  915.       strncpy (programname, thistask->tc_Node.ln_Name, 108);
  916.    }
  917.    icon = GetDiskObject ("ENV:sys/def_Lupe");
  918.    if (!icon)
  919.    {
  920.       icon = GetDiskObject (programname);
  921.       if (!icon)
  922.       {
  923.          icon = GetDefDiskObject (WBTOOL);
  924.       }
  925.    }
  926.    if (icon)
  927.    {
  928.       app_mp = CreateMsgPort ();
  929.       if (app_mp)
  930.       {
  931.          appicon = AddAppIcon (1, 0, "Lupe", app_mp, NULL, icon, NULL);
  932.          if (appicon)
  933.          {
  934.             waitmask |= 1 << app_mp->mp_SigBit;
  935.          }
  936.       }
  937.    }
  938. }
  939.  
  940. //- refresh ------------------------------------
  941.  
  942. void printcoords (LONG x, LONG y)
  943. {
  944.    if (coords)
  945.    {
  946.     LONG args[] = {x - originX, y - originY};
  947.  
  948.       memset (dispstring, ' ', coordsstringlen);
  949.       RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, dispstring);
  950.       dispstring[strlen (dispstring)] = ' ';
  951.       mywin->Flags &= ~SIZEGADGET;
  952.       if ((winx == mywin->Width) && (winy == mywin->Height))
  953.       {
  954.          Move (winrp, leftoff, mywin->Height - textoff);
  955.          Text (winrp, dispstring, coordsstringlen);
  956.       }
  957.       mywin->Flags |= SIZEGADGET;
  958.    }
  959. }
  960.  
  961. void printrgb (LONG x, LONG y)
  962. {
  963.  ULONG colorreg, colors[3], apen, textlen, cybercolor;
  964.  
  965.    if (showrgb)
  966.    {
  967.       colorreg = ReadPixel (scrrp, x, y);
  968.       if (cybergfxscreen)
  969.       {
  970.          cybercolor = ReadRGBPixel (scrrp, x, y);
  971.          colors[0] = (cybercolor >> 16) & 0xff;
  972.          colors[1] = (cybercolor >> 8) & 0xff;
  973.          colors[2] = cybercolor & 0xff;
  974.       }
  975.       else
  976.       {
  977.          GetRGB32 (scr->ViewPort.ColorMap, colorreg, 1, colors);
  978.          colors[0] &= 0xff;
  979.          colors[1] &= 0xff;
  980.          colors[2] &= 0xff;
  981.       }
  982.       RawDoFmt ("%3ld,%3ld,%3ld", colors, (void (*)()) Putchar, dispstring);
  983.       textlen = TextLength (winrp, dispstring, 11);
  984.       apen = GetAPen (winrp);
  985.       mywin->Flags &= ~SIZEGADGET;
  986.       if ((winx == mywin->Width) && (winy == mywin->Height))
  987.       {        
  988.          Move (winrp, innerwidth - textlen, mywin->Height - textoff);
  989.          Text (winrp, dispstring, 11);
  990.          SetAPen (winrp, pens[5]);
  991.          Move (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - 2);
  992.          Draw (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY);
  993.          Draw (winrp, innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - fontY);
  994.          SetAPen (winrp, pens[4]);
  995.          Move (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1);
  996.          Draw (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - 1);
  997.          Draw (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - 1);
  998.          if (cybergfxscreen)
  999.          {
  1000.             FillPixelArray (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
  1001.               fontX - 1, fontY - 2, cybercolor);
  1002.          }
  1003.          else
  1004.          {
  1005.             SetAPen (winrp, colorreg);
  1006.             RectFill (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
  1007.               innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - 2);
  1008.          }
  1009.       }
  1010.       mywin->Flags |= SIZEGADGET;
  1011.       SetAPen (winrp, apen);
  1012.    }  // if (showrgb)
  1013. }
  1014.  
  1015. LONG adjustX (LONG &x)
  1016. {
  1017.  LONG xoff = 0;
  1018.  
  1019.    x -= sourcewidth >> 1;
  1020.    if (x < 0)
  1021.    {
  1022.       xoff = x;
  1023.       x = 0;
  1024.    }
  1025.    else if (x > (scr->Width - sourcewidth))
  1026.    {
  1027.       xoff = -(scr->Width - sourcewidth - x);
  1028.       x = scr->Width - sourcewidth;
  1029.    }
  1030.    return xoff;
  1031. }
  1032.  
  1033. LONG adjustY (LONG &y)
  1034. {
  1035.  LONG yoff = 0;
  1036.  
  1037.    y -= sourceheight >> 1;
  1038.    if (y < 0)
  1039.    {
  1040.       yoff = y;
  1041.       y = 0;
  1042.    }
  1043.    else if (y > (scr->Height - sourceheight))
  1044.    {
  1045.       yoff = -(scr->Height - sourceheight - y);
  1046.       y = scr->Height - sourceheight;
  1047.    }
  1048.    return yoff;
  1049. }
  1050.  
  1051. void refresh ()
  1052. {
  1053.  LONG x, y, xoff, yoff;
  1054.  
  1055.    if (mywin)
  1056.    {
  1057.       // set the coordinates
  1058.       if (enable)
  1059.       {
  1060.          if (fixed)
  1061.          {
  1062.             x = fixedX;
  1063.             y = fixedY;
  1064.          }
  1065.          else
  1066.          {
  1067.             x = scr->MouseX;
  1068.             y = scr->MouseY;
  1069.          }
  1070.          oldx = x;
  1071.          oldy = y;
  1072.       }
  1073.       else
  1074.       {
  1075.          x = oldx;
  1076.          y = oldy;
  1077.       }
  1078.       
  1079.       printcoords (x, y);
  1080.       printrgb (x, y);
  1081.  
  1082.       xoff = adjustX (x);
  1083.       yoff = adjustY (y);
  1084.  
  1085.       // calculate the crosshair
  1086.       if (crosshair)
  1087.       {
  1088.          xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac - 1 >> 1);
  1089.          yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac - 1 >> 1);
  1090.       }
  1091.  
  1092.       if (scalefac > 1)
  1093.       {
  1094.          // blit and scale
  1095.          BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
  1096.          BitMapScale (&bsa);
  1097.          // draw the grid
  1098.          if (grid)
  1099.          {
  1100.             SetDrMd (&destrp, JAM1);
  1101.             BltTemplate (maskbm->Planes[0], 0, maskbm->BytesPerRow, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac);
  1102.          }
  1103.          // draw the crosshair
  1104.          if (crosshair)
  1105.          {
  1106.             SetDrMd (&destrp, COMPLEMENT);
  1107.             RectFill (&destrp, xoff, 0, xoff, sourceheight * scalefac - 1);
  1108.             RectFill (&destrp, 0, yoff, sourcewidth * scalefac - 1, yoff);
  1109.          }
  1110.          mywin->Flags &= ~SIZEGADGET;
  1111.          if ((winx == mywin->Width) && (winy == mywin->Height))
  1112.          {
  1113.             BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1114.          }
  1115.          mywin->Flags |= SIZEGADGET;
  1116.       }
  1117.       else  // 1:1
  1118.       {
  1119.          mywin->Flags &= ~SIZEGADGET;
  1120.          if ((winx == mywin->Width) && (winy == mywin->Height))
  1121.          {
  1122.             BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  1123.             // draw the crosshair in 1:1
  1124.             if (crosshair)
  1125.             {
  1126.                SetDrMd (winrp, COMPLEMENT);
  1127.                RectFill (winrp, leftoff + xoff, topoff, leftoff + xoff, topoff + innerheight - 1);
  1128.                RectFill (winrp, leftoff, topoff + yoff, leftoff + innerwidth - 1, topoff + yoff);
  1129.                SetDrMd (winrp, JAM2);
  1130.             }
  1131.          }
  1132.          mywin->Flags |= SIZEGADGET;
  1133.       }
  1134.       if (!fast)
  1135.       {
  1136.          SetSignal (0, 1 << timesig);
  1137.       }
  1138.    }
  1139. }
  1140.  
  1141. //----------------------------------------------
  1142.  
  1143. void CxFunction (CxMsg *cxm, CxObj *co)
  1144. {
  1145.  struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
  1146.  
  1147.    if (origin)
  1148.    {
  1149.       if (MatchIX (ie, &setoriginix))
  1150.       {
  1151.          originX = scr->MouseX;
  1152.          originY = scr->MouseY;
  1153.          DisposeCxMsg (cxm);
  1154.          return;
  1155.       }
  1156.       if (MatchIX (ie, &resetoriginix))
  1157.       {
  1158.          originX = originY = 0;
  1159.          DisposeCxMsg (cxm);
  1160.          return;
  1161.       }
  1162.    }
  1163.    if (showhide)
  1164.    {
  1165.       if (MatchIX (ie, &showhideix))
  1166.       {
  1167.          Signal (thistask, 1 << showhidesig);
  1168.       }
  1169.    }
  1170.    if ((ie->ie_Class == IECLASS_TIMER) || fast)
  1171.    {
  1172.       Signal (thistask, 1 << timesig);
  1173.    }
  1174. }
  1175.  
  1176. void initbroker ()
  1177. {
  1178.  LONG errorcode;
  1179.  
  1180.    broker_mp = CreateMsgPort ();
  1181.    if (!broker_mp)
  1182.    {
  1183.       error (GetString (TXT_ERROR_COMMODITYMP));
  1184.       throw (1);
  1185.    }
  1186.    newbroker.nb_Port = broker_mp;
  1187.    newbroker.nb_Descr = GetString (TXT_DESCRIPTION),
  1188.    cxsigflag = 1 << broker_mp->mp_SigBit;
  1189.    broker = CxBroker (&newbroker, &errorcode);
  1190.    if (!broker)
  1191.    {
  1192.       if (errorcode == CBERR_SYSERR)
  1193.       {
  1194.          error (GetString (TXT_ERROR_COMMODITYBROKER));
  1195.       }
  1196.       throw (2);
  1197.    }
  1198.    customcxobj = CxCustom (CxFunction, 0);
  1199.    if (!customcxobj)
  1200.    {
  1201.       error (GetString (TXT_ERROR_COMMODITYCUSTOM));
  1202.       throw (3);
  1203.    }
  1204.    AttachCxObj (broker, customcxobj);
  1205.    if (CxObjError (customcxobj))
  1206.    {
  1207.       error (GetString (TXT_ERROR_COMMODITYBROKER));
  1208.       throw (4);
  1209.    }
  1210.    if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
  1211.    {
  1212.       origin = FALSE;
  1213.       error (GetString (TXT_ERROR_HOTKEY), "'Set Origin'");
  1214.    }
  1215.    if (ParseIX (showhidekey, &showhideix))
  1216.    {
  1217.       showhide = FALSE;
  1218.       error (GetString (TXT_ERROR_HOTKEY), "'Show/Hide Window'");
  1219.    }
  1220.    ActivateCxObj (broker, 1);
  1221. }
  1222.  
  1223. void reopenwin ()
  1224. {
  1225.    closewin ();
  1226.    getoffsets ();
  1227.    openwin ();
  1228.    allocbm ();
  1229. }
  1230.  
  1231. void setpropgad ()
  1232. {
  1233.    allocbm ();
  1234.    SetAttrs (propgadget, PGA_Top, scalefac - 1);
  1235.    RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
  1236.    setwintitle ();
  1237. }
  1238.  
  1239. BOOL menupick (UWORD code)
  1240. {
  1241.  static BOOL (*func)();
  1242.  
  1243.    while ((code != MENUNULL) && !jump)
  1244.    {
  1245.       item = ItemAddress (menu, code);
  1246.       if (SUBNUM (code) != NOSUB)
  1247.       {
  1248.          if (GTMENUITEM_USERDATA (item))  // 'no other screen'-submenu == 0
  1249.          {
  1250.             setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item));
  1251.             reopenwin ();
  1252.          }
  1253.       }
  1254.       else
  1255.       {
  1256.          func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
  1257.          if (func () == FALSE)
  1258.          {
  1259.             return FALSE;
  1260.          }
  1261.       }
  1262.       if (!jump) code = item->NextSelect;
  1263.    }
  1264.    return TRUE;
  1265. }
  1266.  
  1267. BOOL vanillakey (UWORD code)
  1268. {
  1269.  BOOL returnvalue = TRUE;
  1270.  
  1271.    code = ToUpper (code);
  1272.  
  1273.    if (code == ToUpper (*GetString (KEY_JUMP)))
  1274.    {
  1275.       returnvalue = jumpFunc ();    
  1276.    }
  1277.    else if (code == ToUpper (*GetString (KEY_JUMPTOACTIVESCREEN)))
  1278.    {
  1279.       jumptoactivescreen = !jumptoactivescreen;
  1280.       setmenu ();    
  1281.    }
  1282.    else if (code == ToUpper (*GetString (KEY_SAVEIFF)))
  1283.    {
  1284.       returnvalue = saveFunc ();
  1285.    }
  1286.    else if (code == ToUpper (*GetString (KEY_ENABLE)))
  1287.    {
  1288.       enable = !enable;
  1289.       ActivateCxObj (broker, enable);
  1290.       setmenu ();
  1291.    }
  1292.    else if (code == ToUpper (*GetString (KEY_FIXED)))
  1293.    {
  1294.       fixed = !fixed;
  1295.       fixedX = scr->MouseX;
  1296.       fixedY = scr->MouseY;
  1297.       setmenu ();
  1298.    }
  1299.    else if (code == ToUpper (*GetString (KEY_FAST)))
  1300.    {
  1301.       fast = !fast;
  1302.       setmenu ();
  1303.    }
  1304.    else if (code == ToUpper (*GetString (KEY_COORDINATES)))
  1305.    {
  1306.       coords = !coords;
  1307.       reopenwin ();
  1308.    }
  1309.    else if (code == ToUpper (*GetString (KEY_CROSSHAIR)))
  1310.    {
  1311.       crosshair = !crosshair;
  1312.       setmenu ();
  1313.    }
  1314.    else if (code == ToUpper (*GetString (KEY_GRID)))
  1315.    {
  1316.       grid = !grid;
  1317.       setupgrid ();
  1318.       setmenu ();
  1319.    }
  1320.    else if (code == ToUpper (*GetString (KEY_SHOWRGB)))
  1321.    {
  1322.       showrgb = !showrgb;
  1323.       reopenwin ();
  1324.    }
  1325.    else if (code == ToUpper (*GetString (KEY_ABOUT)))
  1326.    {
  1327.       returnvalue = AboutFunc ();
  1328.    }
  1329.    else if (code == ToUpper (*GetString (KEY_ICONIFYONCLOSE)))
  1330.    {
  1331.       hideonclose = !hideonclose;
  1332.       setmenu ();
  1333.    }
  1334.    else if (code == ToUpper (*GetString (KEY_ICONIFY)))
  1335.    {
  1336.       returnvalue = hideFunc ();
  1337.    }
  1338.    else if (code == ToUpper (*GetString (KEY_QUIT)))
  1339.    {
  1340.       returnvalue = FALSE;
  1341.    }
  1342.    else switch (code)
  1343.    {
  1344.     case 27:  // ESC
  1345.       if (hideonclose)
  1346.       {
  1347.          hidewindow ();
  1348.          jump = TRUE;
  1349.       }
  1350.       else
  1351.       {
  1352.          returnvalue = FALSE;
  1353.       }
  1354.       break;
  1355.     case '+':
  1356.       if (scalefac < maxscalefac)
  1357.       {
  1358.          scalefac++;
  1359.          setpropgad ();
  1360.       }
  1361.       break;
  1362.     case '-':
  1363.       if (scalefac > 1)
  1364.       {
  1365.          scalefac--;
  1366.          setpropgad ();
  1367.       }
  1368.       break;
  1369.    }
  1370.    return returnvalue;
  1371. }
  1372.  
  1373. void rawkey (UWORD code, UWORD qualifier)
  1374. {
  1375.    switch (code)
  1376.    {
  1377.     // up
  1378.     case 76:
  1379.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1380.       {
  1381.          fixedY -= sourceheight - 1;
  1382.          if (fixedY < 0)
  1383.          {
  1384.             fixedY = 0;
  1385.          }
  1386.       }
  1387.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1388.       {
  1389.          fixedY = 0;
  1390.       }
  1391.       else if (fixedY)
  1392.       {
  1393.          fixedY--;
  1394.       }
  1395.       break;
  1396.     // down
  1397.     case 77:
  1398.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1399.       {
  1400.          fixedY += sourceheight - 1;
  1401.          if (fixedY > (scr->Height - 1))
  1402.          {
  1403.             fixedY = scr->Height - 1;
  1404.          }
  1405.       }
  1406.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1407.       {
  1408.          fixedY = scr->Height - 1;
  1409.       }
  1410.       else if (fixedY < (scr->Height - 1))
  1411.       {
  1412.          fixedY++;
  1413.       }
  1414.       break;
  1415.     // right
  1416.     case 78:
  1417.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1418.       {
  1419.          fixedX += sourcewidth - 1;
  1420.          if (fixedX > (scr->Width - 1))
  1421.          {
  1422.             fixedX = scr->Width - 1;
  1423.          }
  1424.       }
  1425.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1426.       {
  1427.          fixedX = scr->Width - 1;
  1428.       }
  1429.       else if (fixedX < (scr->Width - 1))
  1430.       {
  1431.          fixedX++;
  1432.       }
  1433.       break;
  1434.     // left
  1435.     case 79:
  1436.       if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1437.       {
  1438.          fixedX -= sourcewidth - 1;
  1439.          if (fixedX < 0)
  1440.          {
  1441.             fixedX = 0;
  1442.          }
  1443.       }
  1444.       else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1445.       {
  1446.          fixedX = 0;
  1447.       }
  1448.       else if (fixedX)
  1449.       {
  1450.          fixedX--;
  1451.       }
  1452.       break;
  1453.    }
  1454. }
  1455.  
  1456. void processmsg ()
  1457. {
  1458.  struct IntuiMessage *intuimsg = NULL, m;
  1459.  CxMsg *msg;
  1460.  BOOL cont = TRUE, fixedmove = FALSE, app_clicked = FALSE;
  1461.  LONG sigmask, msgid, msgtype;;
  1462.  ULONG lock;
  1463.  
  1464.    waitmask |= (1 << timesig) | (1 << showhidesig) | cxsigflag | SIGBREAKF_CTRL_C;
  1465.    while (cont)
  1466.    {
  1467.       sigmask = Wait (waitmask);
  1468.       if (sigmask & cxsigflag)
  1469.       {
  1470.          while ((msg = (CxMsg *) GetMsg (broker_mp)) != 0)
  1471.          {
  1472.             msgid = CxMsgID (msg);
  1473.             msgtype = CxMsgType (msg);
  1474.             ReplyMsg ((struct Message *) msg);
  1475.             switch (msgtype)
  1476.             {
  1477.              case CXM_COMMAND:
  1478.                switch (msgid)
  1479.                {
  1480.                 case CXCMD_APPEAR:
  1481.                   showwindow ();
  1482.                   break;
  1483.                 case CXCMD_DISAPPEAR:
  1484.                   hidewindow ();
  1485.                   break;
  1486.                 case CXCMD_DISABLE:
  1487.                   ActivateCxObj (broker, 0);
  1488.                   enable = FALSE;
  1489.                   setmenu ();
  1490.                   break;
  1491.                 case CXCMD_ENABLE:
  1492.                   ActivateCxObj (broker, 1);
  1493.                   enable = TRUE;
  1494.                   setmenu ();
  1495.                   break;
  1496.                 case CXCMD_UNIQUE:
  1497.                   showwindow ();
  1498.                   break;
  1499.                 case CXCMD_KILL:
  1500.                   cont = FALSE;
  1501.                   break;
  1502.                }
  1503.             }
  1504.          }  // while ((msg
  1505.       }
  1506.       if (userport)
  1507.       {
  1508.          if (sigmask & (1 << userport->mp_SigBit))
  1509.          {
  1510.             jump = FALSE;
  1511.             while ((intuimsg = (struct IntuiMessage *) GetMsg (userport)) != 0)
  1512.             {
  1513.                CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
  1514.                ReplyMsg ((struct Message *) intuimsg);
  1515.                switch (m.Class)
  1516.                {
  1517.                 case IDCMP_CLOSEWINDOW:
  1518.                   if (hideonclose)
  1519.                   {
  1520.                      hidewindow ();
  1521.                   }
  1522.                   else
  1523.                   {
  1524.                      cont = FALSE;
  1525.                   }
  1526.                   break;
  1527.                 case IDCMP_NEWSIZE:
  1528.                   allocbm ();
  1529.                   break;
  1530.                 case IDCMP_IDCMPUPDATE:
  1531.                   ULONG h;
  1532.                   GetAttr (PGA_Top, propgadget, &h);
  1533.                   if (++h != scalefac)
  1534.                   {
  1535.                      scalefac = h;
  1536.                      allocbm ();
  1537.                      setwintitle ();
  1538.                      setmenu ();
  1539.                   }
  1540.                   break;
  1541.                 case IDCMP_MENUPICK:
  1542.                   cont = menupick (m.Code);
  1543.                   break;
  1544.                 case IDCMP_ACTIVEWINDOW:
  1545.                   SetAPen (winrp, pens[0]);
  1546.                   SetBPen (winrp, pens[1]);
  1547.                   printcoords (oldx, oldy);
  1548.                   printrgb (oldx, oldy);
  1549.                   ClearMenuStrip (mywin);
  1550.                   freescreenmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  1551.                   makescreenmenu ();
  1552.                   SetMenuStrip (mywin, menu);
  1553.                   break;
  1554.                 case IDCMP_INACTIVEWINDOW:
  1555.                   SetAPen (winrp, pens[2]);
  1556.                   SetBPen (winrp, pens[3]);
  1557.                   printcoords (oldx, oldy);
  1558.                   printrgb (oldx, oldy);
  1559.                   break;
  1560.                 case IDCMP_MOUSEBUTTONS:
  1561.                   if (fixed)
  1562.                   {
  1563.                      if (m.Code == SELECTDOWN)
  1564.                      {
  1565.                         fixedmove = TRUE;
  1566.                      }
  1567.                      else
  1568.                      {
  1569.                         fixedmove = FALSE;
  1570.                      }
  1571.                   }
  1572.                   break;
  1573.                 case IDCMP_MOUSEMOVE:
  1574.                   if (fixedmove)
  1575.                   {
  1576.                      fixedX = scr->MouseX;
  1577.                      fixedY = scr->MouseY;
  1578.                   }
  1579.                   break;
  1580.                 case IDCMP_VANILLAKEY:
  1581.                   cont = vanillakey (m.Code);
  1582.                   break;
  1583.                 case IDCMP_RAWKEY:
  1584.                   rawkey (m.Code, m.Qualifier);
  1585.                   break;
  1586.                 case IDCMP_REFRESHWINDOW:
  1587.                   refresh ();
  1588.                   break;
  1589.                }
  1590.                if (jump)
  1591.                {
  1592.                   break;
  1593.                }
  1594.             }  // while (intuimsg
  1595.          }
  1596.       }  // if (userport)
  1597.       if (app_mp)
  1598.       {
  1599.          if (sigmask & (1 << app_mp->mp_SigBit))
  1600.          {
  1601.             app_clicked = FALSE;
  1602.             while ((appmsg = (struct AppMessage *) GetMsg (app_mp)) != 0)
  1603.             {
  1604.                ReplyMsg ((struct Message *) appmsg);
  1605.                app_clicked = TRUE;
  1606.             }
  1607.             if (app_clicked)
  1608.             {
  1609.                showwindow ();
  1610.             }
  1611.          }
  1612.       }
  1613.       if ((sigmask & (1 << showhidesig)) && cont)
  1614.       {
  1615.          if (mywin)
  1616.          {
  1617.             hidewindow ();
  1618.          }
  1619.          else
  1620.          {
  1621.             showwindow ();
  1622.          }
  1623.       }
  1624.       if ((sigmask & (1 << timesig)) && cont)
  1625.       {
  1626.          if (mywin)
  1627.          {
  1628.             // refresh only if we living on the active screen
  1629.             lock = LockIBase (0);
  1630.             tmpscr = IntuitionBase->ActiveScreen;
  1631.             UnlockIBase (lock);
  1632.             if (scr == tmpscr)
  1633.             {
  1634.                refresh ();
  1635.             }
  1636.             else if (jumptoactivescreen)
  1637.             {
  1638.                setupscreen (tmpscr);
  1639.                screentofront = FALSE;
  1640.                reopenwin ();
  1641.             }
  1642.          }
  1643.       }
  1644.       if (sigmask & SIGBREAKF_CTRL_C)
  1645.       {
  1646.          cont = FALSE;
  1647.       }
  1648.    }  // while (cont)
  1649. }
  1650.  
  1651. //- iff save -----------------------------------
  1652.  
  1653. BOOL openfilereq ()
  1654. {
  1655.  APTR request;
  1656.  
  1657.    request = AllocAslRequestTags (ASL_FileRequest,
  1658.     ASLFR_InitialHeight, scr->Height / 2,
  1659.     ASLFR_Screen, scr,
  1660.     ASLFR_SleepWindow, TRUE,
  1661.     ASLFR_Window, mywin,
  1662.     ASLFR_TitleText, GetString (TXT_SAVEIFF),
  1663.     ASLFR_InitialDrawer, iffpath,
  1664.     ASLFR_InitialFile, iffname,
  1665.     ASLFR_DoSaveMode, TRUE,
  1666.     ASLFR_RejectIcons, TRUE,
  1667.     ASLFR_Screen, OpenWorkBench (),
  1668.     TAG_DONE);
  1669.    if (request)
  1670.    {
  1671.       if (AslRequest (request, NULL))
  1672.       {
  1673.          strncpy (iffpath, ((struct FileRequester *) request)->fr_Drawer, 255);
  1674.          strncpy (iffname, ((struct FileRequester *) request)->fr_File, 108);
  1675.          FreeAslRequest (request);
  1676.          return TRUE;
  1677.       }
  1678.    }
  1679.    return FALSE;
  1680. }
  1681.  
  1682. void write (register __d4 APTR buffer, register __d5 LONG size)
  1683. {
  1684.    if (Write (fh, buffer, size) != size)
  1685.    {
  1686.       throw (1);
  1687.    }
  1688. }
  1689.  
  1690. ULONG compressline (register __a3 UBYTE *src, register __a4 UBYTE *dest, ULONG size)
  1691. {
  1692.  register UBYTE x, y, *tmp, *deststart;
  1693.    
  1694.    deststart = dest;
  1695.    while (size > 1)
  1696.    {
  1697.       x = 0;
  1698.       y = *src++;
  1699.       if (y == *src)
  1700.       {
  1701.          size--;
  1702.          while (size && (x < 127) && (*src == y))
  1703.          {
  1704.             size--;
  1705.             x++;
  1706.             src++;
  1707.          }
  1708.          *dest++ = -x;
  1709.          *dest++ = y;
  1710.       }
  1711.       else
  1712.       {
  1713.          tmp = dest++;
  1714.          while (size && (x < 128) && (*src != y))
  1715.          {
  1716.             size--;
  1717.             x++;
  1718.             *dest++ = y;
  1719.             y = *src++;
  1720.          }
  1721.          *tmp = x - 1;
  1722.          src--;
  1723.       }
  1724.    }
  1725.    if (size)
  1726.    {
  1727.       *dest++ = 0;
  1728.       *dest++ = *src;
  1729.    }
  1730.    return dest - deststart;
  1731. }
  1732.  
  1733. void savetruecolor ()
  1734. {
  1735.  UWORD bpr = ((innerwidth >> 3) + 2) & 0xfffe, byteoff, i, j;
  1736.  UBYTE *mem, *mem2, *offset, r, g, b;
  1737.  ULONG packlen;
  1738.  register UWORD x, y;
  1739.  struct BitMap *bm = NULL;
  1740.  BOOL ownbitmap = FALSE;
  1741.  
  1742.    if (GetBitMapAttr (destbm, BMA_FLAGS) & PIXFMT_RGB24)
  1743.    {
  1744.       bm = destbm;
  1745.    }
  1746.    else
  1747.    {
  1748.       bm = AllocBitMap (innerwidth, innerheight, 24, BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24, 0);
  1749.       if (!bm)
  1750.       {
  1751.          error (GetString (TXT_ERROR_ALLOCBITMAPSAVE));
  1752.          throw (1);
  1753.       }
  1754.       ownbitmap = TRUE;
  1755.       BltBitMap (destbm, 0, 0, bm, 0, 0, innerwidth, innerheight, ABNC | ABC, ~0, NULL);
  1756.    }
  1757.    mem = (UBYTE *) AllocVec (bpr * 24, 0);
  1758.    if (!mem)
  1759.    {
  1760.       throw (2);
  1761.    }
  1762.    mem2 = (UBYTE *) AllocVec (bpr << 1, 0);
  1763.    if (!mem2)
  1764.    {
  1765.       throw (3);
  1766.    }
  1767.    for (i = 0; i < destbm->Rows; i++)
  1768.    {
  1769.       memset (mem, 0, bpr * 24);
  1770.       offset = bm->Planes[0] + i * bpr * 24;
  1771.       for (j = 0, y = 7; j < (bpr * 24); j++, y--)
  1772.       {
  1773.          r = *(offset + j++);
  1774.          g = *(offset + j++);
  1775.          b = *(offset + j);
  1776.          if (y > 7) y = 7;
  1777.          byteoff = j / 24;
  1778.          for (x = 0; x < 8; x++)
  1779.          {
  1780.             mem[x*bpr+byteoff] |= ((r >> x) & 1u) << y;
  1781.             mem[(x+8)*bpr+byteoff] |= ((g >> x) & 1u) << y;
  1782.             mem[(x+16)*bpr+byteoff] |= ((b >> x) & 1u) << y;
  1783.          }
  1784.       }
  1785.       for (j = 0; j < (bpr * 24); j += bpr)
  1786.       {
  1787.          packlen = compressline (&mem[j], mem2, bpr);
  1788.          write (mem2, packlen);
  1789.       }
  1790.       RectFill (winrp, leftoff, i + topoff, innerwidth + leftoff - 1, i + topoff);
  1791.    }
  1792.    FreeVec (mem);
  1793.    FreeVec (mem2);
  1794.    if (ownbitmap && bm)
  1795.    {
  1796.       FreeBitMap (bm);
  1797.    }
  1798. }
  1799.  
  1800. void saveiff ()
  1801. {
  1802.  ULONG len, bodylen, packlen, vpmodeid, colors[3];;
  1803.  UWORD i, j, depth;
  1804.  UBYTE cmap[3], *mem;
  1805.  struct BitMapHeader bh;
  1806.  struct DisplayInfo di;
  1807.  char header[] = "FORM....ILBMANNO";
  1808.  char anno[] = "Written by " VERSION "\0";
  1809.  
  1810.    try
  1811.    {
  1812.       // save header
  1813.       depth = GetBitMapAttr (destbm, BMA_DEPTH);
  1814.       write (header, strlen (header));
  1815.       len = (strlen (anno) + 2) & 0xfe;
  1816.       write (&len, 4);
  1817.       write (anno, len);
  1818.       write ("BMHD", 4);
  1819.       len = sizeof (struct BitMapHeader);
  1820.       write (&len, 4);
  1821.       bh.bmh_Width = innerwidth;
  1822.       bh.bmh_Height = innerheight;
  1823.       bh.bmh_Left = bh.bmh_Top = 0;
  1824.       bh.bmh_Depth = cybergfxscreen ? 24 : depth;
  1825.       bh.bmh_Masking = 0;
  1826.       bh.bmh_Compression = 1;
  1827.       bh.bmh_Pad = 0;
  1828.       bh.bmh_Transparent = 0;
  1829.       vpmodeid = GetVPModeID (&scr->ViewPort);
  1830.       if (GetDisplayInfoData (NULL, (UBYTE *) &di, sizeof (struct DisplayInfo), DTAG_DISP, vpmodeid))
  1831.       {
  1832.          bh.bmh_XAspect = di.Resolution.x;
  1833.          bh.bmh_YAspect = di.Resolution.y;
  1834.       }
  1835.       else
  1836.       {
  1837.          bh.bmh_XAspect = bh.bmh_YAspect = 0;
  1838.       }
  1839.       bh.bmh_PageWidth = innerwidth;
  1840.       bh.bmh_PageHeight = innerheight;
  1841.       write (&bh, len);
  1842.       write ("CAMG", 4);
  1843.       len = 4;
  1844.       write (&len, 4);
  1845.       write (&vpmodeid, 4);
  1846.       // no "CMAP" in true color
  1847.       if (!cybergfxscreen)
  1848.       {
  1849.          write ("CMAP", 4);
  1850.          len = 3 * (1 << depth);
  1851.          write (&len, 4);
  1852.          for (i = 0; i < (1 << depth); i++)
  1853.          {
  1854.             GetRGB32 (scr->ViewPort.ColorMap, i, 1, colors);
  1855.             cmap[0] = colors[0] & 0xff;
  1856.             cmap[1] = colors[1] & 0xff;
  1857.             cmap[2] = colors[2] & 0xff;
  1858.             write (cmap, 3);
  1859.          }
  1860.       }
  1861.       write ("BODY....", 8);
  1862.       bodylen = Seek (fh, 0, OFFSET_CURRENT) - 4;
  1863.       
  1864.       if (cybergfxscreen)
  1865.       {
  1866.          savetruecolor ();
  1867.       }
  1868.       else
  1869.       {
  1870.          mem = (UBYTE *) AllocVec (destbm->BytesPerRow << 1, 0);
  1871.          if (mem)
  1872.          {
  1873.             if (GetBitMapAttr (destbm, BMA_FLAGS) & BMF_INTERLEAVED)
  1874.             {
  1875.                // interleaved
  1876.                for (i = 0, len = 0; i < (destbm->Rows * depth); i++, len += destbm->BytesPerRow / depth)
  1877.                {
  1878.                   packlen = compressline (destbm->Planes[0] + len, mem, destbm->BytesPerRow / depth);
  1879.                   write (mem, packlen);
  1880.                   if (!(i % depth))
  1881.                   {
  1882.                      RectFill (winrp, leftoff, i / depth + topoff, innerwidth + leftoff - 1, i / depth + topoff);
  1883.                   }
  1884.                }
  1885.             }
  1886.             else
  1887.             {
  1888.                len = 0;
  1889.                for (i = 0; i < destbm->Rows; i++)
  1890.                {
  1891.                   for (j = 0; j < depth; j++)
  1892.                   {
  1893.                      packlen = compressline (destbm->Planes[j] + len, mem, destbm->BytesPerRow);
  1894.                      write (mem, packlen);
  1895.                   }
  1896.                   len += destbm->BytesPerRow;
  1897.                   RectFill (winrp, leftoff, i + topoff, innerwidth + leftoff - 1, i + topoff);
  1898.                }
  1899.             }
  1900.             FreeVec (mem);
  1901.          }
  1902.          else
  1903.          {
  1904.             throw (3);
  1905.          }
  1906.       }  // if (cybergfxscreen)
  1907.       if (Seek (fh, 0, OFFSET_CURRENT) & 1)
  1908.       {
  1909.          *cmap = 0x80;
  1910.          write (cmap, 1);
  1911.       }
  1912.       len = Seek (fh, 4, OFFSET_BEGINNING) - 8;
  1913.       write (&len, 4);
  1914.       Seek (fh, bodylen, OFFSET_BEGINNING);
  1915.       len = len - bodylen + 4;
  1916.       write (&len, 4);
  1917.    }
  1918.    catch (int) { }
  1919. }
  1920.  
  1921. //- menu ---------------------------------------
  1922.  
  1923. BOOL fixedFunc ()
  1924. {
  1925.    if (!fixed && (item->Flags & CHECKED))
  1926.    {
  1927.       fixed = TRUE;
  1928.       fixedX = scr->MouseX;
  1929.       fixedY = scr->MouseY;
  1930.    }
  1931.    else if (fixed && !(item->Flags & CHECKED))
  1932.    {
  1933.       fixed = FALSE;
  1934.    }
  1935.    return TRUE;
  1936. }
  1937.  
  1938. BOOL fastFunc ()
  1939. {
  1940.    fast = (item->Flags & CHECKED) != 0;
  1941.    return TRUE;
  1942. }
  1943.  
  1944. BOOL crosshairFunc ()
  1945. {
  1946.    crosshair = (item->Flags & CHECKED) != 0;
  1947.    return TRUE;
  1948. }
  1949.  
  1950. BOOL AboutFunc ()
  1951. {
  1952.  static struct EasyStruct es_about = {
  1953.    20, 0,
  1954.    "Lupe",
  1955.    "%s%s%s%s",
  1956.    "%s"
  1957.  };
  1958.  
  1959.  char *era_about[] = {
  1960.    VERSION " (" __DATE__ ")\n\n",
  1961.    GetString (TXT_ABOUT_WRITTENBY),
  1962.    "\n"
  1963.    "  Frank Toepper\n"
  1964.    "  Maxim Gorki Straße 5A\n"
  1965.    "  Greifswald\n"
  1966.    "  17491\n"
  1967.    "  GERMANY\n\n"
  1968.    "E-Mail:\n"
  1969.    "  toepper@rz.uni-greifswald.de\n"
  1970.    "WWW:\n"
  1971.    "  http://www.user.fh-stralsund.de/~rwermke/di.html\n\n",
  1972.    GetString (TXT_ABOUT_PD),
  1973.    "Ok"
  1974.  };
  1975.  
  1976.    EasyRequestArgs (NULL, &es_about, NULL, era_about);
  1977.    return TRUE;
  1978. }
  1979.  
  1980. BOOL jumpFunc ()
  1981. {
  1982.    if (setupscreen (NULL) == NEWSCREEN)
  1983.    {
  1984.       reopenwin ();
  1985.    }
  1986.    return TRUE;
  1987. }
  1988.  
  1989. BOOL jumptoactiveFunc ()
  1990. {
  1991.    jumptoactivescreen = (item->Flags & CHECKED) != 0;
  1992.    return TRUE;
  1993. }
  1994.  
  1995. BOOL saveFunc ()
  1996. {
  1997.  BPTR dirlock, olddirlock;
  1998.  ULONG reg;
  1999.  
  2000.    if (scalefac == 1)
  2001.    {
  2002.     LONG x = oldx, y = oldy;
  2003.       if (!(destbm = AllocBitMap (innerwidth, innerheight, cybergfxscreen ? 24 : scrdepth, cybergfxscreen ? (BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24) : BMF_CLEAR, 0)))
  2004.       {
  2005.          error (GetString (TXT_ERROR_ALLOCBITMAPSAVE));
  2006.          return TRUE;
  2007.       }
  2008.       adjustX (x);
  2009.       adjustY (y);
  2010.       BltBitMap (scrbm, x, y, destbm, 0, 0, innerwidth, innerheight, ABNC | ABC, ~0, NULL);
  2011.    }
  2012.    if (openfilereq ())
  2013.    {
  2014.       BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  2015.       dirlock = Lock (iffpath, SHARED_LOCK);
  2016.       if (dirlock)
  2017.       {
  2018.          olddirlock = CurrentDir (dirlock);
  2019.          fh = Open (iffname, MODE_NEWFILE);
  2020.          if (fh)
  2021.          {
  2022.             mywin->Flags &= ~SIZEGADGET;
  2023.             reg = GetAPen (winrp);
  2024.             SetAPen (winrp, 0);
  2025.             saveiff ();
  2026.             Close (fh);
  2027.             BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  2028.             SetAPen (winrp, reg);
  2029.             mywin->Flags |= SIZEGADGET;
  2030.          }
  2031.          else
  2032.          {
  2033.             error (GetString (TXT_ERROR_CREATE), iffname);
  2034.          }
  2035.          CurrentDir (olddirlock);
  2036.          UnLock (dirlock);
  2037.       }
  2038.       else
  2039.       {
  2040.          error (GetString (TXT_ERROR_LOCK), iffpath);
  2041.       }
  2042.    }
  2043.    if ((scalefac == 1) && destbm)
  2044.    {
  2045.       FreeBitMap (destbm);
  2046.       destbm = NULL;
  2047.    }
  2048.    return TRUE;
  2049. }
  2050.  
  2051. BOOL coordsFunc ()
  2052. {
  2053.    if (!coords && (item->Flags & CHECKED))
  2054.    {
  2055.       coords = TRUE;
  2056.    }
  2057.    else if (coords && !(item->Flags & CHECKED))
  2058.    {
  2059.       coords = FALSE;
  2060.    }
  2061.    else
  2062.    {
  2063.       return TRUE;  // nothing changed
  2064.    }
  2065.    reopenwin ();
  2066.    return TRUE;
  2067. }
  2068.  
  2069. BOOL gridFunc ()
  2070. {
  2071.    grid = (item->Flags & CHECKED) != 0;
  2072.    setupgrid ();
  2073.    return TRUE;
  2074. }
  2075.  
  2076. BOOL showrgbFunc ()
  2077. {
  2078.    if (!showrgb && (item->Flags & CHECKED))
  2079.    {
  2080.       showrgb = TRUE;
  2081.    }
  2082.    else if (showrgb && !(item->Flags & CHECKED))
  2083.    {
  2084.       showrgb = FALSE;
  2085.    }
  2086.    else
  2087.    {
  2088.       return TRUE;  // nothing changed
  2089.    }
  2090.    reopenwin ();
  2091.    return TRUE;
  2092. }
  2093.  
  2094. BOOL enableFunc ()
  2095. {
  2096.    if (item->Flags & CHECKED)
  2097.    {
  2098.       ActivateCxObj (broker, 1);
  2099.       enable = TRUE;
  2100.    }
  2101.    else if (!(item->Flags & CHECKED))
  2102.    {
  2103.       ActivateCxObj (broker, 0);
  2104.       enable = FALSE;
  2105.    }
  2106.    return TRUE;
  2107. }
  2108.  
  2109. BOOL hideoncloseFunc ()
  2110. {
  2111.    hideonclose = (item->Flags & CHECKED) != 0;
  2112.    return TRUE;
  2113. }
  2114.  
  2115. BOOL hideFunc ()
  2116. {
  2117.    hidewindow ();
  2118.    jump = TRUE;
  2119.    return TRUE;
  2120. }
  2121.  
  2122. BOOL QuitFunc ()
  2123. {
  2124.    return FALSE;
  2125. }
  2126.  
  2127. //- args ---------------------------------------
  2128.  
  2129. BOOL argbool (char **argv, char *name, BOOL def)
  2130. {
  2131.  char *value;
  2132.  
  2133.    value = (char *) FindToolType ((UBYTE **) argv, name);
  2134.    if (value)
  2135.    {
  2136.       if (MatchToolValue (value, "YES") || MatchToolValue (value, "ON")) return TRUE;
  2137.       if (MatchToolValue (value, "OFF") || MatchToolValue (value, "NO")) return FALSE;
  2138.    }
  2139.    return def;
  2140. }
  2141.  
  2142. LONG argint (char **argv, UBYTE *name, LONG def)
  2143. {
  2144.  LONG returnvalue;
  2145.  APTR value;
  2146.  
  2147.    value = FindToolType ((UBYTE **) argv, name);
  2148.    if (value)
  2149.    {
  2150.       if (StrToLong ((UBYTE *) value, &returnvalue))
  2151.       {
  2152.          return returnvalue;
  2153.       }
  2154.    }
  2155.    return def;
  2156. }
  2157.  
  2158. void argstring (char *result, char **argv, char *name, size_t size = 49)
  2159. {
  2160.  char *value;
  2161.  
  2162.    value = FindToolType ((UBYTE **) argv, name);
  2163.    if (value)
  2164.    {
  2165.       strncpy (result, value, size);
  2166.    }
  2167. }
  2168.  
  2169. void readargs ()
  2170. {
  2171.  // first time always the tooltypes will be evaluated
  2172.  // if we started from Cli the tooltypes can be overloaded
  2173.  char **argv;
  2174.  struct DiskObject *programicon;
  2175.  struct RDArgs * rdargs;
  2176.  struct DrawInfo *drawinfo;
  2177.  LONG a[21];
  2178.  long *args = a;
  2179.  
  2180.    wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
  2181.    // make the window as square as possible
  2182.    drawinfo = GetScreenDrawInfo (scr);
  2183.    if (drawinfo)
  2184.    {
  2185.       innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
  2186.       FreeScreenDrawInfo (scr, drawinfo);
  2187.    }
  2188.    if (Cli ())
  2189.    {
  2190.       GetProgramName (programname, 108);
  2191.    }
  2192.    else
  2193.    {
  2194.       strcpy (programname, thistask->tc_Node.ln_Name);
  2195.    }
  2196.    IconBase = OpenLibrary ("icon.library", 37);
  2197.    if (IconBase)
  2198.    {
  2199.       programicon = GetDiskObject (programname);
  2200.       if (programicon)
  2201.       {
  2202.          argv = programicon->do_ToolTypes;
  2203.          newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
  2204.          fast = argbool (argv, "Fast", fast);
  2205.          maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
  2206.          scalefac = argint (argv, "ScaleFactor", scalefac);
  2207.          winleft = argint (argv, "WinLeft", winleft);
  2208.          wintop = argint (argv, "WinTop", wintop);
  2209.          innerheight = argint (argv, "WinHeight", innerheight);
  2210.          innerwidth = argint (argv, "WinWidth", innerwidth);
  2211.          coords = argbool (argv, "Coordinates", coords);
  2212.          crosshair = argbool (argv, "Crosshair", crosshair);
  2213.          argstring (setoriginkey, argv, "SetOriginKey");
  2214.          argstring (resetoriginkey, argv, "ResetOriginKey");
  2215.          fixed = argbool (argv, "Fixed", fixed);
  2216.          argstring (showhidekey, argv, "ShowHideKey");
  2217.          hide = argbool (argv, "Iconify", hide);
  2218.          hideonclose = argbool (argv, "IconifyOnClose", hideonclose);
  2219.          grid = argbool (argv, "Grid", grid);
  2220.          showrgb = argbool (argv, "ShowRGB", showrgb);
  2221.          argstring (iffpath, argv, "IFFFile", 255);
  2222.          jumptoactivescreen = argbool (argv, "JumpToActiveScreen", jumptoactivescreen);
  2223.          argstring (language, argv, "LANGUAGE", 20);
  2224.          FreeDiskObject (programicon);
  2225.       }
  2226.       CloseLibrary (IconBase);
  2227.    }
  2228.    if (Cli ())
  2229.    {
  2230.       memset (args, '\0', 21 * sizeof (LONG));
  2231.       args[1] = fast;
  2232.       args[8] = coords;
  2233.       args[9] = crosshair;
  2234.       args[12] = fixed;
  2235.       args[14] = hide;
  2236.       args[15] = hideonclose;
  2237.       args[16] = grid;
  2238.       args[17] = showrgb;
  2239.       args[19] = jumptoactivescreen;
  2240.       rdargs = ReadArgs (Template, args, NULL);
  2241.       if (rdargs)
  2242.       {
  2243.          if (*args) newbroker.nb_Pri = *args;
  2244.          args++;
  2245.          fast = *args++;
  2246.          if (*args) maxscalefac = *(LONG *) *args;
  2247.          if (*++args) scalefac = *(LONG *) *args;
  2248.          if (*++args) winleft = *(LONG *) *args;
  2249.          if (*++args) wintop = *(LONG *) *args;
  2250.          if (*++args) innerwidth = *(LONG *) *args;
  2251.          if (*++args) innerheight = *(LONG *) *args;
  2252.          args++;
  2253.          coords = *args++;
  2254.          crosshair = *args++;
  2255.          if (*args) strncpy (setoriginkey, (char *) *args, 49);
  2256.          if (*++args) strncpy (resetoriginkey, (char *) *args, 49);
  2257.          args++;
  2258.          fixed = *args++;
  2259.          if (*args) strncpy (showhidekey, (char *) *args, 49);
  2260.          args++;
  2261.          hide = *args++;
  2262.          hideonclose = *args++;
  2263.          grid = *args++;
  2264.          showrgb = *args++;
  2265.          if (*args) strncpy (iffpath, (char *) *args, 255);
  2266.          args++;
  2267.          jumptoactivescreen = *args++ != 0;
  2268.          if (*args) strncpy (language, (char *) *args, 19);
  2269.          FreeArgs (rdargs);
  2270.       }
  2271.    }
  2272.    if (maxscalefac < 5) maxscalefac = 5;
  2273.    // not lower than innerheight or innerwidth
  2274.    // otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
  2275.    // can go to 0 -> 'AllocBitMap ()' failed
  2276.    if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
  2277.    if (scalefac > maxscalefac) scalefac = maxscalefac;
  2278.    if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
  2279.    if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
  2280.    
  2281.    char *str;
  2282.    str = strrchr (iffpath, '/');
  2283.    if (str)
  2284.    {
  2285.       strncpy (iffname, str + 1, 108);
  2286.       *str = '\0';
  2287.    }
  2288.    else if ((str = strrchr (iffpath, ':')) != 0)
  2289.    {
  2290.       strncpy (iffname, ++str, 108);
  2291.       *str = '\0';
  2292.    }
  2293.    else
  2294.    {
  2295.       strncpy (iffname, iffpath, 108);
  2296.       iffpath[0] = '\0';
  2297.    }
  2298. }
  2299.  
  2300. //- main ---------------------------------------
  2301.  
  2302. struct Library *openlib (char *libname, ULONG ver)
  2303. {
  2304.  struct Library *lib;
  2305.    
  2306.    lib = OpenLibrary (libname, ver);
  2307.    if (!lib)
  2308.    {
  2309.       error (GetString (TXT_ERROR_LIBRARY), libname, ver);
  2310.       throw (1);
  2311.    }
  2312.    return lib;
  2313. }
  2314.  
  2315. void main ()
  2316. {
  2317.    try
  2318.    {
  2319.       CxBase = openlib ("commodities.library", 37);
  2320.       GfxBase = (struct GfxBase *) openlib ("graphics.library", 39);
  2321.       GadToolsBase = openlib ("gadtools.library", 37);
  2322.       WorkbenchBase = openlib ("workbench.library", 37);
  2323.       AslBase = openlib ("asl.library", 37);
  2324.       UtilityBase = openlib ("utility.library", 37);
  2325.       CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
  2326.       LocaleBase = OpenLibrary ("locale.library", 38);
  2327.       InitRastPort (&destrp);
  2328.       SetAPen (&destrp, 0);
  2329.       InitRastPort (&maskrp);
  2330.       SetDrMd (&maskrp, COMPLEMENT);
  2331.       thistask = FindTask (NULL);
  2332.       if ((topazfont = OpenFont (&topaz_attr)) != 0)
  2333.       {
  2334.          try
  2335.          {
  2336.             setupscreen (NULL);  // needed before readargs ()
  2337.             readargs ();
  2338.             OpenlupeCatalog (0, language[0] ? language : 0);
  2339.             getoffsets ();
  2340.             if (hide)
  2341.             {
  2342.                hidewindow ();
  2343.             }
  2344.             else
  2345.             {
  2346.                openwin ();
  2347.                allocbm ();
  2348.             }
  2349.             if ((timesig = AllocSignal (-1L)) != -1)
  2350.             {
  2351.                if ((showhidesig = AllocSignal (-1L)) != -1)
  2352.                {
  2353.                   try
  2354.                   {
  2355.                      initbroker ();
  2356.                      processmsg ();
  2357.                   }
  2358.                   catch (int) { };
  2359.                   if (broker)
  2360.                   {
  2361.                      DeleteCxObjAll (broker);
  2362.                      broker = NULL;
  2363.                   }
  2364.                   if (broker_mp)
  2365.                   {
  2366.                      DeleteMsgPort (broker_mp);
  2367.                      broker_mp = NULL;
  2368.                   }
  2369.                   FreeSignal (showhidesig);
  2370.                }
  2371.                else
  2372.                {
  2373.                   error (GetString (TXT_ERROR_SIGNAL));
  2374.                }
  2375.                FreeSignal (timesig);
  2376.             }
  2377.             else
  2378.             {
  2379.                error (GetString (TXT_ERROR_SIGNAL));
  2380.             }
  2381.          }  // try
  2382.          catch (int) { }
  2383.          closewin ();
  2384.          CloseDownScreen ();
  2385.          freeappicon ();
  2386.          CloseFont (topazfont);
  2387.          if (screenfont)
  2388.          {
  2389.             CloseFont (screenfont);
  2390.          }
  2391.       }
  2392.       else
  2393.       {
  2394.          error (GetString (TXT_ERROR_FONT));
  2395.       }
  2396.       CloselupeCatalog ();
  2397.       if (LocaleBase)
  2398.       {
  2399.          CloseLibrary (LocaleBase);
  2400.       }
  2401.       if (CyberGfxBase)
  2402.       {
  2403.          CloseLibrary (CyberGfxBase);
  2404.       }
  2405.       CloseLibrary (UtilityBase);
  2406.       CloseLibrary (AslBase);
  2407.       CloseLibrary (WorkbenchBase);
  2408.       CloseLibrary (GadToolsBase);
  2409.       CloseLibrary ((struct Library *) GfxBase);
  2410.       CloseLibrary (CxBase);
  2411.    }
  2412.    catch (int) { }
  2413. }
  2414.  
  2415.