⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bltpatch.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			index = 0;
			newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SendBehindPatch;
			newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
		}
		NSetTrapAddress((UniversalProcPtr) newdesc, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
	}



	
	gBlitInfo.theMenuIsDown = false;
	gBlitInfo.thisApplicationIsFrontmost = true;
	gBlitInfo.clientPSN.highLongOfPSN = 0;
	gBlitInfo.clientPSN.lowLongOfPSN = 0;
	gBlitInfo.MenuUpCallback = nil;
	gBlitInfo.VisRgnChangedCallback = nil;
	for ( i = 0; i < kMaxMenuRects; i++ )
	{
		gBlitInfo.theMenuRects[i].left = 0;
		gBlitInfo.theMenuRects[i].top = 0;
		gBlitInfo.theMenuRects[i].right = 0;
		gBlitInfo.theMenuRects[i].bottom = 0;
	}
	
	// restore to original heap
	SetZone(theZone);
}


pascal void UnpatchBlitSupport( void )
{

	if (!gInterruptBlitPatchesInstalled) return;
	
	NSetTrapAddress(gOriginal_CopyBits, _CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_MenuSelect, _MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_PopupMenuSelect, _PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_MoveWindow, _MoveWindow, (_MoveWindow & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_WaitNextEvent, _WaitNextEvent, (_WaitNextEvent & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_CloseWindow, _CloseWindow, (_CloseWindow & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_SelectWindow, _SelectWindow, (_SelectWindow & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_PaintBehind, _PaintBehind, (_PaintBehind & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_BringToFront, _BringToFront, (_BringToFront & 0x0800) ? ToolTrap : OSTrap);
	NSetTrapAddress(gOriginal_SendBehind, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);

	gInterruptBlitPatchesInstalled = FALSE;
}



pascal void my_CopyBitsPatch(long param1, long param2, long param3, long param4, short param5, long param6)
{
	int i;
	
	if ( gBlitInfo.theMenuIsDown )
	{
		Rect r = *(Rect*)param3; // source rect
		PixMap* pmp = (PixMap*)param1; // source pixmap
		
// I THINK that if it's blitting FROM anywhere with a non-zero y coordinate,
// that it's sucking it from the screen. How safe is this assumption?

// I further think that if it's blitting TO a location (0,0) with the same
// width and height as the "from" rectangle, that it's definitely saving
// the screen beneath where it's gonna put the menu.

		Rect srcR = *(Rect*)param3;
		Rect dstR = *(Rect*)param4;
		
		if ( srcR.top > 0 && dstR.left == 0 && dstR.top == 0 && dstR.right == (srcR.right - srcR.left) && dstR.bottom == (srcR.bottom - srcR.top) )
		{
			
			// Basically, if it's blitting FROM a non-zero y coordinate then
			// it's pulling it from the screen. So if that's the case then add
			// to this list of rectangles.
			
			Boolean bDealtWith = false;
			
			// OK, first, ensure that this rectangle isn't totally enclosed by
			// an already-existing rectangle. If so we don't need to remember THIS
			// one.
			
			for ( i = 0; i < kMaxMenuRects; i++ )
			{
				if ( gBlitInfo.theMenuRects[i].left <= srcR.left &&
					gBlitInfo.theMenuRects[i].top <= srcR.top &&
					gBlitInfo.theMenuRects[i].right >= srcR.right &&
					gBlitInfo.theMenuRects[i].bottom >= srcR.bottom )
				{
					bDealtWith = true;
				}
			}
			
			i = 0;
			while ( !bDealtWith )
			{
				if ( gBlitInfo.theMenuRects[i].left == 0 &&
					gBlitInfo.theMenuRects[i].top == 0 &&
					gBlitInfo.theMenuRects[i].right == 0 &&
					gBlitInfo.theMenuRects[i].bottom == 0 )
				{
					bDealtWith = true;
					gBlitInfo.theMenuRects[i] = srcR;
				}
				
				i++;
				if ( i >= kMaxMenuRects ) bDealtWith = true;
			}
		}

		r = *(Rect*)param4; // destination rect
		pmp = (PixMap*)param2;
	}
	CALL_SIX_PARAMETER_UPP( gOriginal_CopyBits, upp_CopyBitsProcInfo, param1, param2, param3, param4, param5, param6);

	// Now check to see if it's blitting BACK TO the screen -- ie, a menu is going
	// away. If it equals one of the menu rectangles that's currently saved and
	// remove it from the list if so.
	
	if ( gBlitInfo.theMenuIsDown )
	{
		Rect dstR = *(Rect*)param4;
		for ( i = 0; i < kMaxMenuRects; i++ )
		{
			if ( gBlitInfo.theMenuRects[i].left != 0 ||
				gBlitInfo.theMenuRects[i].top != 0 ||
				gBlitInfo.theMenuRects[i].right != 0 ||
				gBlitInfo.theMenuRects[i].bottom != 0 )
			{
				if ( dstR.left == gBlitInfo.theMenuRects[i].left &&
					dstR.top == gBlitInfo.theMenuRects[i].top &&
					dstR.right == gBlitInfo.theMenuRects[i].right &&
					dstR.bottom == gBlitInfo.theMenuRects[i].bottom )
				{
					// Hmmm, so it directly matches...
					gBlitInfo.theMenuRects[i].left = 0;
					gBlitInfo.theMenuRects[i].top = 0;
					gBlitInfo.theMenuRects[i].right = 0;
					gBlitInfo.theMenuRects[i].bottom = 0;
					if ( gBlitInfo.MenuUpCallback != nil )
					{
					    // call back that callback, passing in that surface object
					    ((MenuCallbackProc)gBlitInfo.MenuUpCallback)( &dstR );
					}
				}
			}
		}
	}
}

pascal long my_MenuSelectPatch(long param1)
{
	long result;
	int i;

	gBlitInfo.theMenuIsDown = true;
	for ( i = 0; i < kMaxMenuRects; i++ )
	{
		gBlitInfo.theMenuRects[i].left = 0;
		gBlitInfo.theMenuRects[i].top = 0;
		gBlitInfo.theMenuRects[i].right = 0;
		gBlitInfo.theMenuRects[i].bottom = 0;
	}
	
	result = CALL_ONE_PARAMETER_UPP( gOriginal_MenuSelect, upp_MenuSelectProcInfo, param1);
	
	for ( i = 0; i < kMaxMenuRects; i++ )
	{
		gBlitInfo.theMenuRects[i].left = 0;
		gBlitInfo.theMenuRects[i].top = 0;
		gBlitInfo.theMenuRects[i].right = 0;
		gBlitInfo.theMenuRects[i].bottom = 0;
	}
	gBlitInfo.theMenuIsDown = false;
	return result;
}

pascal long my_PopupMenuSelectPatch(long param1, short param2, short param3, short param4)
{
	long result;
	int i;

	gBlitInfo.theMenuIsDown = true;
	for ( i = 0; i < kMaxMenuRects; i++ )
	{
		gBlitInfo.theMenuRects[i].left = 0;
		gBlitInfo.theMenuRects[i].top = 0;
		gBlitInfo.theMenuRects[i].right = 0;
		gBlitInfo.theMenuRects[i].bottom = 0;
	}
	
	result = CALL_FOUR_PARAMETER_UPP( gOriginal_PopupMenuSelect, upp_PopupMenuSelectProcInfo, param1, param2, param3, param4);
	
	for ( i = 0; i < kMaxMenuRects; i++ )
	{
		gBlitInfo.theMenuRects[i].left = 0;
		gBlitInfo.theMenuRects[i].top = 0;
		gBlitInfo.theMenuRects[i].right = 0;
		gBlitInfo.theMenuRects[i].bottom = 0;
	}
	gBlitInfo.theMenuIsDown = false;

	return result;
}

pascal void my_MoveWindowPatch(long param1, short param2, short param3, Boolean param4)
{
	Boolean sameProcess = false;
	ProcessSerialNumber currentPSN;
	
	GetCurrentProcess( &currentPSN );
	SameProcess( &currentPSN, &gBlitInfo.clientPSN, &sameProcess );
	if ( sameProcess && gBlitInfo.VisRgnChangedCallback )
	{
		((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_FOUR_PARAMETER_UPP( gOriginal_MoveWindow, upp_MoveWindowProcInfo, param1, param2, param3, param4);
}

pascal Boolean my_WaitNextEventPatch(short param1, long param2, long param3, long param4)
{
	Boolean result;
	
	BOOL bEventFilterAdjustedToSeeOSEvents = FALSE;
	
	if (!(param1 & osMask))
	{
		bEventFilterAdjustedToSeeOSEvents = TRUE;
		param1 |= osMask;
	}
	
	result = CALL_FOUR_PARAMETER_UPP( gOriginal_WaitNextEvent, upp_WaitNextEventProcInfo, param1, param2, param3, param4);
	
	BOOL bProcessedOSEvt = FALSE;
	{
	    EventRecord* event = (EventRecord*)param2;
	    if ( event->what == osEvt )
	    {
		bProcessedOSEvt = TRUE;
		if ( event->message & 0x01000000 ) // suspend/resume
		{
		    if ( event->message & 0x00000001 ) // resume
		    {
			gBlitInfo.thisApplicationIsFrontmost = true;
		    }
		    else
		    {
			gBlitInfo.thisApplicationIsFrontmost = false;
		    }
		}
		if (bEventFilterAdjustedToSeeOSEvents)
		{
		    // XXXbobclark: since they deliberately filtered out OS events, we won't
		    // give them any.
		    result = false;
		    event->what = nullEvent;
		    // XXXbobclark: I think that's the only field in the event record that I need to worry about.
		}
	    }
	    if ( event->what == updateEvt || event->what == activateEvt )
	    {
		gRecentUpdateEvent = true;
	    }
	}
	
	return result;
}

pascal void my_CloseWindowPatch(long param1)
{
	if ( gBlitInfo.VisRgnChangedCallback )
	{
	    ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_ONE_PARAMETER_UPP( gOriginal_CloseWindow, upp_CloseWindowProcInfo, param1);
}

pascal void my_SelectWindowPatch(long param1)
{
	if ( gBlitInfo.VisRgnChangedCallback )
	{
	    ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_ONE_PARAMETER_UPP( gOriginal_SelectWindow, upp_SelectWindowProcInfo, param1);
}

pascal void my_BringToFrontPatch(long param1)
{
	if ( gBlitInfo.VisRgnChangedCallback )
	{
	    ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_ONE_PARAMETER_UPP( gOriginal_BringToFront, upp_BringToFrontProcInfo, param1);
}

pascal void my_SendBehindPatch(long param1, long param2)
{
	if ( gBlitInfo.VisRgnChangedCallback )
	{
	    ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_TWO_PARAMETER_UPP( gOriginal_SendBehind, upp_SendBehindProcInfo, param1, param2);
}

pascal void my_PaintBehindPatch(long param1, long param2)
{
	if ( gBlitInfo.VisRgnChangedCallback )
	{
	    ((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
	}
	CALL_TWO_PARAMETER_UPP( gOriginal_PaintBehind, upp_PaintBehindProcInfo, param1, param2);
}


#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -