home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / cdity / spointer.lha / SPointer / Source.lha / Source / SPointer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-16  |  14.2 KB  |  664 lines

  1. /*
  2. **  SPointer.c  Version 39.3  (14. April 1994)
  3. **
  4. **  Ein Commodity-Programm, welches die SetPointer()-Funktion patcht,
  5. **  um den Mauszeiger in einer gewählten Auflösung darzustellen.
  6. **  Benötigt Amiga-OS 3.0 oder höher.
  7. **
  8. **  (c) Copyright 1994 Ralf Seyfarth
  9. **    Alle Rechte vorbehalten
  10. **  
  11. **  Dieses Programm ist FREEWARE, es darf frei weitergegeben werden,
  12. **  solange alle Dateien im original Zustand enthalten sind.
  13. **
  14. **  Aufruf für DICE (2.07.56R) :
  15. **
  16. **  DCC SPointer.c -o SPointer -3.0 -mi
  17. */
  18.  
  19.  
  20. #include <clib/alib_protos.h>
  21. #include <dos/dos.h>
  22. #include <exec/memory.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxbase.h>
  25. #include <intuition/intuitionbase.h>
  26. #include <intuition/pointerclass.h>
  27. #include <libraries/commodities.h>
  28. #include <workbench/startup.h>
  29. #include <workbench/workbench.h>
  30.  
  31. #define   CxBase_DECLARED
  32. #define   GfxBase_DECLARED
  33. #define   IntuitionBase_DECLARED
  34.  
  35. #include <proto/commodities.h>
  36. #include <proto/dos.h>
  37. #include <proto/exec.h>
  38. #include <proto/graphics.h>
  39. #include <proto/icon.h>
  40. #include <proto/intuition.h>
  41. #include <proto/utility.h>
  42.  
  43. #include <stdlib.h>
  44.  
  45. VOID  _main(VOID);
  46. VOID  _waitwbmsg(VOID);
  47. VOID   HandleEvent(VOID);
  48. VOID   MainLoop(VOID);
  49. BOOL   InstallWedge(VOID);
  50. VOID   RemoveWedge(VOID);
  51. struct JumpTable    *GetJumpTable(VOID);
  52. struct PointerTable *GetPTable(struct Window *, struct BitMap *, UBYTE *, UBYTE *, APTR);
  53.  
  54. __regargs VOID   AddPTable(struct PointerTable *);
  55. __regargs VOID   RemovePTable(struct PointerTable *);
  56. __regargs VOID   FreePTable(struct PointerTable *, ULONG);
  57. __regargs struct PointerTable *FindPTable(struct Window *);
  58.  
  59. __geta4 VOID (*oldSetPointer) (__A0 struct Window *, __A1 UWORD *, __D0 LONG, __D1 LONG, __D2 LONG, __D3 LONG, __A6 struct Library *);
  60. __geta4 VOID newSetPointer(__A0 struct Window *, __A1 UWORD *, __D0 LONG, __D1 LONG, __D2 LONG, __D3 LONG, __A6 struct Library *);
  61. __geta4 VOID (*oldCloseWindow) (__A0 struct Window *, __A6 struct Library *);
  62. __geta4 VOID newCloseWindow(__A0 struct Window *, __A6 struct Library *);
  63.  
  64. IMPORT LVOSetPointer;
  65. IMPORT LVOCloseWindow;
  66.  
  67. IMPORT struct GfxBase        *GfxBase;
  68. IMPORT struct IntuitionBase *IntuitionBase;
  69. IMPORT struct WBStartup        *_WBMsg;
  70.  
  71. #define WordWidth   1L
  72. #define PT_REMOVE   1L
  73. #define PT_FREEVEC  2L
  74.  
  75. struct Library *CxBase;
  76. struct MsgPort *BrokerMP;
  77.  
  78. struct LVOTable
  79. {
  80.     LONG         lt_LVO;
  81.     struct Library *lt_LibBase;
  82.     ULONG         lt_oldFunction;
  83.     ULONG         lt_newFunction;
  84. };
  85.  
  86. struct JumpTable
  87. {
  88.     struct SignalSemaphore  jt_Semaphore;
  89.     UWORD            jt_Word;
  90.     struct Task           *jt_Owner;
  91.     UBYTE             jt_Function[12];
  92. };
  93.  
  94. struct PointerTable
  95. {
  96.     struct PointerTable *pt_NextTable;
  97.     struct PointerTable *pt_PrevTable;
  98.     struct Window    *pt_Window;
  99.     struct BitMap    *pt_BitMap;
  100.     UBYTE         *pt_OldPlane0;
  101.     UBYTE         *pt_OldPlane1;
  102.     APTR          pt_Object;
  103. };
  104.  
  105. struct NewBroker NewBroker =
  106. {
  107.     NB_VERSION,
  108.     "SPointer",
  109.     "SPointer 39.3 (14.4.94)",
  110.     "Copyright © 1994 Ralf Seyfarth",
  111.     NBU_NOTIFY | NBU_UNIQUE,
  112.     0,
  113.     0,
  114.     NULL,
  115.     0
  116. };
  117.  
  118. struct LVOTable LVOArray[] =
  119. {
  120.     { &LVOSetPointer,  (struct Library *) &IntuitionBase, &oldSetPointer,  &newSetPointer  },
  121.     { &LVOCloseWindow, (struct Library *) &IntuitionBase, &oldCloseWindow, &newCloseWindow }
  122. };
  123.  
  124. struct PointerTable *FirstPTable;
  125. struct PointerTable *LastPTable;
  126.  
  127. STATIC const UBYTE VersionsTag[] = "\0$VER: SPointer 39.3 (14.4.94)";
  128.  
  129. STATIC const UBYTE JTName[]     = "« SPointer »";
  130. #define           JTNameLen        12
  131.  
  132. STATIC const UBYTE DefStr[]     = "default";
  133. STATIC const UBYTE NS1Str[]     = "140ns";
  134. STATIC const UBYTE NS7Str[]     = "70ns";
  135. STATIC const UBYTE NS3Str[]     = "35ns";
  136. STATIC const UBYTE ScrStr[]     = "screenres";
  137. STATIC const UBYTE LoStr[]     = "lores";
  138. STATIC const UBYTE HiStr[]     = "highaspect";
  139. STATIC const UBYTE ScrAStr[]     = "screenresaspect";
  140.  
  141. BOOL   PTOn = TRUE,
  142.        Wedged;
  143. CxObj *Broker;
  144. LONG  *ArgA[3],
  145.        Priority;
  146. UBYTE *KeyStr;
  147. ULONG  CxSigFlag,
  148.        XRes = POINTERXRESN_HIRES,
  149.        YRes = POINTERYRESN_HIGH;
  150.  
  151.  
  152. VOID
  153. _main(VOID)
  154. {
  155.     if (IntuitionBase->LibNode.lib_Version < 39)
  156.     _exit(RETURN_FAIL);
  157.  
  158.     if (_WBMsg)
  159.     {
  160.     struct DiskObject *DObj;
  161.  
  162.     CurrentDir(_WBMsg->sm_ArgList[0].wa_Lock);
  163.  
  164.     if (DObj = GetDiskObject(_WBMsg->sm_ArgList[0].wa_Name))
  165.     {
  166.         if (KeyStr = FindToolType(DObj->do_ToolTypes, "CX_PRIORITY"))
  167.         StrToLong(KeyStr, &Priority);
  168.  
  169.         if (KeyStr = FindToolType(DObj->do_ToolTypes, "XRES"))
  170.  
  171.         if (MatchToolValue(KeyStr, DefStr))
  172.             XRes = POINTERXRESN_DEFAULT;
  173.  
  174.         else if (MatchToolValue(KeyStr, NS1Str))
  175.             XRes = POINTERXRESN_140NS;
  176.  
  177.         else if (MatchToolValue(KeyStr, NS7Str))
  178.             XRes = POINTERXRESN_70NS;
  179.  
  180.         else if (MatchToolValue(KeyStr, NS3Str))
  181.             XRes = POINTERXRESN_35NS;
  182.  
  183.         else if (MatchToolValue(KeyStr, ScrStr))
  184.             XRes = POINTERXRESN_SCREENRES;
  185.  
  186.         else if (MatchToolValue(KeyStr, LoStr))
  187.             XRes = POINTERXRESN_LORES;
  188.  
  189.         if (KeyStr = FindToolType(DObj->do_ToolTypes, "YRES"))
  190.  
  191.         if (MatchToolValue(KeyStr, DefStr))
  192.             YRes = POINTERYRESN_DEFAULT;
  193.  
  194.         else if (MatchToolValue(KeyStr, HiStr))
  195.             YRes = POINTERYRESN_HIGHASPECT;
  196.  
  197.         else if (MatchToolValue(KeyStr, ScrStr))
  198.             YRes = POINTERYRESN_SCREENRES;
  199.  
  200.         else if (MatchToolValue(KeyStr, ScrAStr))
  201.             YRes = POINTERYRESN_SCREENRESASPECT;
  202.  
  203.         FreeDiskObject(DObj);
  204.     }
  205.     }
  206.     else
  207.     {
  208.     struct RDArgs *RDArgs;
  209.  
  210.     if (!(RDArgs = ReadArgs("CX_PRIORITY/N/K,XRES/K,YRES/K", ArgA, NULL)))
  211.     {
  212.         PrintFault(IoErr(), NULL);
  213.         _exit(RETURN_FAIL);
  214.     }
  215.  
  216.     if (ArgA[0])
  217.         Priority = *ArgA[0];
  218.  
  219.     if (ArgA[1])
  220.  
  221.         if (!Stricmp((STRPTR) ArgA[1], DefStr))
  222.         XRes = POINTERXRESN_DEFAULT;
  223.  
  224.         else if (!Stricmp((STRPTR) ArgA[1], NS1Str))
  225.         XRes = POINTERXRESN_140NS;
  226.  
  227.         else if (!Stricmp((STRPTR) ArgA[1], NS7Str))
  228.         XRes = POINTERXRESN_70NS;
  229.  
  230.         else if (!Stricmp((STRPTR) ArgA[1], NS3Str))
  231.         XRes = POINTERXRESN_35NS;
  232.  
  233.         else if (!Stricmp((STRPTR) ArgA[1], ScrStr))
  234.         XRes = POINTERXRESN_SCREENRES;
  235.  
  236.         else if (!Stricmp((STRPTR) ArgA[1], LoStr))
  237.         XRes = POINTERXRESN_LORES;
  238.  
  239.     if (ArgA[2])
  240.  
  241.         if (!Stricmp((STRPTR) ArgA[2], DefStr))
  242.         YRes = POINTERYRESN_DEFAULT;
  243.  
  244.         else if (!Stricmp((STRPTR) ArgA[2], HiStr))
  245.         YRes = POINTERYRESN_HIGHASPECT;
  246.  
  247.         else if (!Stricmp((STRPTR) ArgA[2], ScrStr))
  248.         YRes = POINTERYRESN_SCREENRES;
  249.  
  250.         else if (!Stricmp((STRPTR) ArgA[2], ScrAStr))
  251.         YRes = POINTERYRESN_SCREENRESASPECT;
  252.  
  253.     FreeArgs(RDArgs);
  254.     }
  255.  
  256.     MainLoop();
  257. }
  258.  
  259.  
  260. VOID
  261. HandleEvent(VOID)
  262. {
  263.     FOREVER
  264.     {
  265.     ULONG SigRec = Wait(SIGBREAKF_CTRL_C | CxSigFlag);
  266.  
  267.     if (SigRec & SIGBREAKF_CTRL_C)
  268.         return;
  269.  
  270.     if (SigRec & CxSigFlag)
  271.     {
  272.         CxMsg *CxMsg;
  273.  
  274.         while (CxMsg = GetMsg(BrokerMP))
  275.         {
  276.            ULONG MsgID,
  277.              MsgType;
  278.  
  279.            MsgID   = CxMsgID(CxMsg);
  280.            MsgType = CxMsgType(CxMsg);
  281.  
  282.            ReplyMsg((struct Message *) CxMsg);
  283.  
  284.            if (MsgType == CXM_COMMAND)
  285.  
  286.                switch (MsgID)
  287.                {
  288.                    case CXCMD_KILL    :
  289.                    case CXCMD_UNIQUE  : return;
  290.  
  291.                    case CXCMD_ENABLE  : PTOn = TRUE;
  292.                             ActivateCxObj(Broker, TRUE);
  293.                             break;
  294.  
  295.                    case CXCMD_DISABLE : PTOn = FALSE;
  296.                             ActivateCxObj(Broker, FALSE);
  297.                }
  298.         }
  299.     }
  300.     }
  301. }
  302.  
  303.  
  304. VOID
  305. MainLoop(VOID)
  306. {
  307.     CxMsg *CxMsg;
  308.     ULONG  ECode = RETURN_FAIL;
  309.  
  310.     if (CxBase = OpenLibrary("commodities.library", 37L))
  311.     {
  312.     if (BrokerMP = CreateMsgPort())
  313.     {
  314.         NewBroker.nb_Pri  = (BYTE) Priority;
  315.             NewBroker.nb_Port = BrokerMP;
  316.  
  317.         if (Broker = CxBroker(&NewBroker, NULL))
  318.         {
  319.         CxSigFlag = 1L << BrokerMP->mp_SigBit;
  320.  
  321.         ActivateCxObj(Broker, TRUE);
  322.  
  323.         Wedged = InstallWedge();
  324.  
  325.         do
  326.           HandleEvent();
  327.         while (FirstPTable);
  328.  
  329.         if (Wedged)
  330.             RemoveWedge();
  331.  
  332.         DeleteCxObjAll(Broker);
  333.         }
  334.  
  335.         ECode = RETURN_OK;
  336.  
  337.         while (CxMsg = GetMsg(BrokerMP))
  338.            ReplyMsg((struct Message *) CxMsg);
  339.  
  340.         DeleteMsgPort(BrokerMP);
  341.     }
  342.  
  343.     CloseLibrary(CxBase);
  344.     }
  345.  
  346.     _exit(ECode);
  347.     _waitwbmsg();
  348. }
  349.  
  350.  
  351. BOOL
  352. InstallWedge(VOID)
  353. {
  354.     struct JumpTable *JumpTable;
  355.  
  356.     ULONG *AdrPtr;
  357.     UWORD  i,
  358.        j;
  359.  
  360.     Forbid();
  361.  
  362.     if (JumpTable = GetJumpTable())
  363.      
  364.     if (AttemptSemaphore((struct SignalSemaphore *) JumpTable))
  365.     {
  366.         if (JumpTable->jt_Owner == NULL)
  367.         {
  368.         JumpTable->jt_Owner = FindTask(0);
  369.          
  370.         Disable();
  371.  
  372.         for (i = 2, j = 0; i < 12; i += 6, j++)
  373.         {
  374.             AdrPtr = (ULONG *) ((UBYTE *) JumpTable->jt_Function + i);
  375.  
  376.             (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) *AdrPtr;
  377.  
  378.             *AdrPtr = (ULONG) LVOArray[j].lt_newFunction;
  379.         }
  380.  
  381.         CacheClearU();
  382.         Enable();
  383.         }
  384.  
  385.         ReleaseSemaphore((struct SignalSemaphore *) JumpTable);
  386.     }
  387.  
  388.     Permit();
  389.     return((BOOL) JumpTable);
  390. }
  391.  
  392.  
  393. VOID
  394. RemoveWedge(VOID)
  395. {
  396.     struct JumpTable *JumpTable;
  397.  
  398.     ULONG *AdrPtr;
  399.     UWORD  i,
  400.        j;
  401.  
  402.     Forbid();
  403.  
  404.     if (JumpTable = GetJumpTable())
  405.  
  406.     if (JumpTable->jt_Owner == FindTask(0))
  407.     {
  408.         ObtainSemaphore((struct SignalSemaphore *) JumpTable);
  409.         Disable();
  410.  
  411.         for (i = 2, j = 0; i < 12; i += 6, j++)
  412.         {
  413.          AdrPtr = (ULONG *) ((UBYTE *) JumpTable->jt_Function + i);
  414.         *AdrPtr = (*((ULONG *) LVOArray[j].lt_oldFunction));
  415.         }
  416.  
  417.         CacheClearU();
  418.         Enable();
  419.  
  420.         JumpTable->jt_Owner = NULL;
  421.  
  422.         ReleaseSemaphore((struct SignalSemaphore *) JumpTable);
  423.     }
  424.  
  425.     Permit();
  426. }
  427.  
  428.  
  429. struct JumpTable *
  430. GetJumpTable(VOID)
  431. {
  432.     struct JumpTable *JumpTable;
  433.  
  434.     UBYTE *JTStr;
  435.     ULONG *AdrPtr;
  436.     UWORD *JmpIns,
  437.        i,
  438.        j;
  439.  
  440.     if (!(JumpTable = (struct JumpTable *) FindSemaphore(JTName)))
  441.  
  442.     if (JumpTable = AllocVec(sizeof(struct JumpTable), MEMF_PUBLIC | MEMF_CLEAR))
  443.  
  444.         if (JTStr = AllocVec(JTNameLen + 1, MEMF_PUBLIC | MEMF_CLEAR))
  445.         {
  446.         for (i = 0, j = 0; i < 12; i += 6, j++)
  447.         {
  448.              JmpIns = (UWORD *) ((UBYTE *) JumpTable->jt_Function + i);
  449.             *JmpIns = 0x4EF9;
  450.  
  451.              AdrPtr = (ULONG *) ((UBYTE *) JumpTable->jt_Function + i + 2);
  452.             *AdrPtr = (ULONG) SetFunction((struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)), LVOArray[j].lt_LVO, (VOID *) ((UBYTE *) JumpTable->jt_Function + i));
  453.         }
  454.  
  455.         CopyMem(JTName, JTStr, JTNameLen + 1);
  456.  
  457.         JumpTable->jt_Semaphore.ss_Link.ln_Pri  = 0;
  458.         JumpTable->jt_Semaphore.ss_Link.ln_Name = JTStr;
  459.  
  460.         AddSemaphore((struct SignalSemaphore *) JumpTable);
  461.         }
  462.         else
  463.         {
  464.         FreeVec(JumpTable);
  465.         JumpTable = NULL;
  466.         }
  467.  
  468.     return(JumpTable);
  469. }
  470.  
  471.  
  472. __regargs VOID
  473. AddPTable(struct PointerTable *PointerTable)
  474. {
  475.     if (FirstPTable)
  476.     {
  477.     LastPTable->pt_NextTable   = PointerTable;
  478.     PointerTable->pt_PrevTable = LastPTable;
  479.     }
  480.     else
  481.     {
  482.     FirstPTable           = PointerTable;
  483.     PointerTable->pt_PrevTable = NULL;
  484.     }
  485.  
  486.     LastPTable                = PointerTable;
  487.     PointerTable->pt_NextTable = NULL;
  488. }
  489.  
  490.  
  491. __regargs VOID
  492. RemovePTable(struct PointerTable *PointerTable)
  493. {
  494.     if (FirstPTable)
  495.     {
  496.     if (PointerTable->pt_PrevTable)
  497.         PointerTable->pt_PrevTable->pt_NextTable = PointerTable->pt_NextTable;
  498.     else
  499.         FirstPTable = PointerTable->pt_NextTable;
  500.  
  501.     if (PointerTable->pt_NextTable)
  502.         PointerTable->pt_NextTable->pt_PrevTable = PointerTable->pt_PrevTable;
  503.     else
  504.         LastPTable = PointerTable->pt_PrevTable;
  505.     }
  506. }
  507.  
  508.  
  509. __regargs struct PointerTable *
  510. FindPTable(struct Window *Window)
  511. {
  512.     struct PointerTable *PointerTable = FirstPTable;
  513.  
  514.     if (FirstPTable)
  515.  
  516.     do
  517.     {
  518.       if (PointerTable->pt_Window == Window)
  519.           return(PointerTable);
  520.  
  521.       PointerTable = PointerTable->pt_NextTable;
  522.     }
  523.     while (PointerTable);
  524.  
  525.     return(NULL);
  526. }
  527.  
  528.  
  529. struct PointerTable *
  530. GetPTable(struct Window *Window, struct BitMap *BitMap, UBYTE *OldPlane0, UBYTE *OldPlane1, APTR Object)
  531. {
  532.     struct PointerTable *PointerTable;
  533.  
  534.     Forbid();
  535.  
  536.     if (PointerTable = FindPTable(Window))
  537.         FreePTable(PointerTable, NULL);
  538.  
  539.     else if (PointerTable = AllocVec(sizeof(struct PointerTable), MEMF_PUBLIC | MEMF_CLEAR))
  540.     AddPTable(PointerTable);
  541.  
  542.     if (PointerTable)
  543.     {
  544.     PointerTable->pt_Window    = Window;
  545.     PointerTable->pt_BitMap    = BitMap;
  546.     PointerTable->pt_OldPlane0 = OldPlane0;
  547.     PointerTable->pt_OldPlane1 = OldPlane1;
  548.     PointerTable->pt_Object    = Object;
  549.  
  550.     Permit();
  551.     return(PointerTable);
  552.     }
  553.     else
  554.     {   Permit();
  555.     return(NULL);
  556.     }
  557. }
  558.  
  559.  
  560. __regargs VOID
  561. FreePTable(struct PointerTable *PointerTable, ULONG Flags)
  562. {
  563.     if (PointerTable)
  564.     {
  565.     if ((Flags & PT_REMOVE) == PT_REMOVE)
  566.         RemovePTable(PointerTable);
  567.  
  568.     PointerTable->pt_BitMap->Planes[0] = PointerTable->pt_OldPlane0;
  569.     PointerTable->pt_BitMap->Planes[1] = PointerTable->pt_OldPlane1;
  570.  
  571.     DisposeObject(PointerTable->pt_Object);
  572.     FreeBitMap(PointerTable->pt_BitMap);
  573.  
  574.     if ((Flags & PT_FREEVEC) == PT_FREEVEC)
  575.         FreeVec(PointerTable);
  576.     }
  577. }
  578.  
  579.  
  580. __geta4 VOID
  581. newSetPointer(__A0 struct Window *Window, __A1 UWORD *Pointer, __D0 LONG Height, __D1 LONG Width, __D2 LONG XOffset, __D3 LONG YOffset, __A6 struct Library *Base)
  582. {
  583.     struct SignalSemaphore *JT;
  584.  
  585.     if (JT = FindSemaphore(JTName))
  586.     {
  587.     BOOL OldPointer = FALSE;
  588.  
  589.     struct BitMap *BitMap;
  590.  
  591.     ObtainSemaphoreShared(JT);
  592.  
  593.     if (PTOn && (XRes != POINTERXRESN_DEFAULT || YRes != POINTERYRESN_DEFAULT))
  594.     {
  595.         if (BitMap = AllocBitMap(Width, Height, 2, BMF_INTERLEAVED | BMF_CLEAR, NULL))
  596.         {
  597.         BOOL   RemPtr    = FALSE;
  598.         UBYTE *OldPlane0 = BitMap->Planes[0],
  599.               *OldPlane1 = BitMap->Planes[1];
  600.         ULONG  Object;
  601.  
  602.         BitMap->Planes[0] = Pointer + 2;
  603.         BitMap->Planes[1] = Pointer + 3;
  604.  
  605.         if (Object = (ULONG) NewObject(NULL,
  606.                            "pointerclass",
  607.                            POINTERA_BitMap,      BitMap,
  608.                            POINTERA_XOffset,     XOffset,
  609.                            POINTERA_YOffset,     YOffset,
  610.                            POINTERA_WordWidth,   WordWidth,
  611.                            POINTERA_XResolution, XRes,
  612.                            POINTERA_YResolution, YRes,
  613.                            TAG_DONE))
  614.         {
  615.             if (GetPTable(Window, BitMap, OldPlane0, OldPlane1, (APTR) Object))
  616.             SetWindowPointer(Window, WA_Pointer, Object, TAG_DONE);
  617.             else
  618.             RemPtr = TRUE;
  619.         }
  620.         else
  621.             RemPtr = TRUE;
  622.  
  623.                 if (RemPtr)
  624.         {
  625.             OldPointer          = TRUE;
  626.             BitMap->Planes[0] = OldPlane0;
  627.             BitMap->Planes[1] = OldPlane1;
  628.  
  629.             if (Object)
  630.             DisposeObject((APTR) Object);
  631.  
  632.             FreeBitMap(BitMap);
  633.         }
  634.         }
  635.         else
  636.             OldPointer = TRUE;
  637.     }
  638.     else
  639.         OldPointer = TRUE;
  640.  
  641.     if (OldPointer)
  642.         oldSetPointer(Window, Pointer, Height, Width, XOffset, YOffset, (struct Library *) IntuitionBase);
  643.  
  644.     ReleaseSemaphore(JT);
  645.     }
  646. }
  647.  
  648.  
  649. __geta4 VOID
  650. newCloseWindow(__A0 struct Window *Window, __A6 struct Library *Base)
  651. {
  652.     struct SignalSemaphore *JT;
  653.  
  654.     if (JT = FindSemaphore(JTName))
  655.     {
  656.     ObtainSemaphoreShared(JT);
  657.     Forbid();
  658.     FreePTable(FindPTable(Window), PT_REMOVE | PT_FREEVEC);
  659.     Permit();
  660.     oldCloseWindow(Window, (struct Library *) IntuitionBase);
  661.     ReleaseSemaphore(JT);
  662.     }
  663. }
  664.