bltpatch.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:34k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: bltpatch.cpp,v 1.1.1.1.42.1 2004/07/09 01:59:02 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #if TARGET_CPU_68K && !TARGET_RT_MAC_CFM
  50. #error Sorry Can't do that
  51. #endif
  52. #include <MixedMode.h>
  53. #include <Appearance.h>
  54. #include <SpeechSynthesis.h>
  55. #include <Traps.h>
  56. #include "macintosh.h"
  57. #include "bltpatch.h"
  58. //#include "../dcondev/dcon.h"
  59. /*
  60. xxxbobclark
  61. Reasons for patches:
  62. Blitting at interrupt time and avoiding menus accounts for the
  63. following trap patches:
  64. - CopyBits (to see where the menus are)
  65. - MenuSelect (to see when the menu is down)
  66. - PopupMenuSelect
  67. Seeing when we switch out of the application accounts for the
  68. following trap patch:
  69. - WaitNextEvent (to watch for osEvt switching in/out)
  70. Ensuring that the current visRgn is what we're using
  71. for the visRgn -- ie, things where we wait for a system-time
  72. call to update our version of the visRgn...
  73. - MoveWindow
  74. - CloseWindow
  75. - SelectWindow
  76. - PaintBehind (like when the app quits)
  77. - BringToFront (deprecated because SelectWindow is better but
  78.   apparently the fine folks at Netscape didn't hear that.)
  79. - SendBehind (also used by Netscape and apparently nobody else)
  80. Note: I think that with the PaintBehind trap being patched, it
  81. makes the CloseWindow patch redundant. At least until code
  82. is added that blits over the last "XORed" part of the dragged
  83. window frame.
  84. Note: Menus popped up from the Control Strip are being blasted
  85. over. ControlStripDispatch is a likely candidate to patch to
  86. turn on the theMenuIsDown boolean, but I'm gonna
  87. procrastinate on that.
  88. */
  89. #ifdef _CARBON
  90. BlittingPatchInfoStruct gBlitInfo;
  91. bool gRecentUpdateEvent = false;
  92. BOOL gInterruptBlitPatchesInstalled = FALSE;
  93. pascal void PatchBlitSupport(void)
  94. {
  95. }
  96. pascal void UnpatchBlitSupport( void )
  97. {
  98. }
  99. #else
  100. // enums for routinedescriptor
  101. enum {
  102. upp_CopyBitsProcInfo = kPascalStackBased
  103. | STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  104. | STACK_ROUTINE_PARAMETER(2,kFourByteCode)
  105. | STACK_ROUTINE_PARAMETER(3,kFourByteCode)
  106. | STACK_ROUTINE_PARAMETER(4,kFourByteCode)
  107. | STACK_ROUTINE_PARAMETER(5,kTwoByteCode)
  108. | STACK_ROUTINE_PARAMETER(6,kFourByteCode),
  109. upp_MenuSelectProcInfo = kPascalStackBased
  110. | RESULT_SIZE(kFourByteCode)
  111. | STACK_ROUTINE_PARAMETER(1,kFourByteCode),
  112. upp_PopupMenuSelectProcInfo = kPascalStackBased
  113. | RESULT_SIZE(kFourByteCode)
  114. | STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  115. | STACK_ROUTINE_PARAMETER(2,kTwoByteCode)
  116. | STACK_ROUTINE_PARAMETER(3,kTwoByteCode)
  117. | STACK_ROUTINE_PARAMETER(4,kTwoByteCode),
  118. upp_MoveWindowProcInfo = kPascalStackBased
  119. | STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  120. | STACK_ROUTINE_PARAMETER(2,kTwoByteCode)
  121. | STACK_ROUTINE_PARAMETER(3,kTwoByteCode)
  122. | STACK_ROUTINE_PARAMETER(4,kOneByteCode),
  123. upp_WaitNextEventProcInfo = kPascalStackBased
  124. | RESULT_SIZE(kOneByteCode)
  125. | STACK_ROUTINE_PARAMETER(1,kTwoByteCode)
  126. | STACK_ROUTINE_PARAMETER(2,kFourByteCode)
  127. | STACK_ROUTINE_PARAMETER(3,kFourByteCode)
  128. | STACK_ROUTINE_PARAMETER(4,kFourByteCode),
  129. upp_CloseWindowProcInfo = kPascalStackBased
  130. | STACK_ROUTINE_PARAMETER(1,kFourByteCode),
  131. upp_SelectWindowProcInfo = kPascalStackBased
  132. | STACK_ROUTINE_PARAMETER(1,kFourByteCode),
  133. upp_PaintBehindProcInfo = kPascalStackBased
  134. | STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  135. | STACK_ROUTINE_PARAMETER(2,kFourByteCode),
  136. upp_BringToFrontProcInfo = kPascalStackBased
  137. | STACK_ROUTINE_PARAMETER(1,kFourByteCode),
  138. upp_SendBehindProcInfo = kPascalStackBased
  139. | STACK_ROUTINE_PARAMETER(1,kFourByteCode)
  140. | STACK_ROUTINE_PARAMETER(2,kFourByteCode),
  141. uppPatcExtraInfo
  142. };
  143. // Function Prototypes
  144. extern pascal void my_CopyBitsPatch(long param1, long param2, long param3, long param4, short param5, long param6);
  145. extern pascal long my_MenuSelectPatch(long param1);
  146. extern pascal long my_PopupMenuSelectPatch(long param1, short param2, short param3, short param4);
  147. extern pascal void my_MoveWindowPatch(long param1, short param2, short param3, Boolean param4);
  148. extern pascal Boolean my_WaitNextEventPatch(short param1, long param2, long param3, long param4);
  149. extern pascal void my_CloseWindowPatch(long param1);
  150. extern pascal void my_SelectWindowPatch(long param1);
  151. extern pascal void my_PaintBehindPatch(long param1, long param2);
  152. extern pascal void my_BringToFrontPatch(long param1);
  153. extern pascal void my_SendBehindPatch(long param1, long param2);
  154. // Globals to hold original routine descriptors
  155. RoutineDescriptorPtr gOriginal_CopyBits = nil;
  156. RoutineDescriptorPtr gOriginal_MenuSelect = nil;
  157. RoutineDescriptorPtr gOriginal_PopupMenuSelect = nil;
  158. RoutineDescriptorPtr gOriginal_MoveWindow = nil;
  159. RoutineDescriptorPtr gOriginal_WaitNextEvent = nil;
  160. RoutineDescriptorPtr gOriginal_CloseWindow = nil;
  161. RoutineDescriptorPtr gOriginal_SelectWindow = nil;
  162. RoutineDescriptorPtr gOriginal_PaintBehind = nil;
  163. RoutineDescriptorPtr gOriginal_BringToFront = nil;
  164. RoutineDescriptorPtr gOriginal_SendBehind = nil;
  165. #define kMaxMenuRects 20
  166. typedef pascal void (*MenuCallbackProc)( Rect* theRectToRestore );
  167. typedef pascal void (*VisRgnChangedCallbackProc)(void);
  168. BlittingPatchInfoStruct gBlitInfo;
  169. bool gRecentUpdateEvent = false;
  170. BOOL gInterruptBlitPatchesInstalled = FALSE;
  171. // Tell MetroWerks the procInfo for main
  172. ProcInfoType __procinfo =  kPascalStackBased;
  173. pascal void PatchBlitSupport(void)
  174. {
  175. RoutineDescriptorPtr originaldesc, newdesc, unImplimentedTrapAddr;
  176. UInt32 size;
  177. UInt16 index;
  178. THz theZone;
  179. int i;
  180. // detach ourselves
  181. //DetachResource(Get1Resource('INIT', 0));  Are we *trying* to crash?
  182.     // if the gestalt selector is installed and 
  183.     // the interruptblit bit (low bit) is clear, bail
  184.     
  185. SInt32 gestResult;
  186.     const OSType kHXCoreGestaltSelector = 'RNc';
  187.     const UINT32 kInterruptBlitBit = 0; // if lowest bit set, we blit at interrupt time
  188.     if (Gestalt(kHXCoreGestaltSelector, &gestResult) == noErr 
  189.      && (gestResult & (1L << kInterruptBlitBit)) == 0)
  190.     {
  191. gInterruptBlitPatchesInstalled = FALSE;
  192. // DebugStr("p Bypassing patch installation");
  193. return;
  194. }
  195. gInterruptBlitPatchesInstalled = TRUE;
  196. // make sure we are in the system heap
  197. theZone = GetZone();
  198. SetZone(SystemZone());
  199. unImplimentedTrapAddr = NGetTrapAddress(_Unimplemented, (_Unimplemented & 0x0800) ? ToolTrap : OSTrap);
  200. originaldesc = NGetTrapAddress(_CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
  201. if (originaldesc != unImplimentedTrapAddr) {
  202. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  203. // Trap is 68K
  204. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  205. // allocate new descriptor
  206. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  207. if (!newdesc) {
  208. return;
  209. }
  210. // set fields of routine decscriptor
  211. newdesc->goMixedModeTrap = _MixedModeMagic;
  212. newdesc->version = 7;
  213. newdesc->routineDescriptorFlags = 0;
  214. newdesc->reserved1 = 0;
  215. newdesc->reserved2 = 0;
  216. newdesc->selectorInfo = 0;
  217. newdesc->routineCount = 0;
  218. index = 0;
  219. gOriginal_CopyBits = originaldesc;
  220. newdesc->routineRecords[index].procInfo = upp_CopyBitsProcInfo;
  221. newdesc->routineRecords[index].reserved1 = 0;
  222. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  223. newdesc->routineRecords[index].routineFlags = 4;
  224. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CopyBitsPatch;
  225. newdesc->routineRecords[index].reserved2 = 0;
  226. newdesc->routineRecords[index].selector = 0;
  227. }
  228. else {
  229. // Trap is PPC
  230. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  231. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  232. if (!newdesc) {
  233. return;
  234. }
  235. BlockMoveData(originaldesc, newdesc, size);
  236. gOriginal_CopyBits = originaldesc;
  237. index = 0;
  238. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CopyBitsPatch;
  239. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  240. }
  241. NSetTrapAddress((UniversalProcPtr) newdesc, _CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
  242. }
  243. originaldesc = NGetTrapAddress(_MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
  244. if (originaldesc != unImplimentedTrapAddr) {
  245. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  246. // Trap is 68K
  247. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  248. // allocate new descriptor
  249. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  250. if (!newdesc) {
  251. return;
  252. }
  253. // set fields of routine decscriptor
  254. newdesc->goMixedModeTrap = _MixedModeMagic;
  255. newdesc->version = 7;
  256. newdesc->routineDescriptorFlags = 0;
  257. newdesc->reserved1 = 0;
  258. newdesc->reserved2 = 0;
  259. newdesc->selectorInfo = 0;
  260. newdesc->routineCount = 0;
  261. index = 0;
  262. gOriginal_MenuSelect = originaldesc;
  263. newdesc->routineRecords[index].procInfo = upp_MenuSelectProcInfo;
  264. newdesc->routineRecords[index].reserved1 = 0;
  265. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  266. newdesc->routineRecords[index].routineFlags = 4;
  267. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MenuSelectPatch;
  268. newdesc->routineRecords[index].reserved2 = 0;
  269. newdesc->routineRecords[index].selector = 0;
  270. }
  271. else {
  272. // Trap is PPC
  273. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  274. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  275. if (!newdesc) {
  276. return;
  277. }
  278. BlockMoveData(originaldesc, newdesc, size);
  279. gOriginal_MenuSelect = originaldesc;
  280. index = 0;
  281. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MenuSelectPatch;
  282. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  283. }
  284. NSetTrapAddress((UniversalProcPtr) newdesc, _MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
  285. }
  286. originaldesc = NGetTrapAddress(_PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
  287. if (originaldesc != unImplimentedTrapAddr) {
  288. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  289. // Trap is 68K
  290. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  291. // allocate new descriptor
  292. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  293. if (!newdesc) {
  294. return;
  295. }
  296. // set fields of routine decscriptor
  297. newdesc->goMixedModeTrap = _MixedModeMagic;
  298. newdesc->version = 7;
  299. newdesc->routineDescriptorFlags = 0;
  300. newdesc->reserved1 = 0;
  301. newdesc->reserved2 = 0;
  302. newdesc->selectorInfo = 0;
  303. newdesc->routineCount = 0;
  304. index = 0;
  305. gOriginal_PopupMenuSelect = originaldesc;
  306. newdesc->routineRecords[index].procInfo = upp_PopupMenuSelectProcInfo;
  307. newdesc->routineRecords[index].reserved1 = 0;
  308. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  309. newdesc->routineRecords[index].routineFlags = 4;
  310. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_PopupMenuSelectPatch;
  311. newdesc->routineRecords[index].reserved2 = 0;
  312. newdesc->routineRecords[index].selector = 0;
  313. }
  314. else {
  315. // Trap is PPC
  316. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  317. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  318. if (!newdesc) {
  319. return;
  320. }
  321. BlockMoveData(originaldesc, newdesc, size);
  322. gOriginal_PopupMenuSelect = originaldesc;
  323. index = 0;
  324. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_PopupMenuSelectPatch;
  325. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  326. }
  327. NSetTrapAddress((UniversalProcPtr) newdesc, _PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
  328. }
  329. originaldesc = NGetTrapAddress(_MoveWindow, (_MoveWindow & 0x0800) ? ToolTrap : OSTrap);
  330. if (originaldesc != unImplimentedTrapAddr) {
  331. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  332. // Trap is 68K
  333. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  334. // allocate new descriptor
  335. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  336. if (!newdesc) {
  337. return;
  338. }
  339. // set fields of routine decscriptor
  340. newdesc->goMixedModeTrap = _MixedModeMagic;
  341. newdesc->version = 7;
  342. newdesc->routineDescriptorFlags = 0;
  343. newdesc->reserved1 = 0;
  344. newdesc->reserved2 = 0;
  345. newdesc->selectorInfo = 0;
  346. newdesc->routineCount = 0;
  347. index = 0;
  348. gOriginal_MoveWindow = originaldesc;
  349. newdesc->routineRecords[index].procInfo = upp_MoveWindowProcInfo;
  350. newdesc->routineRecords[index].reserved1 = 0;
  351. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  352. newdesc->routineRecords[index].routineFlags = 4;
  353. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MoveWindowPatch;
  354. newdesc->routineRecords[index].reserved2 = 0;
  355. newdesc->routineRecords[index].selector = 0;
  356. }
  357. else {
  358. // Trap is PPC
  359. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  360. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  361. if (!newdesc) {
  362. return;
  363. }
  364. BlockMoveData(originaldesc, newdesc, size);
  365. gOriginal_MoveWindow = originaldesc;
  366. index = 0;
  367. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MoveWindowPatch;
  368. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  369. }
  370. NSetTrapAddress((UniversalProcPtr) newdesc, _MoveWindow, (_MoveWindow & 0x0800) ? ToolTrap : OSTrap);
  371. }
  372. originaldesc = NGetTrapAddress(_WaitNextEvent, (_WaitNextEvent & 0x0800) ? ToolTrap : OSTrap);
  373. if (originaldesc != unImplimentedTrapAddr) {
  374. // yeesh, forcing it to 68K! Ouchie
  375. // Trap is 68K
  376. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  377. // allocate new descriptor
  378. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  379. if (!newdesc) {
  380. return;
  381. }
  382. // set fields of routine decscriptor
  383. newdesc->goMixedModeTrap = _MixedModeMagic;
  384. newdesc->version = 7;
  385. newdesc->routineDescriptorFlags = 0;
  386. newdesc->reserved1 = 0;
  387. newdesc->reserved2 = 0;
  388. newdesc->selectorInfo = 0;
  389. newdesc->routineCount = 0;
  390. index = 0;
  391. gOriginal_WaitNextEvent = originaldesc;
  392. newdesc->routineRecords[index].procInfo = upp_WaitNextEventProcInfo;
  393. newdesc->routineRecords[index].reserved1 = 0;
  394. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  395. newdesc->routineRecords[index].routineFlags = 4;
  396. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_WaitNextEventPatch;
  397. newdesc->routineRecords[index].reserved2 = 0;
  398. newdesc->routineRecords[index].selector = 0;
  399. NSetTrapAddress((UniversalProcPtr) newdesc, _WaitNextEvent, (_WaitNextEvent & 0x0800) ? ToolTrap : OSTrap);
  400. }
  401. originaldesc = NGetTrapAddress(_CloseWindow, (_CloseWindow & 0x0800) ? ToolTrap : OSTrap);
  402. if (originaldesc != unImplimentedTrapAddr) {
  403. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  404. // Trap is 68K
  405. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  406. // allocate new descriptor
  407. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  408. if (!newdesc) {
  409. return;
  410. }
  411. // set fields of routine decscriptor
  412. newdesc->goMixedModeTrap = _MixedModeMagic;
  413. newdesc->version = 7;
  414. newdesc->routineDescriptorFlags = 0;
  415. newdesc->reserved1 = 0;
  416. newdesc->reserved2 = 0;
  417. newdesc->selectorInfo = 0;
  418. newdesc->routineCount = 0;
  419. index = 0;
  420. gOriginal_CloseWindow = originaldesc;
  421. newdesc->routineRecords[index].procInfo = upp_CloseWindowProcInfo;
  422. newdesc->routineRecords[index].reserved1 = 0;
  423. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  424. newdesc->routineRecords[index].routineFlags = 4;
  425. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CloseWindowPatch;
  426. newdesc->routineRecords[index].reserved2 = 0;
  427. newdesc->routineRecords[index].selector = 0;
  428. }
  429. else {
  430. // Trap is PPC
  431. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  432. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  433. if (!newdesc) {
  434. return;
  435. }
  436. BlockMoveData(originaldesc, newdesc, size);
  437. gOriginal_CloseWindow = originaldesc;
  438. index = 0;
  439. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CloseWindowPatch;
  440. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  441. }
  442. NSetTrapAddress((UniversalProcPtr) newdesc, _CloseWindow, (_CloseWindow & 0x0800) ? ToolTrap : OSTrap);
  443. }
  444. originaldesc = NGetTrapAddress(_SelectWindow, (_SelectWindow & 0x0800) ? ToolTrap : OSTrap);
  445. if (originaldesc != unImplimentedTrapAddr) {
  446. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  447. // Trap is 68K
  448. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  449. // allocate new descriptor
  450. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  451. if (!newdesc) {
  452. return;
  453. }
  454. // set fields of routine decscriptor
  455. newdesc->goMixedModeTrap = _MixedModeMagic;
  456. newdesc->version = 7;
  457. newdesc->routineDescriptorFlags = 0;
  458. newdesc->reserved1 = 0;
  459. newdesc->reserved2 = 0;
  460. newdesc->selectorInfo = 0;
  461. newdesc->routineCount = 0;
  462. index = 0;
  463. gOriginal_SelectWindow = originaldesc;
  464. newdesc->routineRecords[index].procInfo = upp_SelectWindowProcInfo;
  465. newdesc->routineRecords[index].reserved1 = 0;
  466. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  467. newdesc->routineRecords[index].routineFlags = 4;
  468. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SelectWindowPatch;
  469. newdesc->routineRecords[index].reserved2 = 0;
  470. newdesc->routineRecords[index].selector = 0;
  471. }
  472. else {
  473. // Trap is PPC
  474. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  475. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  476. if (!newdesc) {
  477. return;
  478. }
  479. BlockMoveData(originaldesc, newdesc, size);
  480. gOriginal_SelectWindow = originaldesc;
  481. index = 0;
  482. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SelectWindowPatch;
  483. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  484. }
  485. NSetTrapAddress((UniversalProcPtr) newdesc, _SelectWindow, (_SelectWindow & 0x0800) ? ToolTrap : OSTrap);
  486. }
  487. originaldesc = NGetTrapAddress(_PaintBehind, (_PaintBehind & 0x0800) ? ToolTrap : OSTrap);
  488. if (originaldesc != unImplimentedTrapAddr) {
  489. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  490. // Trap is 68K
  491. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  492. // allocate new descriptor
  493. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  494. if (!newdesc) {
  495. return;
  496. }
  497. // set fields of routine decscriptor
  498. newdesc->goMixedModeTrap = _MixedModeMagic;
  499. newdesc->version = 7;
  500. newdesc->routineDescriptorFlags = 0;
  501. newdesc->reserved1 = 0;
  502. newdesc->reserved2 = 0;
  503. newdesc->selectorInfo = 0;
  504. newdesc->routineCount = 0;
  505. index = 0;
  506. gOriginal_PaintBehind = originaldesc;
  507. newdesc->routineRecords[index].procInfo = upp_PaintBehindProcInfo;
  508. newdesc->routineRecords[index].reserved1 = 0;
  509. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  510. newdesc->routineRecords[index].routineFlags = 4;
  511. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_PaintBehindPatch;
  512. newdesc->routineRecords[index].reserved2 = 0;
  513. newdesc->routineRecords[index].selector = 0;
  514. }
  515. else {
  516. // Trap is PPC
  517. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  518. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  519. if (!newdesc) {
  520. return;
  521. }
  522. BlockMoveData(originaldesc, newdesc, size);
  523. gOriginal_PaintBehind = originaldesc;
  524. index = 0;
  525. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_PaintBehindPatch;
  526. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  527. }
  528. NSetTrapAddress((UniversalProcPtr) newdesc, _PaintBehind, (_PaintBehind & 0x0800) ? ToolTrap : OSTrap);
  529. }
  530. originaldesc = NGetTrapAddress(_BringToFront, (_BringToFront & 0x0800) ? ToolTrap : OSTrap);
  531. if (originaldesc != unImplimentedTrapAddr) {
  532. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  533. // Trap is 68K
  534. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  535. // allocate new descriptor
  536. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  537. if (!newdesc) {
  538. return;
  539. }
  540. // set fields of routine decscriptor
  541. newdesc->goMixedModeTrap = _MixedModeMagic;
  542. newdesc->version = 7;
  543. newdesc->routineDescriptorFlags = 0;
  544. newdesc->reserved1 = 0;
  545. newdesc->reserved2 = 0;
  546. newdesc->selectorInfo = 0;
  547. newdesc->routineCount = 0;
  548. index = 0;
  549. gOriginal_BringToFront = originaldesc;
  550. newdesc->routineRecords[index].procInfo = upp_BringToFrontProcInfo;
  551. newdesc->routineRecords[index].reserved1 = 0;
  552. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  553. newdesc->routineRecords[index].routineFlags = 4;
  554. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_BringToFrontPatch;
  555. newdesc->routineRecords[index].reserved2 = 0;
  556. newdesc->routineRecords[index].selector = 0;
  557. }
  558. else {
  559. // Trap is PPC
  560. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  561. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  562. if (!newdesc) {
  563. return;
  564. }
  565. BlockMoveData(originaldesc, newdesc, size);
  566. gOriginal_BringToFront = originaldesc;
  567. index = 0;
  568. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_BringToFrontPatch;
  569. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  570. }
  571. NSetTrapAddress((UniversalProcPtr) newdesc, _BringToFront, (_BringToFront & 0x0800) ? ToolTrap : OSTrap);
  572. }
  573. originaldesc = NGetTrapAddress(_SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
  574. if (originaldesc != unImplimentedTrapAddr) {
  575. if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
  576. // Trap is 68K
  577. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
  578. // allocate new descriptor
  579. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  580. if (!newdesc) {
  581. return;
  582. }
  583. // set fields of routine decscriptor
  584. newdesc->goMixedModeTrap = _MixedModeMagic;
  585. newdesc->version = 7;
  586. newdesc->routineDescriptorFlags = 0;
  587. newdesc->reserved1 = 0;
  588. newdesc->reserved2 = 0;
  589. newdesc->selectorInfo = 0;
  590. newdesc->routineCount = 0;
  591. index = 0;
  592. gOriginal_SendBehind = originaldesc;
  593. newdesc->routineRecords[index].procInfo = upp_SendBehindProcInfo;
  594. newdesc->routineRecords[index].reserved1 = 0;
  595. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  596. newdesc->routineRecords[index].routineFlags = 4;
  597. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SendBehindPatch;
  598. newdesc->routineRecords[index].reserved2 = 0;
  599. newdesc->routineRecords[index].selector = 0;
  600. }
  601. else {
  602. // Trap is PPC
  603. size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
  604. newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
  605. if (!newdesc) {
  606. return;
  607. }
  608. BlockMoveData(originaldesc, newdesc, size);
  609. gOriginal_SendBehind = originaldesc;
  610. index = 0;
  611. newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SendBehindPatch;
  612. newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
  613. }
  614. NSetTrapAddress((UniversalProcPtr) newdesc, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
  615. }
  616. gBlitInfo.theMenuIsDown = false;
  617. gBlitInfo.thisApplicationIsFrontmost = true;
  618. gBlitInfo.clientPSN.highLongOfPSN = 0;
  619. gBlitInfo.clientPSN.lowLongOfPSN = 0;
  620. gBlitInfo.MenuUpCallback = nil;
  621. gBlitInfo.VisRgnChangedCallback = nil;
  622. for ( i = 0; i < kMaxMenuRects; i++ )
  623. {
  624. gBlitInfo.theMenuRects[i].left = 0;
  625. gBlitInfo.theMenuRects[i].top = 0;
  626. gBlitInfo.theMenuRects[i].right = 0;
  627. gBlitInfo.theMenuRects[i].bottom = 0;
  628. }
  629. // restore to original heap
  630. SetZone(theZone);
  631. }
  632. pascal void UnpatchBlitSupport( void )
  633. {
  634. if (!gInterruptBlitPatchesInstalled) return;
  635. NSetTrapAddress(gOriginal_CopyBits, _CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
  636. NSetTrapAddress(gOriginal_MenuSelect, _MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
  637. NSetTrapAddress(gOriginal_PopupMenuSelect, _PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
  638. NSetTrapAddress(gOriginal_MoveWindow, _MoveWindow, (_MoveWindow & 0x0800) ? ToolTrap : OSTrap);
  639. NSetTrapAddress(gOriginal_WaitNextEvent, _WaitNextEvent, (_WaitNextEvent & 0x0800) ? ToolTrap : OSTrap);
  640. NSetTrapAddress(gOriginal_CloseWindow, _CloseWindow, (_CloseWindow & 0x0800) ? ToolTrap : OSTrap);
  641. NSetTrapAddress(gOriginal_SelectWindow, _SelectWindow, (_SelectWindow & 0x0800) ? ToolTrap : OSTrap);
  642. NSetTrapAddress(gOriginal_PaintBehind, _PaintBehind, (_PaintBehind & 0x0800) ? ToolTrap : OSTrap);
  643. NSetTrapAddress(gOriginal_BringToFront, _BringToFront, (_BringToFront & 0x0800) ? ToolTrap : OSTrap);
  644. NSetTrapAddress(gOriginal_SendBehind, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
  645. gInterruptBlitPatchesInstalled = FALSE;
  646. }
  647. pascal void my_CopyBitsPatch(long param1, long param2, long param3, long param4, short param5, long param6)
  648. {
  649. int i;
  650. if ( gBlitInfo.theMenuIsDown )
  651. {
  652. Rect r = *(Rect*)param3; // source rect
  653. PixMap* pmp = (PixMap*)param1; // source pixmap
  654. // I THINK that if it's blitting FROM anywhere with a non-zero y coordinate,
  655. // that it's sucking it from the screen. How safe is this assumption?
  656. // I further think that if it's blitting TO a location (0,0) with the same
  657. // width and height as the "from" rectangle, that it's definitely saving
  658. // the screen beneath where it's gonna put the menu.
  659. Rect srcR = *(Rect*)param3;
  660. Rect dstR = *(Rect*)param4;
  661. if ( srcR.top > 0 && dstR.left == 0 && dstR.top == 0 && dstR.right == (srcR.right - srcR.left) && dstR.bottom == (srcR.bottom - srcR.top) )
  662. {
  663. // Basically, if it's blitting FROM a non-zero y coordinate then
  664. // it's pulling it from the screen. So if that's the case then add
  665. // to this list of rectangles.
  666. Boolean bDealtWith = false;
  667. // OK, first, ensure that this rectangle isn't totally enclosed by
  668. // an already-existing rectangle. If so we don't need to remember THIS
  669. // one.
  670. for ( i = 0; i < kMaxMenuRects; i++ )
  671. {
  672. if ( gBlitInfo.theMenuRects[i].left <= srcR.left &&
  673. gBlitInfo.theMenuRects[i].top <= srcR.top &&
  674. gBlitInfo.theMenuRects[i].right >= srcR.right &&
  675. gBlitInfo.theMenuRects[i].bottom >= srcR.bottom )
  676. {
  677. bDealtWith = true;
  678. }
  679. }
  680. i = 0;
  681. while ( !bDealtWith )
  682. {
  683. if ( gBlitInfo.theMenuRects[i].left == 0 &&
  684. gBlitInfo.theMenuRects[i].top == 0 &&
  685. gBlitInfo.theMenuRects[i].right == 0 &&
  686. gBlitInfo.theMenuRects[i].bottom == 0 )
  687. {
  688. bDealtWith = true;
  689. gBlitInfo.theMenuRects[i] = srcR;
  690. }
  691. i++;
  692. if ( i >= kMaxMenuRects ) bDealtWith = true;
  693. }
  694. }
  695. r = *(Rect*)param4; // destination rect
  696. pmp = (PixMap*)param2;
  697. }
  698. CALL_SIX_PARAMETER_UPP( gOriginal_CopyBits, upp_CopyBitsProcInfo, param1, param2, param3, param4, param5, param6);
  699. // Now check to see if it's blitting BACK TO the screen -- ie, a menu is going
  700. // away. If it equals one of the menu rectangles that's currently saved and
  701. // remove it from the list if so.
  702. if ( gBlitInfo.theMenuIsDown )
  703. {
  704. Rect dstR = *(Rect*)param4;
  705. for ( i = 0; i < kMaxMenuRects; i++ )
  706. {
  707. if ( gBlitInfo.theMenuRects[i].left != 0 ||
  708. gBlitInfo.theMenuRects[i].top != 0 ||
  709. gBlitInfo.theMenuRects[i].right != 0 ||
  710. gBlitInfo.theMenuRects[i].bottom != 0 )
  711. {
  712. if ( dstR.left == gBlitInfo.theMenuRects[i].left &&
  713. dstR.top == gBlitInfo.theMenuRects[i].top &&
  714. dstR.right == gBlitInfo.theMenuRects[i].right &&
  715. dstR.bottom == gBlitInfo.theMenuRects[i].bottom )
  716. {
  717. // Hmmm, so it directly matches...
  718. gBlitInfo.theMenuRects[i].left = 0;
  719. gBlitInfo.theMenuRects[i].top = 0;
  720. gBlitInfo.theMenuRects[i].right = 0;
  721. gBlitInfo.theMenuRects[i].bottom = 0;
  722. if ( gBlitInfo.MenuUpCallback != nil )
  723. {
  724.     // call back that callback, passing in that surface object
  725.     ((MenuCallbackProc)gBlitInfo.MenuUpCallback)( &dstR );
  726. }
  727. }
  728. }
  729. }
  730. }
  731. }
  732. pascal long my_MenuSelectPatch(long param1)
  733. {
  734. long result;
  735. int i;
  736. gBlitInfo.theMenuIsDown = true;
  737. for ( i = 0; i < kMaxMenuRects; i++ )
  738. {
  739. gBlitInfo.theMenuRects[i].left = 0;
  740. gBlitInfo.theMenuRects[i].top = 0;
  741. gBlitInfo.theMenuRects[i].right = 0;
  742. gBlitInfo.theMenuRects[i].bottom = 0;
  743. }
  744. result = CALL_ONE_PARAMETER_UPP( gOriginal_MenuSelect, upp_MenuSelectProcInfo, param1);
  745. for ( i = 0; i < kMaxMenuRects; i++ )
  746. {
  747. gBlitInfo.theMenuRects[i].left = 0;
  748. gBlitInfo.theMenuRects[i].top = 0;
  749. gBlitInfo.theMenuRects[i].right = 0;
  750. gBlitInfo.theMenuRects[i].bottom = 0;
  751. }
  752. gBlitInfo.theMenuIsDown = false;
  753. return result;
  754. }
  755. pascal long my_PopupMenuSelectPatch(long param1, short param2, short param3, short param4)
  756. {
  757. long result;
  758. int i;
  759. gBlitInfo.theMenuIsDown = true;
  760. for ( i = 0; i < kMaxMenuRects; i++ )
  761. {
  762. gBlitInfo.theMenuRects[i].left = 0;
  763. gBlitInfo.theMenuRects[i].top = 0;
  764. gBlitInfo.theMenuRects[i].right = 0;
  765. gBlitInfo.theMenuRects[i].bottom = 0;
  766. }
  767. result = CALL_FOUR_PARAMETER_UPP( gOriginal_PopupMenuSelect, upp_PopupMenuSelectProcInfo, param1, param2, param3, param4);
  768. for ( i = 0; i < kMaxMenuRects; i++ )
  769. {
  770. gBlitInfo.theMenuRects[i].left = 0;
  771. gBlitInfo.theMenuRects[i].top = 0;
  772. gBlitInfo.theMenuRects[i].right = 0;
  773. gBlitInfo.theMenuRects[i].bottom = 0;
  774. }
  775. gBlitInfo.theMenuIsDown = false;
  776. return result;
  777. }
  778. pascal void my_MoveWindowPatch(long param1, short param2, short param3, Boolean param4)
  779. {
  780. Boolean sameProcess = false;
  781. ProcessSerialNumber currentPSN;
  782. GetCurrentProcess( &currentPSN );
  783. SameProcess( &currentPSN, &gBlitInfo.clientPSN, &sameProcess );
  784. if ( sameProcess && gBlitInfo.VisRgnChangedCallback )
  785. {
  786. ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  787. }
  788. CALL_FOUR_PARAMETER_UPP( gOriginal_MoveWindow, upp_MoveWindowProcInfo, param1, param2, param3, param4);
  789. }
  790. pascal Boolean my_WaitNextEventPatch(short param1, long param2, long param3, long param4)
  791. {
  792. Boolean result;
  793. BOOL bEventFilterAdjustedToSeeOSEvents = FALSE;
  794. if (!(param1 & osMask))
  795. {
  796. bEventFilterAdjustedToSeeOSEvents = TRUE;
  797. param1 |= osMask;
  798. }
  799. result = CALL_FOUR_PARAMETER_UPP( gOriginal_WaitNextEvent, upp_WaitNextEventProcInfo, param1, param2, param3, param4);
  800. BOOL bProcessedOSEvt = FALSE;
  801. {
  802.     EventRecord* event = (EventRecord*)param2;
  803.     if ( event->what == osEvt )
  804.     {
  805. bProcessedOSEvt = TRUE;
  806. if ( event->message & 0x01000000 ) // suspend/resume
  807. {
  808.     if ( event->message & 0x00000001 ) // resume
  809.     {
  810. gBlitInfo.thisApplicationIsFrontmost = true;
  811.     }
  812.     else
  813.     {
  814. gBlitInfo.thisApplicationIsFrontmost = false;
  815.     }
  816. }
  817. if (bEventFilterAdjustedToSeeOSEvents)
  818. {
  819.     // XXXbobclark: since they deliberately filtered out OS events, we won't
  820.     // give them any.
  821.     result = false;
  822.     event->what = nullEvent;
  823.     // XXXbobclark: I think that's the only field in the event record that I need to worry about.
  824. }
  825.     }
  826.     if ( event->what == updateEvt || event->what == activateEvt )
  827.     {
  828. gRecentUpdateEvent = true;
  829.     }
  830. }
  831. return result;
  832. }
  833. pascal void my_CloseWindowPatch(long param1)
  834. {
  835. if ( gBlitInfo.VisRgnChangedCallback )
  836. {
  837.     ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  838. }
  839. CALL_ONE_PARAMETER_UPP( gOriginal_CloseWindow, upp_CloseWindowProcInfo, param1);
  840. }
  841. pascal void my_SelectWindowPatch(long param1)
  842. {
  843. if ( gBlitInfo.VisRgnChangedCallback )
  844. {
  845.     ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  846. }
  847. CALL_ONE_PARAMETER_UPP( gOriginal_SelectWindow, upp_SelectWindowProcInfo, param1);
  848. }
  849. pascal void my_BringToFrontPatch(long param1)
  850. {
  851. if ( gBlitInfo.VisRgnChangedCallback )
  852. {
  853.     ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  854. }
  855. CALL_ONE_PARAMETER_UPP( gOriginal_BringToFront, upp_BringToFrontProcInfo, param1);
  856. }
  857. pascal void my_SendBehindPatch(long param1, long param2)
  858. {
  859. if ( gBlitInfo.VisRgnChangedCallback )
  860. {
  861.     ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  862. }
  863. CALL_TWO_PARAMETER_UPP( gOriginal_SendBehind, upp_SendBehindProcInfo, param1, param2);
  864. }
  865. pascal void my_PaintBehindPatch(long param1, long param2)
  866. {
  867. if ( gBlitInfo.VisRgnChangedCallback )
  868. {
  869.     ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
  870. }
  871. CALL_TWO_PARAMETER_UPP( gOriginal_PaintBehind, upp_PaintBehindProcInfo, param1, param2);
  872. }
  873. #endif