home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d326 / snap.lha / Snap / source / snap.c < prev    next >
C/C++ Source or Header  |  1990-03-05  |  30KB  |  900 lines

  1. /***********************************************\
  2. *                                               *
  3. *                     Snap                      *
  4. *           (c) Mikael Karlsson 1988              *
  5. *                                               *
  6. \***********************************************/
  7. /* Auto: make
  8. */
  9.  
  10. #ifdef SNAPREXX
  11. #include "minrexx.h"
  12. #endif
  13.  
  14. #define ARGVAL() (*++(*argv) || (--argc && *++argv))
  15.  
  16. /* signals */
  17. LONGBITS startsignal, insertsignal, cancelsignal, donesignal;
  18. LONGBITS movesignal, clicksignal, timersignal, initsignal, cwsignal;
  19. ULONG startsignum = -1L;
  20. ULONG insertsignum = -1L;
  21. ULONG cancelsignum = -1L;
  22. ULONG donesignum = -1L;
  23. ULONG movesignum = -1L;
  24. ULONG clicksignum = -1L;
  25. ULONG timersignum = -1L;
  26. ULONG initsignum = -1L;
  27. ULONG cwsignum = -1L;
  28. ULONG WaitSignal;
  29.  
  30. /* program */
  31. struct SnapRsrc *SnapRsrc = NULL;
  32. struct Task *MyTask;
  33.  
  34. /* Snap state machine */
  35. WORD action;
  36. WORD state;
  37.  
  38. /* clipboard */
  39. struct IOClipReq *ClipReq = NULL;
  40. struct MsgPort *ClipPort = NULL;
  41.  
  42. /* timer device */
  43. struct MsgPort *TimerPort = NULL;
  44. struct timerequest MyTR;
  45.  
  46. /* input device */
  47. struct MsgPort *inputDevPort = NULL;
  48. struct Interrupt handlerStuff;
  49. struct IOStdReq *inputRequestBlock = NULL;
  50. struct InputEvent SimEvent;
  51. WORD textqual;
  52. WORD gfxqual;
  53. WORD insertkey;
  54. WORD cwkey;
  55. WORD modinsert;
  56.  
  57. UBYTE *CharData = NULL;
  58. UBYTE TrueUnderscore;
  59.  
  60. /* console */
  61. struct MsgPort *ConPort = NULL;
  62. struct IOStdReq *ConIOR = NULL;
  63. struct KeyMap keymap;
  64.  
  65. /* windows */
  66. struct MsgPort *Sharedport = NULL;
  67. SHORT Sharedrefs;
  68. IMPORT UBYTE *WindowTitle;
  69. IMPORT struct Window *ControlWindow;
  70. struct Window *SaveWin = NULL;
  71. IMPORT struct Gadget SaveGad;
  72. IMPORT struct Gadget NameGad;
  73. struct GfxSnap *SwapGS = NULL;
  74. struct MinList CachedWindows;
  75. IMPORT struct StringInfo TranspSI;
  76.  
  77. /* libraries */
  78. struct IntuitionBase *IntuitionBase = NULL;
  79. struct GfxBase       *GfxBase = NULL;
  80. struct LayersBase    *LayersBase = NULL;
  81. struct ArpBase       *ArpBase = NULL;
  82. /* struct DosLibrary    *DosBase = NULL; */
  83.  
  84. /* graphics */
  85. struct Screen *theScreen;
  86. struct Layer *theLayer;
  87. struct RastPort rp, TempRp, MyRP;
  88. struct BitMap TempBM, MyBM;
  89. UBYTE *TempRaster = NULL;
  90.  
  91. IMPORT struct FileRequester NameFR;
  92. IMPORT UBYTE SaveName[256];
  93. IMPORT UBYTE SaveDirName[256];
  94. BPTR SnapFile;
  95.  
  96. /* ARexx stuff */
  97. #ifdef SNAPREXX
  98. ULONG rexxsignal;
  99. IMPORT struct rexxCommandList rcl[];
  100. WORD disp();
  101. #endif
  102.  
  103. /* detaching */
  104. ULONG _BackGroundIO = 0;
  105. ULONG _stack = 4096L;
  106. ULONG _priority = 4L;
  107. char *_procname = "Snap";
  108. #ifdef LATTICE
  109. extern BPTR _Backstdout;
  110. #endif LATTICE
  111.  
  112. WORD isdigit(c)
  113. REGISTER char c;
  114. {
  115.     return (WORD)(c>='0' && c<='9');
  116. }
  117.  
  118. #ifdef AZTEC_C
  119. char *strupr(str)
  120. char *str;
  121. {
  122.     register char *p = str;
  123.     register char c;
  124.     while (c = *p) {
  125.         if ('a' <= c && c <= 'z') {
  126.             *p = c - ('a' - 'A');
  127.         }
  128.         ++p;
  129.     }
  130.     return str;
  131. }
  132. #endif AZTEC_C
  133.  
  134. LONG dectoint(str)
  135. REGISTER char *str;
  136. {
  137.     REGISTER long val = 0;
  138.     REGISTER char c;
  139.     while (isdigit(c = *str)) {
  140.         val = (((val<<2)+val)<<1) + c-'0';
  141.         str++;
  142.     }
  143.     return(val);
  144. }
  145.  
  146. LONG hextoint(str)
  147. REGISTER char *str;
  148. {
  149.     REGISTER long val = 0;
  150.     REGISTER char c;
  151.     while (c = *str) {
  152.         val <<= 4;
  153.         val |= (c & 15) + (isdigit(c) ? 0 : 9);
  154.         str++;
  155.     }
  156.     return(val);
  157. }
  158.  
  159. WORD insertcount;
  160.  
  161. VOID InsertAscii(ascii)
  162. ULONG ascii;
  163. {
  164.     if (insertcount == 1) {   /* Time for second char */
  165.           /* Not necessary to patch here but it guarantees
  166.              that all inserted chars end up in the same window. */
  167.         SafePatch();
  168.     }
  169.     InvertKeyMap(ascii, &SimEvent, &keymap);
  170.     DoIO(inputRequestBlock);
  171.     if (SnapRsrc->chardelay) {
  172.         MyTR.tr_node.io_Command = TR_ADDREQUEST;
  173.         MyTR.tr_time.tv_micro = SnapRsrc->chardelay;
  174.         MyTR.tr_time.tv_secs = 0;
  175.         DoIO((struct IOStdReq *)&MyTR);
  176.     }
  177.     ++insertcount;
  178. }
  179.  
  180. VOID GadText(Gad, Str, Len)
  181. struct Gadget *Gad;
  182. char *Str;
  183. LONG Len;
  184. {
  185.     char temp[256];
  186.     SHORT i;
  187.  
  188.     SetDrMd(ControlWindow->RPort, JAM2);
  189.     SetAPen(ControlWindow->RPort, 0L);
  190.     RectFill(ControlWindow->RPort, (LONG)Gad->LeftEdge, (LONG)Gad->TopEdge,
  191.       (LONG)Gad->LeftEdge + Gad->Width - 1, (LONG)Gad->TopEdge + Gad->Height - 1);
  192.     SetAPen(ControlWindow->RPort, 1L);
  193.     SetBPen(ControlWindow->RPort, 0L);
  194.     Move(ControlWindow->RPort,
  195.       (LONG)Gad->LeftEdge + 1,
  196.       (LONG)Gad->TopEdge + ControlWindow->RPort->Font->tf_Baseline + 1);
  197.     if (TextLength(ControlWindow->RPort, Str, Len) > Gad->Width) {
  198.         i = Len;
  199.         strncpy(temp, Str, i - 3);
  200.         strcat(temp, "...");
  201.         while (TextLength(ControlWindow->RPort, temp, (LONG)i) > Gad->Width) {
  202.             --i;
  203.             temp[i] = '\0';
  204.             temp[i-3] = '.';
  205.         }
  206.         Text(ControlWindow->RPort, temp, (LONG)i);
  207.     } else {
  208.         Text(ControlWindow->RPort, Str, Len);
  209.     }
  210. }
  211.  
  212. VOID SwapColorMap(GS)
  213. struct GfxSnap *GS;
  214. {
  215.     struct ViewPort *vp = &GS->window->WScreen->ViewPort;
  216.     LONG i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
  217.     ULONG col;
  218.  
  219.     while (i-- && (col = GetRGB4(vp->ColorMap, i)) != -1L) {
  220.         SetRGB4(vp, i,
  221.           (LONG)GS->rgb[i][0] >> 4,
  222.           (LONG)GS->rgb[i][1] >> 4,
  223.           (LONG)GS->rgb[i][2] >> 4);
  224.         GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
  225.         GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
  226.         GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
  227.     }
  228. }
  229.  
  230. VOID CheckWindowMsgs()
  231. {
  232.     struct IntuiMessage *Msg;
  233.     struct IntuiMessage *QdMsg = NULL;
  234.     ULONG Class;
  235.     USHORT Code;
  236.     struct Window *Win;
  237.     struct Gadget *Gad;
  238.  
  239.     while (Sharedport &&
  240.       (QdMsg || (Msg = (struct IntuiMessage *)GetMsg(Sharedport)))) {
  241.         if (QdMsg) {
  242.             Msg = QdMsg;
  243.             QdMsg = NULL;
  244.         }
  245.         Class = Msg->Class;
  246.         Code  = Msg->Code;
  247.         Win   = Msg->IDCMPWindow;
  248.         Gad   = (struct Gadget *)Msg->IAddress;
  249.         ReplyMsg((struct Message *)Msg);
  250.         switch (Class) {
  251.             case CLOSEWINDOW: {
  252.                 if (Win == ControlWindow) {
  253.                     ControlWindow = NULL;
  254.                     if (SaveWin) {
  255.                         struct GfxSnap *GS;
  256.                         SetWindowTitles(SaveWin, WindowTitle, NULL);
  257.                         GS = (struct GfxSnap *)SaveWin->UserData;
  258.                         RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  259.                         SaveWin = NULL;
  260.                     }
  261.                 } else {
  262.                     struct GfxSnap *GS;
  263.                     GS = (struct GfxSnap *)Win->UserData;
  264.                     FreePlanes(&GS->BM, GS->width, GS->height);
  265.                     Kill(GS);
  266.                     if (Win == SaveWin) {
  267.                         if (ControlWindow) {
  268.                             OffGadget(&SaveGad, ControlWindow, NULL);
  269.                         }
  270.                         SaveWin = NULL;
  271.                     }
  272.                 }
  273.                 closesharedwindow(Win);
  274.                 break;
  275.             }
  276.             case NEWSIZE: {
  277.                 AdjustSize((struct GfxSnap *)Win->UserData);
  278.                 break;
  279.             }
  280.             case MOUSEMOVE: {
  281.                   /* Collapse all consecutively queued MOUSEMOVE msgs */
  282.                 while ((QdMsg = (struct IntuiMessage *)GetMsg(Sharedport))
  283.                   && (QdMsg->Class == MOUSEMOVE)) {
  284.                     ReplyMsg((struct Message *)QdMsg);
  285.                 }
  286.                 SyncGS((struct GfxSnap *)Win->UserData);
  287.                 break;
  288.             }
  289.             case ACTIVEWINDOW: {
  290.                 if (Win != ControlWindow) {
  291.                     struct GfxSnap *GS;
  292.                     GS = (struct GfxSnap *)Win->UserData;
  293.                     RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  294.                 }
  295.                 break;
  296.             }
  297.             case INACTIVEWINDOW: {
  298.                 if (Win != ControlWindow) {
  299.                     struct GfxSnap *GS;
  300.                     if (SwapGS) {
  301.                         SwapColorMap(SwapGS);
  302.                         SwapGS = NULL;
  303.                     }
  304.                     GS = (struct GfxSnap *)Win->UserData;
  305.                     RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  306.                 }
  307.                 break;
  308.             }
  309.             case GADGETUP: {
  310.                 switch (Gad->GadgetID) {
  311.                     case VPROP:
  312.                     case HPROP: {
  313.                         SyncGS((struct GfxSnap *)Win->UserData);
  314.                         break;
  315.                     }
  316.                     case SAVEGAD: {
  317. savepic:
  318.                         if (SaveWin) {
  319.                             WORD success;
  320.                             if (SaveName[0] == '\0') {
  321.                                 DisplayBeep(NULL);
  322.                                 ActivateGadget(&NameGad, ControlWindow, NULL);
  323.                                 break;
  324.                             }
  325.                             SnapFile = (BPTR)Open(SaveName, MODE_NEWFILE);
  326.                             success = SaveGS((struct GfxSnap *)SaveWin->UserData);
  327.                             Close(SnapFile);
  328.                             if (success) {
  329.                                 SetWindowTitles(ControlWindow, "Saved ok", NULL);
  330.                             } else {
  331.                                 DeleteFile(SaveName);
  332.                                 DisplayBeep(NULL);
  333.                                 SetWindowTitles(ControlWindow, "Save failed", NULL);
  334.                             }
  335.                         }
  336.                         break;
  337.                     }
  338.                     case NAMEGAD: { /* Should only happen with Arp */
  339.                         strcpy(SaveDirName, SaveName);
  340.                         strcpy(SaveName, BaseName(SaveDirName));
  341.                         *(BaseName(SaveDirName)) = '\0';
  342.                         NameFR.fr_Window = ControlWindow;
  343.                         (VOID)FileRequest(&NameFR);
  344.                         TackOn(SaveDirName, SaveName);
  345.                         strcpy(SaveName, SaveDirName);
  346.                         GadText(&NameGad, SaveName, (LONG)strlen(SaveName));
  347.                         break;
  348.                     }
  349.                     case DISKGAD: {
  350.                         struct GfxSnap *GS;
  351.                         if (!ControlWindow && !OpenCW()) {
  352.                             DisplayBeep(NULL);
  353.                             break;
  354.                         }
  355.                         if (Win == SaveWin) {
  356.                             goto savepic;
  357.                         }
  358.                         if (SaveWin) {
  359.                             SetWindowTitles(SaveWin, WindowTitle, NULL);
  360.                             GS = (struct GfxSnap *)SaveWin->UserData;
  361.                             RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  362.                         } else {
  363.                             GadText(&SaveGad, "Save", 4L);
  364.                             OnGadget(&SaveGad, ControlWindow, NULL);
  365.                         }
  366.                         SaveWin = Win;
  367.                         SetWindowTitles(SaveWin, "Selected", NULL);
  368.                         GS = (struct GfxSnap *)SaveWin->UserData;
  369.                         RefreshGList(&GS->DiskGad, GS->window, NULL, 1L);
  370.                         break;
  371.                     }
  372.                     default: {
  373.                         break;
  374.                     }
  375.                 }
  376.                 break;
  377.             }
  378.             case MOUSEBUTTONS: {
  379.                 if (Win != ControlWindow) {
  380.                     if (Code == SELECTDOWN && !SwapGS) {
  381.                         SwapGS = (struct GfxSnap *)Win->UserData;
  382.                         SwapColorMap(SwapGS);
  383.                     } else if (Code == SELECTUP && SwapGS) {
  384.                         SwapColorMap(SwapGS);
  385.                         SwapGS = NULL;
  386.                     }
  387.                 }
  388.                 break;
  389.             }
  390.             default: {
  391.                 break;
  392.             }
  393.         }
  394.     }
  395.     if (QdMsg) {
  396.         ReplyMsg((struct Message *)QdMsg);
  397.     }
  398. }
  399.  
  400. #define WriteStdOut(str) Write(StdOut, str, (LONG)strlen(str))
  401.  
  402. VOID main(argc, argv)
  403. int argc;
  404. char **argv;
  405. {
  406.     WORD create = 0, usage = 0;
  407.  
  408.     BPTR StdOut = (BPTR)Open("*", MODE_OLDFILE);
  409.  
  410. #ifdef LATTICE
  411.     if(_Backstdout)
  412.         Close(_Backstdout);
  413.  
  414.     _Backstdout = 0;
  415. #endif LATTICE
  416.  
  417. #ifdef AZTEC_C
  418.     Enable_Abort = 0;
  419. #endif AZTEC_C
  420.     if (!(SnapRsrc = (struct SnapRsrc *)OpenResource(SNAPRSRC))) {
  421.         create = 1;
  422.         SnapRsrc = Create(SnapRsrc);
  423.         SnapRsrc->node.ln_Type = NT_RESOURCE;
  424.         SnapRsrc->node.ln_Name = SNAPRSRC;
  425.         SnapRsrc->Task = FindTask(NULL);
  426.         SnapRsrc->Priority = 51;
  427.         SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
  428.         SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
  429.         SnapRsrc->insertkey = 0x17;
  430.         SnapRsrc->cwkey = 0x11;
  431.         strcpy(&SnapRsrc->Prepend[0], "> ");
  432.         strcpy(&SnapRsrc->Append[0], "");
  433.         SnapRsrc->flags = TRUEUNDERSCORE;
  434.         SnapRsrc->chardelay = 0;
  435.         SnapRsrc->linedelay = 0;
  436.         SnapRsrc->CrawlPtrn = 0x7777;
  437.         SnapRsrc->StartUnit = UNIT_FRAME;
  438.         SnapRsrc->FrameMask = 1;
  439.         SnapRsrc->GadOffset = 52;
  440.         SnapRsrc->CacheSize = 10;
  441.         SnapRsrc->BadChar = '?';
  442.         AddResource(SnapRsrc);
  443.     }
  444.  
  445.     if (!argc) {    /* WB Startup */
  446.         if (!create) {     /* Second time from WB -- Remove Snap */
  447.             Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
  448.             goto exitpoint;
  449.         } else {
  450.             goto skipargs;
  451.         }
  452.     }
  453.  
  454.     if (create && StdOut) {
  455.         WriteStdOut("Snap 1.4 (c) 1990 Mikael Karlsson\n");
  456.     }
  457.  
  458.     for (argc--, argv++; argc > 0; argc--, argv++) {
  459.         if (**argv == '-') { /* Argument coming up */
  460.             switch(*++(*argv)) {
  461.                 case 'p': priority: {  /* Priority */
  462.                     if (ARGVAL()) {
  463.                         WORD pri = dectoint(*argv);
  464.                         if (pri>50 && pri<128) {
  465.                             SnapRsrc->Priority = pri;
  466.                         }
  467.                     } else {
  468.                         usage = 1;
  469.                     }
  470.                     break;
  471.                 }
  472.                 case 't': textqual: {
  473.                     if (ARGVAL()) {
  474.                         SnapRsrc->textqual = hextoint(*argv);
  475.                     } else {
  476.                         usage = 1;
  477.                     }
  478.                     break;
  479.                 }
  480.                 case 'g': gfxqual: {
  481.                     if (ARGVAL()) {
  482.                         SnapRsrc->gfxqual = hextoint(*argv);
  483.                     } else {
  484.                         usage = 1;
  485.                     }
  486.                     break;
  487.                 }
  488.                 case 'i': insertkey: {
  489.                     if (ARGVAL()) {
  490.                         SnapRsrc->insertkey = hextoint(*argv);
  491.                     } else {
  492.                         usage = 1;
  493.                     }
  494.                     break;
  495.                 }
  496.                 case 'w': cwkey: {
  497.                     if (ARGVAL()) {
  498.                         SnapRsrc->cwkey = hextoint(*argv);
  499.                     } else {
  500.                         usage = 1;
  501.                     }
  502.                     break;
  503.                 }
  504.                 case 'c': chardelay: {
  505.                     if (ARGVAL()) {
  506.                         SnapRsrc->chardelay = dectoint(*argv) * 1000;
  507.                     } else {
  508.                         usage = 1;
  509.                     }
  510.                     break;
  511.                 }
  512.                 case 'l': linedelay: {
  513.                     if (ARGVAL()) {
  514.                         SnapRsrc->linedelay = dectoint(*argv) * 1000;
  515.                     } else {
  516.                         usage = 1;
  517.                     }
  518.                     break;
  519.                 }
  520.                 case 'a': crawlptrn: {
  521.                     if (ARGVAL()) {
  522.                         SnapRsrc->CrawlPtrn = hextoint(*argv);
  523.                     } else {
  524.                         usage = 1;
  525.                     }
  526.                     break;
  527.                 }
  528.                 case 'X': noxerox: {
  529.                     SnapRsrc->flags &= ~XEROX;
  530.                     break;
  531.                 }
  532.                 case 'x': xerox: {
  533.                     SnapRsrc->flags |= XEROX;
  534.                     break;
  535.                 }
  536.                 case 'E': noearlypatch: {
  537.                     SnapRsrc->flags &= ~EARLYPATCH;
  538.                     break;
  539.                 }
  540.                 case 'e': earlypatch: {
  541.                     SnapRsrc->flags |= EARLYPATCH;
  542.                     break;
  543.                 }
  544.                 case 'R': fakeunderscore: {
  545.                     SnapRsrc->flags &= ~TRUEUNDERSCORE;
  546.                     break;
  547.                 }
  548.                 case 'r': realunderscore: {
  549.                     SnapRsrc->flags |= TRUEUNDERSCORE;
  550.                     break;
  551.                 }
  552.                 case 'J': nojoinlong: {
  553.                     SnapRsrc->flags &= ~JOINLONG;
  554.                     break;
  555.                 }
  556.                 case 'j': joinlong: {
  557.                     SnapRsrc->flags |= JOINLONG;
  558.                     break;
  559.                 }
  560.                 case 'A': append:
  561.                 case 'P': prepend: {
  562.                     char *dest = (**argv == 'A' ?
  563.                       &SnapRsrc->Append[0] : &SnapRsrc->Prepend[0]);
  564.                     if (*++(*argv) || (--argc && ++argv)) { /* "" is ok */
  565.                         char *src = *argv;
  566.                         WORD i = 16;
  567.                         while (*src && i--) {
  568.                             *dest++ = *src++;
  569.                         }
  570.                         *dest = '\0';
  571.                     } else {
  572.                         usage = 1;
  573.                     }
  574.                     break;
  575.                 }
  576.                 case 'u': startunit: {
  577.                     if (ARGVAL()) {
  578.                         switch(dectoint(*argv)) {
  579.                             case 1: {
  580.                                 SnapRsrc->StartUnit = UNIT_CHAR;
  581.                                 break;
  582.                             }
  583.                             case 0:
  584.                             default: {
  585.                                 SnapRsrc->StartUnit = UNIT_FRAME;
  586.                                 break;
  587.                             }
  588.                         }
  589.                     } else {
  590.                         usage = 1;
  591.                     }
  592.                     break;
  593.                 }
  594.                 case 'b': planemask: {
  595.                     if (ARGVAL()) {
  596.                         SnapRsrc->FrameMask = hextoint(*argv);
  597.                     } else {
  598.                         usage = 1;
  599.                     }
  600.                     break;
  601.                 }
  602.                 case 'o': gadoffset: {
  603.                     if (ARGVAL()) {
  604.                         SnapRsrc->GadOffset = dectoint(*argv);
  605.                     } else {
  606.                         usage = 1;
  607.                     }
  608.                     break;
  609.                 }
  610.                 case 'C': cachesize: {
  611.                     if (ARGVAL()) {
  612.                         SnapRsrc->CacheSize = dectoint(*argv);
  613.                     } else {
  614.                         usage = 1;
  615.                     }
  616.                     break;
  617.                 }
  618.                 case 'B': badchar: {
  619.                     if (ARGVAL()) {
  620.                         SnapRsrc->BadChar = dectoint(*argv);
  621.                     } else {
  622.                         usage = 1;
  623.                     }
  624.                     break;
  625.                 }
  626.                 case 'Q': quit: {
  627.                     Close(StdOut);
  628.                     if (create) {
  629.                         goto close;
  630.                     } else {
  631.                         Signal(SnapRsrc->Task, SIGBREAKF_CTRL_C);
  632.                         goto exitpoint;
  633.                     }
  634.                 }
  635.                 case '?': {
  636.                     usage = 1;
  637.                     break;
  638.                 }
  639.                 default: {
  640.                     if (StdOut) {
  641.                         WriteStdOut("Bad option: -");
  642.                         Write(StdOut, *argv, 1L);
  643.                         WriteStdOut(".\n");
  644.                     }
  645.                     usage = 1;
  646.                     break;
  647.                 }
  648.             }
  649.         } else {
  650.             (VOID)strupr(*argv);
  651.             if (!strcmp(*argv, "PRIORITY")) {
  652.                 (*argv)[1] = '\0';                  /* Fake no argument */
  653.                 goto priority;                      /* Terrible, ain't it? */
  654.             } else if (!strcmp(*argv, "TEXTQUAL")) {
  655.                 (*argv)[1] = '\0';
  656.                 goto textqual;
  657.             } else if (!strcmp(*argv, "GFXQUAL")) {
  658.                 (*argv)[1] = '\0';
  659.                 goto gfxqual;
  660.             } else if (!strcmp(*argv, "INSERTKEY")) {
  661.                 (*argv)[1] = '\0';
  662.                 goto insertkey;
  663.             } else if (!strcmp(*argv, "CWKEY")) {
  664.                 (*argv)[1] = '\0';
  665.                 goto cwkey;
  666.             } else if (!strcmp(*argv, "PREPEND")) {
  667.                 (*argv)[1] = '\0';
  668.                 goto prepend;
  669.             } else if (!strcmp(*argv, "APPEND")) {
  670.                 (*argv)[1] = '\0';
  671.                 goto append;
  672.             } else if (!strcmp(*argv, "CHARDELAY")) {
  673.                 (*argv)[1] = '\0';
  674.                 goto chardelay;
  675.             } else if (!strcmp(*argv, "LINEDELAY")) {
  676.                 (*argv)[1] = '\0';
  677.                 goto linedelay;
  678.             } else if (!strcmp(*argv, "CRAWLPTRN")) {
  679.                 (*argv)[1] = '\0';
  680.                 goto crawlptrn;
  681.             } else if (!strcmp(*argv, "XEROX")) {
  682.                 goto xerox;
  683.             } else if (!strcmp(*argv, "NOXEROX")) {
  684.                 goto noxerox;
  685.             } else if (!strcmp(*argv, "EARLYPATCH")) {
  686.                 goto earlypatch;
  687.             } else if (!strcmp(*argv, "NOEARLYPATCH")) {
  688.                 goto noearlypatch;
  689.             } else if (!strcmp(*argv, "TRUEUNDERSCORE")) {
  690.                 goto realunderscore;
  691.             } else if (!strcmp(*argv, "FAKEUNDERSCORE")) {
  692.                 goto fakeunderscore;
  693.             } else if (!strcmp(*argv, "JOINLONG")) {
  694.                 goto joinlong;
  695.             } else if (!strcmp(*argv, "NOJOINLONG")) {
  696.                 goto nojoinlong;
  697.             } else if (!strcmp(*argv, "STARTUNIT")) {
  698.                 (*argv)[1] = '\0';
  699.                 goto startunit;
  700.             } else if (!strcmp(*argv, "PLANEMASK")) {
  701.                 (*argv)[1] = '\0';
  702.                 goto planemask;
  703.             } else if (!strcmp(*argv, "GADOFFSET")) {
  704.                 (*argv)[1] = '\0';
  705.                 goto gadoffset;
  706.             } else if (!strcmp(*argv, "CACHESIZE")) {
  707.                 (*argv)[1] = '\0';
  708.                 goto cachesize;
  709.             } else if (!strcmp(*argv, "BADCHAR")) {
  710.                 (*argv)[1] = '\0';
  711.                 goto badchar;
  712.             } else if (!strcmp(*argv, "QUIT")) {
  713.                 goto quit;
  714.             } else if (strcmp(*argv, "?") && StdOut) {
  715.                 WriteStdOut("Bad switch/keyword: ");
  716.                 WriteStdOut(*argv);
  717.                 WriteStdOut(".\n");
  718.             }
  719.             usage = 1;
  720.         }
  721.     }
  722.  
  723.     if (usage && StdOut) {
  724.         WriteStdOut("Usage:\n");
  725.         WriteStdOut(" snap -pNN -tXX -gXX -iXX -wXX -Pstr -Astr -cNN -lNN -aXXXX\n");
  726.         WriteStdOut("   -x -X -e -E -uN -r -R -j -J -bXX -oNN -CNN -BNN -Q\n");
  727.         WriteStdOut(" or\n");
  728.         WriteStdOut(" snap PRIORITY/k TEXTQUAL/k GFXQUAL/k INSERTKEY/k CWKEY/k\n");
  729.         WriteStdOut("   PREPEND/k APPEND/k CHARDELAY/k LINEDELAY/k CRAWLPTRN/k\n");
  730.         WriteStdOut("   XEROX/s NOXEROX/s EARLYPATCH/s NOEARLYPATCH/s STARTUNIT/k\n");
  731.         WriteStdOut("   TRUEUNDERSCORE/s FAKEUNDERSCORE/s JOINLONG/s NOJOINLONG/s\n");
  732.         WriteStdOut("   PLANEMASK/k GADOFFSET/k CACHESIZE/k BADCHAR/s QUIT/s\n");
  733.     }
  734.  
  735. skipargs:
  736.     if (StdOut) {
  737.         Close(StdOut);
  738.     }
  739.  
  740.     if (!create) {
  741.           /* Tell him there are new settings available */
  742.         Signal(SnapRsrc->Task, SIGBREAKF_CTRL_F);
  743.         goto exitpoint;
  744.     }
  745.  
  746.     textqual = SnapRsrc->textqual;
  747.     gfxqual = SnapRsrc->gfxqual;
  748.     insertkey = SnapRsrc->insertkey;
  749.     cwkey = SnapRsrc->cwkey;
  750.     TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  751.  
  752.     if (!OpenStuff()) {
  753.         goto close;
  754.     }
  755.  
  756. #ifdef SNAPREXX
  757.     rexxsignal = upRexxPort("SNAP", &rcl, NULL, &disp);
  758. #endif
  759.  
  760.     /* This is what we're waiting for */
  761.     WaitSignal = startsignal | insertsignal | initsignal | cancelsignal |
  762. #ifdef SNAPREXX
  763.                  rexxsignal |
  764. #endif
  765.                  cwsignal | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
  766.  
  767.     FOREVER {
  768.         REGISTER LONGBITS sig =
  769.           Wait(WaitSignal |
  770.                (Sharedport ? (1L << Sharedport->mp_SigBit) : 0L));
  771.         CheckWindowMsgs();
  772. #ifdef SNAPREXX
  773.         if (sig & rexxsignal) {
  774.             dispRexxPort();
  775.         }
  776. #endif
  777.         if (sig & SIGBREAKF_CTRL_C) {
  778.             /* This is my cue. Exit if there are no open windows depending on us */
  779.             if (Sharedrefs) {
  780.                 DisplayBeep(NULL);
  781.             } else {
  782.                 goto close;
  783.             }
  784.         }
  785.         if (sig & SIGBREAKF_CTRL_F) {
  786.             /* Hey, seems like there are new settings available. */
  787.             textqual = SnapRsrc->textqual;
  788.             gfxqual = SnapRsrc->gfxqual;
  789.             insertkey = SnapRsrc->insertkey;
  790.             cwkey = SnapRsrc->cwkey;
  791.             TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  792.         }
  793.         if (sig & initsignal) {
  794.             if (SnapRsrc->flags & (XEROX | EARLYPATCH)) {
  795.                 SafePatch();               /* Patch dangerous functions */
  796.             }
  797.         }
  798.         if (sig & cancelsignal) {
  799.             SafeRestore();
  800.         }
  801.         if (sig & startsignal) { /* The handler wants a word in. */
  802.             SafePatch();
  803.             if (action == snapgfx) {       /* Check user action */
  804.                 HandleGfx();               /* Get the picture :-) */
  805.             } else if (action == snaptext) {
  806.                 if (HandleChars()) {             /* Snap some chars */
  807.                     if (SnapRsrc->flags & XEROX) {
  808.                         sig |= insertsignal;
  809.                     }
  810.                 }
  811.             } else {
  812.                   /* Previous snap wasn't finished when this one started. */
  813.                 SetSignal(0L,
  814.                   movesignal|cancelsignal|donesignal|clicksignal|timersignal);
  815.                 DisplayBeep(NULL);
  816.                 action = noaction;
  817.             }
  818.             if (!(sig & insertsignal)) {
  819.                 SafeRestore();             /* Layers unlocked - all safe */
  820.             }
  821.         }
  822.  
  823.         if (sig & insertsignal) {
  824.             LONG i;
  825.             struct Snap *Snap;
  826.             ULONG ascii;
  827.  
  828.             action = insert;
  829.             if (Snap = FetchClip()) {  /* Get clipboard data */
  830.                   /* get the current keymap  */
  831.                 ConIOR->io_Command =  CD_ASKDEFAULTKEYMAP;
  832.                 ConIOR->io_Length  = sizeof (struct KeyMap);
  833.                 ConIOR->io_Data    = (APTR) &keymap;
  834.                 ConIOR->io_Flags   = 1;    /* no IOQuick   */
  835.                 DoIO(ConIOR);
  836.                   /* Set up an input request */
  837.                 inputRequestBlock->io_Command = IND_WRITEEVENT;
  838.                 inputRequestBlock->io_Flags   = 0L;
  839.                 inputRequestBlock->io_Length  = (long)sizeof(struct InputEvent);
  840.                 inputRequestBlock->io_Data    = (APTR)&SimEvent;
  841.                   /* Translate chars in SnapSpace and insert them
  842.                      into the input stream. */
  843.                 insertcount = 0;
  844.                 ascii = 13;  /* Simulate start of new line */
  845.                 for (i = 0; Snap->Chars[i] && (action == insert); ++i) {
  846.                     if (ascii == 13 && modinsert) {
  847.                         int cnt = 0;
  848.                         while (ascii = SnapRsrc->Prepend[cnt++]) {
  849.                             InsertAscii(ascii);
  850.                         }
  851.                     }
  852.  
  853.                     ascii = Snap->Chars[i];
  854.                     if (ascii == 10) {
  855.                         if (modinsert) {
  856.                             int cnt = 0;
  857.                             while (ascii = SnapRsrc->Append[cnt++]) {
  858.                                 InsertAscii(ascii);
  859.                             }
  860.                         }
  861.                         ascii = 13;     /* WYSIWYG? Hah! */
  862.                         if (SnapRsrc->linedelay) {
  863.                             MyTR.tr_node.io_Command = TR_ADDREQUEST;
  864.                             MyTR.tr_time.tv_micro = SnapRsrc->linedelay;
  865.                             MyTR.tr_time.tv_secs = 0;
  866.                             DoIO((struct IOStdReq *)&MyTR);
  867.                         }
  868.                     }
  869.                     InsertAscii(ascii);
  870.                 }
  871.                 if (modinsert) {
  872.                     int cnt = 0;
  873.                     while (ascii = SnapRsrc->Append[cnt++]) {
  874.                         InsertAscii(ascii);
  875.                     }
  876.                 }
  877.                 SafeRestore();  /* "Depatch" */
  878.                   /* Free memory given to us by FetchClip() */
  879.                 FreeMem(Snap, Snap->Size);
  880.             }
  881.             action = noaction;
  882.             modinsert = 0;
  883.         }
  884.  
  885.         if (sig & cwsignal) {
  886.             if (!ControlWindow && !OpenCW()) {
  887.                 DisplayBeep(NULL);
  888.             }
  889.         }
  890.     }
  891.  
  892. close:
  893. #ifdef SNAPREXX
  894.     dnRexxPort();
  895. #endif
  896.     CloseStuff();  /* Guess what */
  897. exitpoint: ;
  898. }
  899.  
  900.