home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / PatchLib 1.0d3 / Source / PatchTest / PatchTest.c next >
Encoding:
C/C++ Source or Header  |  1994-12-01  |  6.3 KB  |  237 lines  |  [TEXT/KAHL]

  1. /*    See the file Distribution for distribution terms.
  2.     (c) Copyright 1994 Ari Halberstadt */
  3.  
  4. /*    Application to demonstrate the use of the patch library. First, a
  5.     dialog is displayed without patching any traps. Then, a second dialog
  6.     is displayed with the patch SetDialogItemText patched. The patch
  7.     replaces the text passed to SetDialogItemText with a string pointed
  8.     to by the global variable gPatchText. */
  9.  
  10. /*    941130 aih updated for universal headers
  11.     940418 aih created */
  12.  
  13. #include <Dialogs.h>
  14. #include <Events.h>
  15. #include <Fonts.h>
  16. #include <Memory.h>
  17. #include <Menus.h>
  18. #include <OSEvents.h>
  19. #include <QuickDraw.h>
  20. #include <Traps.h>
  21. #include "PatchLib.h"
  22.  
  23. /*----------------------------------------------------------------------------*/
  24. /* patch information */
  25. /*----------------------------------------------------------------------------*/
  26.  
  27. static PatchType gPatchSetDialogItemText;
  28.  
  29. typedef UniversalProcPtr SetDialogItemTextUPP;
  30.  
  31. #if USESROUTINEDESCRIPTORS
  32.  
  33.     enum {
  34.         uppSetDialogItemTextProcInfo = kPascalStackBased |
  35.             RESULT_SIZE(kNoByteCode) |
  36.             STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Handle))) |
  37.             STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const unsigned char *)))
  38.     };
  39.     
  40.     #define NewSetDialogItemTextProc(userRoutine) \
  41.             (SetDialogItemTextUPP) NewRoutineDescriptor((ProcPtr) userRoutine, \
  42.                 uppSetDialogItemTextProcInfo, GetCurrentISA())
  43.  
  44.  
  45.     #define CallSetDialogItemTextProc(patch, item, text) \
  46.         CallUniversalProc(patch->trap, uppSetDialogItemTextProcInfo, item, text)
  47.  
  48. #else /* USESROUTINEDESCRIPTORS */
  49.  
  50.     #define NewSetDialogItemTextProc(userRoutine) ((SetDialogItemTextUPP) userRoutine)
  51.     #define CallSetDialogItemTextProc(patch, item, text) ((void) (0))
  52.     
  53. #endif /* USESROUTINEDESCRIPTORS */
  54.  
  55. /*----------------------------------------------------------------------------*/
  56. /* global definitions and declarations */
  57. /*----------------------------------------------------------------------------*/
  58.  
  59. /* the test dialog */
  60. #define rDialog (128)
  61.  
  62. /* dialog items */
  63. enum {
  64.     iOK = 1,
  65.     iTextTitle,
  66.     iTextNoPatch,
  67.     iTextPatch1,
  68.     iTextPatch2,
  69.     iTextPatch3,
  70.     iLast
  71. };
  72.  
  73. /* the text to set when the patch is executed */
  74. static const unsigned char *gPatchText;
  75.  
  76. /*----------------------------------------------------------------------------*/
  77. /* standard Macintosh initializations */
  78. /*----------------------------------------------------------------------------*/
  79.  
  80. /* initialize application heap */
  81. static void HeapInit(long stack, short masters)
  82. {
  83.     SetApplLimit(GetApplLimit() - stack);
  84.     MaxApplZone();
  85.     while (masters-- > 0)
  86.         MoreMasters();
  87. }
  88.  
  89. /* initialize managers */
  90. static void ManagersInit(void)
  91. {
  92.     EventRecord event;
  93.     short i;
  94.     
  95.     /* standard initializations */
  96.     InitGraf((Ptr) &qd.thePort);
  97.     InitFonts();
  98.     InitWindows();
  99.     InitMenus();
  100.     TEInit();
  101.     InitDialogs(0);
  102.     FlushEvents(everyEvent, 0);
  103.     InitCursor();
  104.     
  105.     /* so first window will be frontmost */
  106.     for (i = 0; i < 4; i++)
  107.         EventAvail(everyEvent, &event);
  108. }
  109.  
  110. /*----------------------------------------------------------------------------*/
  111. /* the patch */
  112. /*----------------------------------------------------------------------------*/
  113.  
  114. /* subsititute some global string for whatever string is passed in */
  115. static pascal void PatchSetDialogItemText(Handle hndl, const unsigned char *text)
  116. {
  117.     PATCH_ENTER();
  118.     text = gPatchText;
  119.     #if USESROUTINEDESCRIPTORS
  120.         CallSetDialogItemTextProc(gPatchSetDialogItemText, hndl, text);
  121.     #endif
  122.     PATCH_RETURN(gPatchSetDialogItemText);
  123. }
  124.  
  125. /*----------------------------------------------------------------------------*/
  126. /* run the dialog */
  127. /*----------------------------------------------------------------------------*/
  128.  
  129. /* exit on nil pointer */
  130. static void FailNIL(void *p, const unsigned char *msg)
  131. {
  132.     if (! p) {
  133.         DebugStr(msg);
  134.         ExitToShell();
  135.     }
  136. }
  137.  
  138. /* create the patch */
  139. static PatchType PatchCreate(void)
  140. {
  141.     static SetDialogItemTextUPP uppSetDialogItemText;
  142.     PatchType patch;
  143.     
  144.     if (! uppSetDialogItemText) {
  145.         uppSetDialogItemText = NewSetDialogItemTextProc(PatchSetDialogItemText);
  146.         FailNIL(uppSetDialogItemText, (StringPtr) "\p nil uppSetDialogItemText");
  147.     }
  148.     patch = PatchBegin(uppSetDialogItemText, _SetDialogItemText);
  149.     FailNIL(patch, (StringPtr) "\p nil patch");
  150.     return(patch);
  151. }
  152.     
  153. /* create the dialog */
  154. static DialogPtr CreateDialog(short id)
  155. {
  156.     DialogPtr dlg;
  157.     
  158.     dlg = GetNewDialog(id, NULL, (WindowPtr) -1);
  159.     FailNIL(dlg, (StringPtr) "\p nil dialog");
  160.     return(dlg);
  161. }
  162.  
  163. /* set up the dialog */
  164. static void SetupDialog(DialogPtr dlg, Boolean patch)
  165. {
  166.     /* some strings to use in patches */
  167.     const unsigned char *textStrings[] = {
  168.         (StringPtr) "\p There isn't a patch in sight!",
  169.         (StringPtr) "\p It's great to have a working patch!",
  170.         (StringPtr) "\p This patch never made it to beta.",
  171.         (StringPtr) "\p Thou Shalt Not Patch Unless Thou Hath A Flat.",
  172.     };
  173.     Handle text;        /* handle to text item */
  174.     Rect box;            /* rectangle containing dialog item */
  175.     short type;            /* type of dialog item */
  176.     short item;            /* item in dialog */
  177.     short textIndex;    /* index to text strings */
  178.  
  179.     /* temporarily remove patch */
  180.     if (patch)
  181.         PatchRemove(gPatchSetDialogItemText);
  182.  
  183.     /* set title and first unpatched text string */
  184.     GetDialogItem(dlg, iTextTitle, &type, &text, &box);
  185.     if (patch)
  186.         SetDialogItemText(text, (StringPtr) "\p Running Dialog And Patching SetDialogItemText");
  187.     else
  188.         SetDialogItemText(text, (StringPtr) "\p Running Dialog Without Patching SetDialogItemText");
  189.     GetDialogItem(dlg, iTextNoPatch, &type, &text, &box);
  190.     SetDialogItemText(text, textStrings[0]);
  191.     
  192.     /* reinstall patch */
  193.     if (patch)
  194.         PatchInstall(gPatchSetDialogItemText);
  195.  
  196.     /* set strings in the dialog */
  197.     textIndex = 1;
  198.     for (item = iTextNoPatch + 1; item < iLast; item++) {
  199.         /*    Even though we're always passing the same string to SetDialogItemText,
  200.             the patch will use the string pointed to by gPatchText. */
  201.         gPatchText = textStrings[textIndex++];
  202.         GetDialogItem(dlg, item, &type, &text, &box);
  203.         SetDialogItemText(text, textStrings[0]);
  204.     }
  205. }
  206.  
  207. /* create and run the dialog */
  208. static void Run(Boolean patch)
  209. {
  210.     DialogPtr dlg;
  211.     short item;
  212.     
  213.     /* create patch and dialog */
  214.     if (patch)
  215.         gPatchSetDialogItemText = PatchCreate();
  216.     dlg = CreateDialog(rDialog);
  217.     SetupDialog(dlg, patch);
  218.  
  219.     /* wait until user hits an enabled item */
  220.     ModalDialog(NULL, &item);
  221.     
  222.     /* cleanup */
  223.     DisposeDialog(dlg);
  224.     if (patch) {
  225.         PatchEnd(gPatchSetDialogItemText);
  226.         gPatchSetDialogItemText = NULL;
  227.     }
  228. }
  229.  
  230. void main(void)
  231. {
  232.     HeapInit(0, 4);
  233.     ManagersInit();
  234.     Run(false);
  235.     Run(true);
  236. }
  237.