home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 192.lha / Snip_v1.3 / snip.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  12KB  |  391 lines

  1.  
  2. /*
  3.  *  SNIP V1.3
  4.  *
  5.  *  Freely redistributable, donations not discouraged.
  6.  *  Bug reports, suggestions, feedback welcomed.
  7.  *
  8.  *  John    07-01-88
  9.  */
  10.  
  11. /*
  12.  *  John Russell
  13.  *  5 Alderdice Place
  14.  *  St. John's, Newfoundland
  15.  *  Canada  A1B 2P8
  16.  *  (709) 726-7847
  17.  *
  18.  *  john13@garfield.uucp    (...utai!garfield!john13)
  19.  *
  20.  */
  21.  
  22. /* this contains mostly the bitmaps for the characters of the topaz-8 font */
  23.  
  24. /* assign whatever directory snip is in to snip: */
  25.  
  26. /* you may need to add extra includes yourself, I use a precompiled */
  27. /* include file of common intuition/graphics files */
  28.  
  29. #include "snip:snip.h"
  30.  
  31. /* these are the defines I use for all modules */
  32. #include "snip:defs.h"
  33.  
  34. extern struct Window *WhichWindow();    /* find window under mouse */
  35. extern struct Screen *WhichScreen();    /* find screen under mouse */
  36. extern BOOL reactivate;
  37.  
  38. short save_format = PRINT_STDOUT;   /* default if you don't give "-p" or "-c" on command line */
  39.  
  40. /* these are concerned with storing the text in a rectangular block */
  41.  
  42. char *scratch = NULL;
  43. short scratchsize = 0;
  44. short scratchwidth, scratchheight;
  45.  
  46. /* these are concerned with making it possible to get text from any window */
  47.  
  48. short x_offset = 0, y_offset = 0;
  49.  
  50. struct NewWindow nwindow =
  51. {
  52.     50,0,372,10,
  53.     1,2,
  54.     VANILLAKEY | CLOSEWINDOW | MOUSEBUTTONS | INACTIVEWINDOW,
  55.     REPORTMOUSE | RMBTRAP | SMART_REFRESH | NOCAREREFRESH | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
  56.     NULL, NULL,
  57.     (UBYTE *)"SNIP V1.3 © 1988 John Russell",
  58.     NULL, NULL, -1, -1, -1, -1, WBENCHSCREEN
  59. };
  60.  
  61. /* using these snip can be detached from the CLI without run, by linking */
  62. /* with detach.o32 from Manx 3.6 */
  63.  
  64. long _stack         =   4000;
  65. long _priority      =   0;
  66. long _BackGroundIO  =   1;
  67. char *_procname     =   (char *)&(nwindow.Title);
  68.  
  69. char usage[] = "Usage: snip [options] ('run' not needed)\n\
  70. Options may be in any order. Possible options are:\n\
  71. -s  : Snipped text is written to standard output (default)\n\
  72. -p  : Snipped text is written to \"pipe:snip\"\n\
  73. -c  : Snipped text is written to the clipboard\n\
  74. -k  : Snipped text is typed into the next window to become active\n\
  75. -K  : Same as -k, except text is written as one line (no carriage returns)\n\
  76. -a  : Use with -k or -K. Snip window re-activates itself after pasting.\n\
  77. -o <name> : Standard output sent to name, eg PAR: or df0:text.\n\
  78. -f <name> : Use a different font. Filename should be the name of a font\n\
  79.             definition file created by SNIPGEN; the search path will be\n\
  80.             <name>.fontdef and s:<name>.fontdef.\n\
  81. on <name> : Open Snip window on screen called <name>. Use \"-null\" as name\n\
  82.             of unnamed screens (ie on -null).\n\
  83. x y : For non-console windows (eg the VT100 window), you specify an offset\n\
  84.       for SNIP to use in positioning its capture box. If one offset is\n\
  85.       specified then both must be even if the other one is just zero.\n\
  86. See documentation for help with interactive commands.\n\
  87. \t\t\tSNIP Copyright 1988 John Russell\n\
  88. ";
  89.  
  90. char plea[] = "Please use Kickstart/Workbench V1.2 for latest ";
  91.  
  92. /* to be able to safely abort, I need to declare these externally */
  93. /* ^C won't be trapped now, but I keep _abort() out of habit */
  94.  
  95. struct Window *w = NULL;        /* this is the one I open */
  96. struct Window *window;          /* this is an arbitrary window */
  97. struct FileHandle *fp = NULL;   /* for writing captured text to a file */
  98. BOOL layer_locked = FALSE;      /* so I'll always know if I control someone else's window */
  99. struct FileHandle *outfilehandle = NULL;
  100.  
  101. main(argc,argv)
  102. int argc;
  103. char *argv[];
  104. {
  105.     struct Screen *screen;
  106.     struct MsgPort *port;
  107.     register ULONG class, code;
  108.  
  109.     struct RastPort rp;                     /* <- Note actual structure, not pointer */
  110.     register struct RastPort *myrp = &rp;   /* saves some bytes & is faster */
  111.  
  112.     register struct IntuiMessage *msg;
  113.  
  114.     register struct FileHandle *out = Output();
  115.  
  116.     register short count, x, y;             /* I _always_ have variables called x & y. Does anyone else *hate* i & j for subscripts? */
  117.     short x1, y1, x2, y2;
  118.  
  119.     short tx1, tx2, ty1, ty2;   /* temps for reversing box corners if need be (unused at the moment) */
  120.  
  121.     register BOOL drawing = FALSE;
  122.     BOOL done = FALSE;
  123.  
  124.     if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33L)))
  125.     {
  126.         Wrlen(out,plea);
  127.         Wr(out,"Intuition.\n");
  128.         goto breakpoint;
  129.     }
  130.  
  131.     if (!(GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",33L)))
  132.     {
  133.         Wrlen(out,plea);
  134.         Wr(out,"Graphics.\n");
  135.         goto breakpoint;
  136.     }
  137.  
  138.     if (!(LayersBase=(struct LayersBase *) OpenLibrary("layers.library",33L)))
  139.     {
  140.         Wrlen(out,plea);
  141.         Wr(out,"Layers.\n");
  142.         goto breakpoint;
  143.     }
  144.  
  145.     if (!parse_args(argc,argv))
  146.         goto breakpoint;    /* error in command line */
  147.  
  148.     if (!initstuff())
  149.     {
  150.         Wr(out,"Error establishing keyboard IO\n");
  151.         goto breakpoint;
  152.     }
  153.  
  154.     if (!(w = OpenWindow(&nwindow)))
  155.     {
  156.         Wr(out,"Can't open window\n");
  157.         goto breakpoint;
  158.     }
  159.  
  160.     while (NOT done)
  161.     {
  162.         WaitPort(w->UserPort);
  163.  
  164.         while (msg = (struct IntuiMessage *)GetMsg(w->UserPort))
  165.         {
  166.             class = msg->Class;
  167.             code = msg->Code;
  168.             x = msg->MouseX;
  169.             y = msg->MouseY;
  170.  
  171.             ReplyMsg(msg);
  172.  
  173.             switch(class)
  174.             {
  175.                 case CLOSEWINDOW:
  176.                     done = TRUE;
  177.                     break;
  178.  
  179. /*
  180.  *  Here is the outline for the outline routine:
  181.  *      - clicking right mouse button sets (x1,y1) point (upper left of a
  182.  *        character) and outlines that character; it also seizes control
  183.  *        of the window layer we are interested in so it won't change yet
  184.  *      - moving mouse makes box erase and then redraw; as new characters
  185.  *        are covered they will be outlined
  186.  *      - releasing the right mouse button erases the box for a final time,
  187.  *        and causes the area within the rectangle to be "read" using the
  188.  *        character bitmap compare routines
  189.  *      - the final location of the rectangle endpoints may be reversed and
  190.  *        then tweaked a bit if the rubberbanding was not left->right, top->
  191.  *        bottom (not yet)
  192.  *
  193.  */
  194.  
  195.                 case MOUSEBUTTONS:
  196.                     switch(code)
  197.                     {
  198.                         case MENUDOWN:
  199.  
  200. /* what was mouse clicked upon? */
  201.  
  202.                             window = WhichWindow();
  203.  
  204.                             if (!window)
  205.                             {
  206.                                 Wr(out,"Please select a valid window.\n");
  207.                                 break;
  208.                             }
  209.  
  210. /* FREEZE, WINDOW! */
  211.  
  212. #ifndef NOLOCK
  213.                             LockLayerRom(window->WLayer);
  214. #endif
  215.                             layer_locked = TRUE;
  216.  
  217. /* make a copy of the rastport to bang on */
  218.                             CopyMem(window->RPort, myrp, sizeof(struct RastPort));
  219.  
  220.                             SetDrMd(myrp, COMPLEMENT);
  221.  
  222. /* figure out the exact pixels for box corners */
  223.                             compute_xy1(window, &x1, &y1);
  224.                             compute_xy2(window, &x2, &y2);
  225.                             drawing = TRUE;
  226.                             ModifyIDCMP(w, MOUSEMOVE | CLOSEWINDOW | MOUSEBUTTONS | INACTIVEWINDOW);
  227.                             do_box(myrp, x1, y1, x2, y2);
  228.                             break;
  229.  
  230.                         case MENUUP:
  231.                             if (drawing)
  232.                             {
  233.                                 drawing = FALSE;
  234.                                 ModifyIDCMP(w, CLOSEWINDOW | MOUSEBUTTONS | VANILLAKEY | INACTIVEWINDOW);
  235.                                 do_box(myrp, x1, y1, x2, y2);
  236.  
  237. /* for actually reading from the screen, x1,y1 must be above & left x2,y2 */
  238.  
  239.                                 if (    x1+4 >= x2 ||
  240.                                         y1+4 >= y2   )
  241.                                 {
  242.                                     free_window();
  243.                                     Wr(out,"Please drag down and to the left\n");
  244.                                     break;
  245.                                 }
  246.  
  247.                                 interpret(myrp, x1, y1, x2, y2);
  248.  
  249. /* "flash" the region to indicate we are finished */
  250.                                 for (x=0; x<2; x++)
  251.                                 {
  252.                                     RectFill(myrp, x1, y1, x2, y2);
  253.                                     Delay(10);
  254.                                 }
  255.  
  256. /* unlock layers */
  257.                                 free_window();
  258.  
  259. /* store the text in optional format */
  260. /* the stash routine will use all global variables */
  261.  
  262.                                 stash();
  263.  
  264.                                 FreeMem(scratch, scratchsize);
  265.                                 scratch = NULL;
  266.                             }
  267.                             break;
  268.  
  269.                         default:
  270.                             break;
  271.                     }
  272.                     break;
  273.  
  274.                 case MOUSEMOVE:
  275.  
  276. /* I'll ignore the message when I can for max speed */
  277.  
  278.                 if ((NOT drawing) || (x != w->MouseX) || (y != w->MouseY))
  279.                     break;
  280.  
  281. /* out with the old... */
  282.                 do_box(myrp, x1, y1, x2, y2);
  283.                 compute_xy2(window, &x2, &y2);
  284.  
  285. /* and in with the new */
  286.                 do_box(myrp, x1, y1, x2, y2);
  287.                 break;
  288.  
  289.                 case VANILLAKEY:
  290.  
  291.                     switch(code)
  292.                     {
  293. /* Control exact placement of 8x8 square areas */
  294. /* [u]p, [d]own, [l]eft, [r]ight are key commands */
  295.  
  296. /* (I considered h,j,k, & l but that would be Unix-snobbish :-) */
  297.  
  298.                         case 'l':
  299.                             x_offset--;
  300.                             break;
  301.  
  302.                         case 'r':
  303.                             x_offset++;
  304.                             break;
  305.  
  306.                         case 'u':
  307.                             y_offset--;
  308.                             break;
  309.  
  310.                         case 'd':
  311.                             y_offset++;
  312.                             break;
  313.  
  314. /* toggle automatic activation of window after keyboard pasting */
  315.  
  316.                         case 'a':
  317.                             reactivate = reactivate ? FALSE : TRUE;
  318.                             break;
  319.  
  320. /* Control how data is to be 'pasted' */
  321. /* [s]tandard output, [c]lipboard, [p]ipe file are key commands */
  322. /* new additions for V1.2: [k]eyboard and [K]eyboard without CR's */
  323.  
  324. /* Note that you can add your own save functions and use other letters to switch to them */
  325.  
  326.                         case 'p':
  327.                             save_format = WRITE_PIPE;
  328.                             break;
  329.  
  330.                         case 's':
  331.                             save_format = PRINT_STDOUT;
  332.                             break;
  333.  
  334.                         case 'k':
  335.                             save_format = TYPE_KEYBOARD;
  336.                             break;
  337.  
  338.                         case 'K':
  339.                             save_format = KEYBOARD_NOCR;
  340.                             break;
  341.  
  342.                         case 'c':
  343.                             save_format = PASTE_CLIPBOARD;
  344.                         default:
  345.                             break;
  346.                     }
  347.                     break;
  348.  
  349.                 default:
  350.                     break;
  351.  
  352.             }       /* end switch class */
  353.  
  354.         }       /* end while GetMsg */
  355.  
  356.     }           /* end while NOT done */
  357.  
  358. breakpoint:
  359.     _abort();
  360. }
  361.  
  362. _abort()
  363. {
  364.     if (ioReq)
  365.         if (ioReq->io_Device)
  366.             CloseDevice(ioReq);
  367.         DeleteStdIO(ioReq);
  368.     if (ioPort)
  369.         DeletePort(ioPort);
  370.     if (layer_locked)   free_window();
  371.     if (w)              CloseWindow(w);
  372.     if (fp)             Close(fp);
  373.     if (outfilehandle)  Close(outfilehandle);
  374.     if (scratch)        FreeMem(scratch, scratchsize);
  375.     if (IntuitionBase)  CloseLibrary(IntuitionBase);
  376.     if (GfxBase)        CloseLibrary(GfxBase);
  377.     if (LayersBase)     CloseLibrary(LayersBase);
  378.     exit(0);
  379. }
  380.  
  381. /* Always trying to save a few bytes... */
  382.  
  383. free_window()
  384. {
  385. #ifndef NOLOCK
  386.     UnlockLayerRom(window->WLayer);
  387. #endif
  388.     layer_locked = FALSE;
  389. }
  390.  
  391.