home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d3 / Telnet2.6.1d3.src.sit.hqx / Telnet 2.6.1d3 source / source / main / wdefpatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-27  |  12.0 KB  |  465 lines

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ⌐1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.     
  11.     Roberto Avanzi (independent programmer), June 18, 1992
  12.     Added support for tracking the extra part, in a way similar to the one used
  13.     by the system.
  14.     given back to Apple as an enhanced snippet (mmmh, sounds quite absurd)
  15.     
  16.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  17.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  18.     
  19. *******************************************/
  20.  
  21. #ifdef MPW
  22. #pragma segment 22
  23. #endif
  24.  
  25. #include "TelnetHeader.h"
  26. #include <GestaltEqu.h>
  27. #ifdef THINK_C
  28. #include <SysEqu.h>
  29. #endif
  30. #include "wind.h"
  31. #include "wdefpatch.proto.h"
  32. #include "tnae.h"
  33.  
  34. static void drawicon(short id, Rect *dest);
  35.  
  36. /* 931112, ragge, NADA, KTH */
  37. static void drawSize(Rect *wSize, WindowPtr window);
  38.  
  39. /* add 2 to this when checking with FindWindow() ! */
  40.  
  41. #define kOurHit    32
  42.  
  43.  
  44. /* 
  45.  * this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  46.  * and stores the old handle to the WDEF
  47.  */
  48.  
  49. typedef struct {
  50. #ifdef __powerpc__
  51.     RoutineDescriptor rd;
  52. #else
  53.     short jmpInst;
  54.     ProcPtr patchAddr;
  55. #endif
  56.     Handle oldAddr;
  57.     Boolean partState;    /* roberto avanzi jun 18 1992 */
  58.     long ourA5;
  59.     struct WindRec *tw;
  60. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  61.  
  62.  
  63. /* 
  64.  * RePatchWindowWDEF
  65.  * this adjusts the tw pointer for a patched window
  66.  * We have to do this since the tw for a window can change when other
  67.  * windows are killed.
  68.  */
  69. void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  70. {
  71.     WDEFPatchHndl wdPatch;
  72.  
  73.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  74.     (**wdPatch).tw = tw;
  75. }
  76.  
  77.  
  78. /*
  79.  * GetPatchStuffHandle
  80.  * This returns the handle to our patch block so we can release it
  81.  * when killing windows. The tw is verified to insure that this
  82.  * window is really patched.
  83.  */
  84. Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw)
  85. {
  86.     WDEFPatchHndl wdPatch;
  87.  
  88.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  89.     if ((**wdPatch).tw == tw)
  90.         return ((Handle)wdPatch);
  91.     else
  92.         return ((Handle)0);
  93. }
  94.  
  95.  
  96. #ifdef __powerpc__
  97. enum {
  98.     uppMyWDEFPatch = kPascalStackBased
  99.         | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  100.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
  101.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
  102.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short)))
  103.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  104. };
  105. #endif
  106.  
  107. pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param)
  108. {
  109.     WDEFPatchHndl wdPatch;
  110.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  111.     Handle oldWDEF;
  112.     long result;
  113.     Rect ourRect,ourElementRect;
  114.     GrafPtr    savePort;
  115.     GrafPtr aPort;
  116.     RgnHandle aRgn;
  117.     Rect aRect;
  118.     struct WindRec *tw;
  119.     long appA5, saveA5;
  120.     
  121.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  122.     appA5 = (**wdPatch).ourA5;
  123.     saveA5 = SetA5(appA5);
  124.  
  125.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  126.     /* our 16x16 rectangle */
  127.     SetRect(&ourElementRect,ourRect.right-42,ourRect.top+1,ourRect.right-26,ourRect.top+17);
  128.     
  129.     tw = (**wdPatch).tw;
  130.  
  131.     oldWDEF = (**wdPatch).oldAddr;
  132.     HLock(oldWDEF);
  133.     wdefProc = (void *)*oldWDEF;
  134.     wdefProc = (void *)StripAddress(wdefProc);
  135.  
  136.     /* 
  137.      * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in
  138.      * the sys WDEF (at least, sys 7's, dunno whattabout older ones) .
  139.      * Suppose You click once in the grow icon and DO NOT resize the window.
  140.      * (remember, just click and do not move the mouse in the meantime).
  141.      * Then you click on the added part. That part is tracked in the right way,
  142.      *                             *    BUT   *
  143.      * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot
  144.      * of FUN. Sadly, cannot find its place in any useful app. Therefore we
  145.      * do this check.
  146.      * APPLE says: if you write your own WDEF and receive unknown messages, do not
  147.      *             do anything. pass along and do NOTHING.
  148.      * APPLE does: we get something new ? therefore we process it anyway, just to
  149.      *             keep developers writing workarounds and keep their minds afresh.
  150.      * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992)
  151.      */
  152.     if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) {
  153. #ifdef __powerpc__
  154.         result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param);
  155. #else
  156.         result = (wdefProc)(varCode,window,message,param);
  157. #endif
  158.     }
  159.  
  160.     if (((WindowPeek)window)->visible)
  161.     if (((WindowPeek)window)->hilited)
  162.     {
  163.         switch (message) {
  164.             case wDraw:
  165.                 GetPort(&savePort);
  166.                 GetWMgrPort(&aPort);
  167.                 SetPort(aPort);
  168.                 aRgn = NewRgn();
  169.                 GetClip(aRgn);
  170.                 SetRect(&aRect,-32000,-32000,32000,32000);
  171.                 ClipRect(&aRect);
  172.                 switch ( (short) param ) {    // Roberto Avanzi 18-06-1992: support for 
  173.                                             // tracking of the new part
  174.                     case 0:
  175.                         (**wdPatch).partState = false;
  176.  
  177.                     case kOurHit:
  178.                         PenNormal();                            // draw our part
  179.     
  180.                          if (tw->aedata != NULL) {
  181.                             tnParams *ae = (tnParams *)tw->aedata;
  182.  
  183.                              if (ae->encrypting || ae->decrypting) {
  184.                                  /* 
  185.                                   * erase 18 x 11. This gives us a 1 pixel margin
  186.                                   * on the left and right, and matches the mask that
  187.                                   * we're using in our crsr resources.
  188.                                   */
  189.                                  InsetRect(&ourElementRect, -1, 0);
  190.                                  ourElementRect.top += 3;
  191.                                  ourElementRect.bottom -= 2;
  192.                                  EraseRect(&ourElementRect);
  193.                                  ourElementRect.top -= 3;
  194.                                  ourElementRect.bottom += 2;
  195.                                  InsetRect(&ourElementRect, 1, 0);
  196.                              }                        
  197.                              if (ae->encrypting && ae->decrypting)
  198.                                  drawicon(lockcrsr, &ourElementRect);
  199.                              else if (ae->encrypting)
  200.                                  drawicon(rightcrsr, &ourElementRect);
  201.                              else if (ae->decrypting)
  202.                                  drawicon(leftcrsr, &ourElementRect);
  203.                          }
  204.                         break;
  205.                         
  206.                     default:
  207.                         break;
  208.                 }
  209.                 SetClip(aRgn);
  210.                 DisposeRgn(aRgn);
  211.                 SetPort(savePort);
  212.                 break;
  213.  
  214.                 // removed this test so that one can move the window
  215.                 // also when clicking on the icon area.
  216.                 // 931112, ragge, NADA, KTH
  217. #ifdef NOTDEF
  218.             case wHit:
  219.                 hitPt = (Point *)¶m;                    // hit test our part
  220.                 if (PtInRect(*hitPt,&ourElementRect))
  221.                 {
  222.                     //result =  kOurHit;
  223.                 }
  224.                 break;
  225. #endif
  226.             
  227.             case wGrow:        /* 931112, ragge, NADA, KTH */
  228.                 drawSize((Rect *) param, window);
  229.                 break;
  230.  
  231.             default:
  232.                 break;
  233.         }    // switch
  234.     }    //    if hilited (otherwise we dont see the new box, addition by Roberto Avanzi)
  235.     HUnlock(oldWDEF);
  236.     
  237.     SetA5(saveA5);
  238.     
  239.     return result;
  240. }
  241.  
  242.  
  243. #ifdef __powerpc__
  244. RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch);
  245. #endif
  246.  
  247. /* 
  248.  * this installs the WDEF patch into a window 
  249.  */
  250. void PatchWindowWDEF (WindowPtr window, struct WindRec *tw)
  251. {
  252.     WDEFPatchHndl wdefHndl;
  253.     WDEFPatchPtr wdefPatch;
  254.     Handle oldAddr;
  255.     unsigned long wdefEntry;
  256.     
  257.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  258.  
  259.     oldAddr = ((WindowPeek)window)->windowDefProc;
  260.     if (GetMMUMode()) // 32-bit
  261.         wdefEntry = (unsigned long)wdefHndl;
  262.     else
  263.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  264.  
  265.     HLock((Handle)wdefHndl);
  266.     wdefPatch = *wdefHndl;
  267.     wdefPatch->oldAddr = oldAddr;
  268. #ifdef __powerpc__
  269.     BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd));
  270. #else
  271.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  272.     wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch;
  273. #endif
  274.     wdefPatch->ourA5 = (long)LMGetCurrentA5();        /* Use universal access (RW) */
  275.     wdefPatch->tw = tw;
  276.  
  277.     HUnlock((Handle)wdefHndl);
  278.  
  279.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  280. }
  281.  
  282.  
  283. /*
  284.  * drawicon
  285.  */
  286. void drawicon (short id, Rect *dest)
  287. {
  288.     long qdv;
  289.     Handle ih = 0;
  290.     Rect source_rect;
  291.     BitMap mask_bitmap;
  292.     GrafPtr local_port;
  293.     PixMap *pm;
  294.     Ptr colormap;
  295.     CCrsr *ccrsr;
  296.     BitMap src_bitmap;
  297.  
  298.     GetPort(&local_port);
  299.  
  300.     ih = GetResource ('crsr', id);                /* color cursor */
  301.     if (!ih)
  302.         return;
  303.     DetachResource(ih);        /* ... need to save handle somewhere ... */
  304.     HLock(ih);                /* ... to avoid reloading the resource all the time */
  305.  
  306.     /* 
  307.      * Set source Rect and intialize source BitMaps. 
  308.      * A few PixMap fields must be munged;
  309.      */
  310.     SetRect (&source_rect, 0, 0, 16, 16);
  311.     
  312.     ccrsr = (CCrsr *)(*ih);
  313.  
  314.     mask_bitmap.bounds = source_rect;
  315.     mask_bitmap.rowBytes = 2;
  316.     mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */
  317.     
  318.     /*
  319.      * if gestalt fails or no color quickdraw, just use the b/w bitmap.
  320.      */
  321.     if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) {
  322.         src_bitmap.bounds = source_rect;
  323.         src_bitmap.rowBytes = 2;
  324.         src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data;
  325.         CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest,
  326.                  srcCopy, nil);    
  327.     } else {
  328.         pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap);
  329.         pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData);
  330.             colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable);
  331.         pm->pmTable = (CTabHandle) &colormap;        /* handle to colormap */
  332.  
  333.         /* 
  334.          * Draw the crsr using its mask. 
  335.          * Do we need the mask ??? ...
  336.          */
  337.         CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits),
  338.                  &source_rect, &source_rect, dest);
  339.     }
  340.  
  341.     HUnlock(ih);
  342.     ReleaseResource((Handle)ih);
  343.     DisposHandle((Handle)ih);
  344. }
  345.  
  346. /* 931112, ragge, NADA, KTH */
  347. #define    HOFFSET    2
  348. #define VOFFSET    2
  349. static Rect gGrowTextBox;
  350. static Rect gGrowTextBoxInset;
  351. Boolean gDoGrowSize = false;
  352. static struct growSavedStruct {
  353.     Point charSize;
  354.     Point charInset;
  355.     Boolean eraseIt;
  356.  
  357.     PenState    savedPen;
  358.     short txFont;
  359.     Style txFace;
  360.     short txMode;
  361.     short txSize;
  362. } gGrowSaved;
  363.  
  364. /* 931112, ragge, NADA, KTH */
  365. void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize)
  366. {
  367.     GrafPtr    savedPort;
  368.     FontInfo fInfo;
  369.  
  370.     GetPort(&savedPort);
  371.     SetPort(window);
  372.         
  373.     gGrowSaved.charSize.h = hCharSize;
  374.     gGrowSaved.charSize.v = vCharSize;
  375.     gGrowSaved.charInset.h = hCharInset;
  376.     gGrowSaved.charInset.v = vCharInset;
  377.  
  378.     if(gGrowSaved.charSize.h == 0)    // don't want zero-div
  379.         gGrowSaved.charSize.h = 1;
  380.     if(gGrowSaved.charSize.v == 0)
  381.         gGrowSaved.charSize.v = 1;
  382.         
  383.     gGrowSaved.eraseIt = false;
  384.     
  385.     GetPenState(&gGrowSaved.savedPen);
  386.     
  387.     gGrowSaved.txFont = window->txFont;
  388.     gGrowSaved.txFace = window->txFace;
  389.     gGrowSaved.txMode = window->txMode;
  390.     gGrowSaved.txSize = window->txSize;
  391.  
  392.     PenNormal();
  393.     TextFont(1);
  394.     TextSize(9);
  395.     TextFace(0);
  396.     TextMode(srcCopy);
  397.     
  398.     GetFontInfo(&fInfo);
  399.  
  400.     gGrowTextBox.top = VOFFSET;
  401.     gGrowTextBox.left = HOFFSET;
  402.     gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3;    // Yes, 3!
  403.     gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6;
  404.     gGrowTextBoxInset = gGrowTextBox;
  405.     InsetRect(&gGrowTextBoxInset, 1, 1);
  406.     
  407.     gDoGrowSize = true;
  408.     
  409.     SetPort(savedPort);
  410. }
  411.  
  412. /* 931112, ragge, NADA, KTH */
  413. void cleanupForGrow(WindowPtr window)
  414. {
  415.     GrafPtr    savedPort;
  416.     GetPort(&savedPort);
  417.     SetPort(window);
  418.     
  419.     gDoGrowSize = false;
  420.     
  421.     InvalRect(&gGrowTextBox);
  422.     
  423.     SetPenState(&gGrowSaved.savedPen);
  424.     
  425.     window->txFont = gGrowSaved.txFont;
  426.     window->txFace = gGrowSaved.txFace;
  427.     window->txMode = gGrowSaved.txMode;
  428.     window->txSize = gGrowSaved.txSize;
  429.     
  430.     SetPort(savedPort);
  431. }
  432.  
  433. /* 931112, ragge, NADA, KTH */
  434. void drawSize(Rect *wSize, WindowPtr window)
  435. {
  436.     unsigned char string[50], yValLen;
  437.     GrafPtr savedPort;
  438.     
  439.     if(!gDoGrowSize)
  440.         return;
  441.  
  442.     GetPort(&savedPort);
  443.     SetPort(window);
  444.     
  445.     if(!gGrowSaved.eraseIt) {
  446.         NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string);
  447.         string[++string[0]] = ' ';
  448.         string[++string[0]] = '*';
  449.         NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1);
  450.         yValLen = string[string[0] + 1];
  451.         string[++string[0]] = ' ';
  452.         string[0] += yValLen;
  453.         TextBox(string + 1, string[0], &gGrowTextBoxInset, 1);
  454.         FrameRect(&gGrowTextBox);
  455.     } else {
  456.         Rect rGlob = gGrowTextBox;
  457.         LocalToGlobal((Point *) &(rGlob.top));
  458.         LocalToGlobal((Point *) &(rGlob.bottom));
  459.     }
  460.     
  461.     gGrowSaved.eraseIt = !gGrowSaved.eraseIt;
  462.  
  463.     SetPort(savedPort);
  464. }
  465.