bltpatch.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:34k
源码类别:

Symbian

开发平台:

C/C++

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