platform_win32.c

来自「betaplayer_0.096源码 tcpmp老版本」· C语言 代码 · 共 2,601 行 · 第 1/5 页

C
2,601
字号
		for (i=2;i<n;i=i*i)
			p->Pixel.BitCount <<= 1;

		if (n>16) //4,2,1 bits are grayscale (default palette required)
		{
			GetSystemPaletteEntries(DC,0,256,(PALETTEENTRY*)Palette);
			p->Pixel.Palette = Palette;
		}
	}
	else
	if (QueryPlatform(PLATFORM_CAPS) & CAPS_ONLY12BITRGB)
		DefaultRGB(&p->Pixel,GetDeviceCaps(DC,BITSPIXEL),4,4,4,1,2,1);
	else
	{
		int i;
		int RBits = 4;
		int GBits = 4;
		int BBits = 4;
		int BitCount = GetDeviceCaps(DC,BITSPIXEL);

		COLORREF Old = GetPixel(DC,0,0);
		for (i=3;i>=0;--i)
		{
			COLORREF c = SetPixel(DC,0,0,0x010101<<i);
			if (c == (COLORREF)-1)
			{
				if (BitCount > 16)
					RBits = GBits = BBits = 8;
				else
			{
					RBits = BBits = 5; GBits = 6;
				}
				break;
			}
			if (c & 0xFF)	  RBits++;
			if (c & 0xFF00)	  GBits++;
			if (c & 0xFF0000) BBits++;
		}
		SetPixel(DC,0,0,Old);

		DefaultRGB(&p->Pixel,BitCount,RBits,GBits,BBits,0,0,0);
	}

	ReleaseDC(0,DC);
}

void* PhyMemAlloc(int Length,phymemblock* Blocks,int* BlockCount)
{
	void* p = NULL;

#if defined(_WIN32_WCE)
	if (*BlockCount>=1)
	{
		int n,Pos;
		int Count = 0;

		Length = (Length + PageSize-1) & ~(PageSize-1);

		if (FuncAllocPhysMem && FuncFreePhysMem && FuncVirtualCopy)
		{
			// try allocate in one continous block
			Blocks[0].Private = FuncAllocPhysMem(Length,PAGE_READWRITE,PageSize-1,0,&Blocks[0].Addr);
			if (Blocks[0].Private)
			{
				Blocks[0].Length = Length;
				Count = 1;
			}

			/* not worth it. allocphysmem is buggy anyway. won't be able to allocate per one pagesize

			if (!Count && *BlockCount>1)
			{
				int Left = Length;
				int BlockMax;
				int BlockSize = (Left+PageSize-1) & ~(PageSize-1);

				// allocate in separate blocks
			
				while (Count < *BlockCount && BlockSize > 0)
				{
					Blocks[Count].Private = FuncAllocPhysMem(BlockSize,PAGE_READWRITE,PageSize-1,0,&Blocks[Count].Addr);
					if (Blocks[Count].Private)
					{
						Blocks[Count].Length = BlockSize;
						++Count;
						Left -= BlockSize;
						BlockMax = (Left+PageSize-1) & ~(PageSize-1);
						if (BlockSize > BlockMax)
							BlockSize = BlockMax;
					}
					else
					if (BlockSize > PageSize*8)
						BlockSize = (BlockSize/2+PageSize-1) & ~(PageSize-1);
					else
						BlockSize -= PageSize;
				}

				if (Left>0)
				{
					for (n=0;n<Count;++n)
						FuncFreePhysMem(Blocks[n].Private);
					Count = 0;
				}
			}
			*/

			if (Count)
			{
				p = VirtualAlloc(NULL,Length,MEM_RESERVE,PAGE_READWRITE);

				if (p)
				{
					Pos = 0;
					for (n=0;n<Count;++n)
					{
						if (!FuncVirtualCopy((char*)p+Pos,(LPVOID)(Blocks[n].Addr >> 8),Blocks[n].Length, PAGE_READWRITE | PAGE_PHYSICAL))
							break;
						Pos += Blocks[n].Length;
					}
				
					if (n!=Count)
					{
						VirtualFree(p,0,MEM_RELEASE);
						p = NULL;
					}
				}

				if (!p)
				{
					for (n=0;n<Count;++n)
						FuncFreePhysMem(Blocks[n].Private);
					Count = 0;
				}
			}
		}
		
		if (!p && FuncLockPages && FuncUnlockPages)
		{
			int h=1;
			do
			{
				p = VirtualAlloc(NULL,Length,MEM_COMMIT,PAGE_READWRITE);
			}
			while (!p && NodeHibernate(h--));

			if (p)
			{
				int Pages = Length / PageSize;
				DWORD* PFN = (DWORD*) alloca(sizeof(DWORD)*Pages);

				if (FuncLockPages(p,Length,PFN,LOCKFLAG_WRITE))
				{
					DWORD Last = (DWORD)-1;
					for (n=0;n<Pages;++n)
					{
						if (PFN[n] != Last)
						{
							if (Count >= *BlockCount)
							{
								Count = 0;
								break;
							}

							Blocks[Count].Addr = PFN[n];
							Blocks[Count].Length = PageSize;
							Blocks[Count].Private = NULL;
							++Count;
						}
						else
							Blocks[Count-1].Length += PageSize;

						Last = PFN[n] + PageSize;
					}

					if (!Count)
						FuncUnlockPages(p,Length);
				}
				
				if (!Count)
				{
					VirtualFree(p,0,MEM_RELEASE);
					p = NULL;
				}
			}
		}

#ifdef ARM
		if (p && FuncVirtualSetAttributes && (QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_XSCALE))
			FuncVirtualSetAttributes(p,Length,TBL_CACHE|TBL_BUFFER,TBL_CACHE|TBL_BUFFER,NULL);
#endif

		*BlockCount = Count;
	}
#endif

	return p;
}

void PhyMemFree(void* p,phymemblock* Blocks,int BlockCount)
{
#if defined(_WIN32_WCE)
	if (p)
	{
		int n;

		if (FuncLockPages && FuncUnlockPages)
		{
			int Size = 0;
			for (n=0;n<BlockCount;++n)
			{
				if (Blocks[n].Private)
					break;
				Size += Blocks[n].Length;
			}
			if (Size)
				FuncUnlockPages(p,Size);
		}

		VirtualFree(p,0,MEM_RELEASE);

		if (FuncAllocPhysMem && FuncFreePhysMem && FuncVirtualCopy)
			for (n=0;n<BlockCount;++n)
				if (Blocks[n].Private)
					FuncFreePhysMem(Blocks[n].Private);
	}
#endif
}

void* PhyMemBeginEx(phymemblock* Blocks,int BlockCount,bool_t Cached)
{
#if defined(_WIN32_WCE)
	if (FuncVirtualCopy && Blocks && BlockCount)
	{
		int n;
		int Mode;
		phymem* p;
		for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
			if (p->BlockCount == BlockCount && p->Length == Blocks[0].Length && p->Phy == Blocks[0].Addr)
			{
				for (n=1;n<BlockCount;++n)
					if (p->Blocks[n].Addr != Blocks[n].Addr || p->Blocks[n].Length != Blocks[n].Length)
						break;

				if (n==BlockCount)
				{
					++p->RefCount;
					return p->Virt;
				}
			}

		if (BlockCount==1)
			return PhyMemBegin(Blocks[0].Addr,Blocks[0].Length,Cached);

		for (Mode=0;Mode<2;++Mode)
			for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
			{
				if (Mode && !p->RefCount && p->Length)
				{
					Free(p->Blocks);
					VirtualFree(p->Virt,0,MEM_RELEASE);
					memset(p,0,sizeof(phymem));
				}

				if (!p->Length)
				{
					p->Blocks = (phymemblock*) Alloc(sizeof(phymemblock)*BlockCount);
					if (p->Blocks)
					{
						int Size = 0;
						for (n=0;n<BlockCount;++n)
							Size += Blocks[n].Length;

						p->BlockCount = BlockCount;
						p->Virt = (char*) VirtualAlloc(0, Size, MEM_RESERVE, PAGE_NOACCESS);
						if (p->Virt)
						{
							int Mode = PAGE_READWRITE | PAGE_PHYSICAL;
							char* Virt = p->Virt;

							if (!Cached)
								Mode |= PAGE_NOCACHE;

							for (n=0;n<BlockCount;++n)
							{
								if (!FuncVirtualCopy(Virt,(LPVOID)(Blocks[n].Addr >> 8), Blocks[n].Length,Mode))
									break;

								p->Blocks[n].Addr = Blocks[n].Addr;
								p->Blocks[n].Length = Blocks[n].Length;
								Virt += Blocks[n].Length;
							}

							if (n==BlockCount)
							{
								p->RefCount = 1;
								p->Phy = Blocks[0].Addr;
								p->Length = Blocks[0].Length;
								p->BlockCount = BlockCount;

#ifdef ARM
								if (Cached && FuncVirtualSetAttributes && (QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_XSCALE))
									FuncVirtualSetAttributes(p->Virt,Size,TBL_CACHE|TBL_BUFFER,TBL_CACHE|TBL_BUFFER,NULL);
#endif
								return p->Virt;
							}

							VirtualFree(p->Virt,0,MEM_RELEASE);
						}
						Free(p->Blocks);
					}

					memset(p,0,sizeof(phymem));
					return NULL;
				}
			}
	}	
#endif
	return NULL;
}

void* PhyMemBegin(uint32_t Phy,uint32_t Length,bool_t Cached)
{
#if defined(_WIN32_WCE)
	if (FuncVirtualCopy && Phy && Length)
	{
		int Mode;
		phymem* p;
		for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
			if (p->Phy <= Phy && p->Phy+p->Length >= Phy+Length)
			{
				++p->RefCount;
				return p->Virt + (Phy - p->Phy);
			}

		for (Mode=0;Mode<2;++Mode)
			for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
			{
				if (Mode && !p->RefCount && p->Length)
				{
					Free(p->Blocks);
					VirtualFree(p->Virt,0,MEM_RELEASE);
					memset(p,0,sizeof(phymem));
				}

				if (!p->Length)
				{
					int Align = Phy & 4095;
					Phy -= Align;
					Length = (Length + Align + 4095) & ~4095;
					p->Virt = (char*) VirtualAlloc(0, Length, MEM_RESERVE, PAGE_NOACCESS);
					if (p->Virt)
					{
						int Mode = PAGE_READWRITE | PAGE_PHYSICAL;
						if (!Cached)
							Mode |= PAGE_NOCACHE;

						if (FuncVirtualCopy(p->Virt,(LPVOID)(Phy >> 8), Length, Mode))
						{
							p->RefCount = 1;
							p->Phy = Phy;
							p->Length = Length;
							p->BlockCount = 1;

#ifdef ARM
							if (Cached && FuncVirtualSetAttributes && (QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_XSCALE))
								FuncVirtualSetAttributes(p->Virt,Length,TBL_CACHE|TBL_BUFFER,TBL_CACHE|TBL_BUFFER,NULL);
#endif
							return p->Virt + Align;
						}
						VirtualFree(p->Virt,0,MEM_RELEASE);
					}
					return NULL;
				}
			}
	}	
#endif
	return NULL;
}

void PhyMemEnd(void* Virt)
{
#if defined(_WIN32_WCE)
	if (Virt)
	{
		phymem* p;
		for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
			if (p->RefCount && p->Virt <= (char*)Virt && p->Virt+p->Length > (char*)Virt)
			{
				--p->RefCount;
				break;
			}
	}
#endif
}

bool_t KernelMode(bool_t v)
{
#if defined(_WIN32_WCE)
	if (FuncSetKMode)
		return FuncSetKMode(v);
#endif
	return 0;
}

bool_t GetDisplayPower()
{
	return DisplayPower;
}

void SetDisplayPower(bool_t State,bool_t Force)
{
	VIDEO_POWER_MANAGEMENT VPM;
	HDC DC;

	if (DisplayPower != State || Force)
	{
		DisplayPower = State;

		DC = GetDC(NULL);
		VPM.Length = sizeof(VPM);
		VPM.DPMSVersion = 1;
		VPM.PowerState = State ? 1:4;

		ExtEscape(DC, SETPOWERMANAGEMENT, sizeof(VPM), (LPCSTR) &VPM, 0, NULL);
		ReleaseDC(NULL, DC);
	}
}

static bool_t ChangeRegEntry( bool_t CurrentUser, const tchar_t* Reg, const tchar_t* Name, bool_t State, int NewValue, int BackupId ) 
{
	HKEY Key = 0;
	DWORD Size;
	DWORD Value;

	if (RegOpenKeyEx(CurrentUser ? HKEY_CURRENT_USER:HKEY_LOCAL_MACHINE,Reg, 0, ACCESS_SAVE, &Key ) == ERROR_SUCCESS) 
	{
		if (State)
		{
			// save old value 
			Size = sizeof(Value);
			if (RegQueryValueEx( Key, Name,NULL,NULL,(LPBYTE)&Value,&Size) == ERROR_SUCCESS)
				NodeSaveValue(BackupId,&Value,sizeof(Value),TYPE_INT);

			// set no screensaver
			Value = NewValue;
			Size = sizeof(Value);
			RegSetValueEx( Key, Name,0,REG_DWORD,(LPBYTE)&Value,Size);
		}
		else
		if (NodeLoadValue(BackupId,&Value,sizeof(Value),NULL))
		{
			// restore value (and delete old value)
			Size = sizeof(Value);
			RegSetValueEx( Key, Name,0,REG_DWORD,(LPBYTE)&Value,Size);

			NodeSaveValue(BackupId,NULL,0,TYPE_INT);
		}

		RegCloseKey( Key );
	}

	return Key != 0;
}

static bool_t BacklightTimeoutDisabled = -1;

void IdleTimerReset()
{
#if defined(_WIN32_WCE)
	SystemIdleTimerReset();
	if (FuncSHIdleTimerReset)
		if (BacklightTimeoutDisabled || !QueryAdvPlatform(ADVPLATFORM_HOMESCREEN))
			FuncSHIdleTimerReset();
	if (BacklightTimeoutDisabled)
		SetEvent(BacklightEvent);
#endif
}

void BacklightTimeout(bool_t Disable)
{
	if (Disable && QueryAdvPlatform(ADVPLATFORM_NOBACKLIGHT))
		Disable = 0;

	if (Disable != BacklightTimeoutDisabled)
	{
		HANDLE Handle;
		int Value;

		BacklightTimeoutDisabled = Disable;

#ifdef MIPS
		if (Platform.Model == MODEL_CASIO_E125 ||
			Platform.Model == MODEL_CASIO_EM500 ||
			Platform.Model == MODEL_CASIO_E115 ||
			Platform.Model == MODEL_CASIO_BE300 ||
			Platform.Model == MODEL_CASIO_E105)
		{
			Value = 0;
			ChangeRegEntry(0,RegCASIOBacklight,RegTimeoutBattery,Disable,Value,PLATFORM_BATTERYTIMEOUT);
			ChangeRegEntry(0,RegCASIOBacklight,RegTimeoutExPower,Disable,Value,PLATFORM_ACTIMEOUT);
		}
		else
#endif
		{
			Value = (Platform.Type == TYPE_SMARTPHONE) ? 7199999 /*10*3600*1000*/ : 0x7FFFFFFF;
			if (Platform.Model == MODEL_AXIM_X5) 
				Value = 0;
			ChangeRegEntry(1,RegScreenSaver,RegMode,Disable,1,PLATFORM_SCREENSAVER);
			ChangeRegEntry(1,RegBacklight,RegBatteryTimeout,Disable,Value,PLATFORM_BATTERYTIMEOUT);
			ChangeRegEntry(1,RegBacklight,RegACTimeout,Disable,Value,PLATFORM_ACTIMEOUT);
			ChangeRegEntry(1,RegPower,RegDisplay,Disable,-1,PLATFORM_DISPPOWER);

			// just in case try HKEY_LOCAL_MACHINE as well 
			ChangeRegEntry(0,RegBacklight,RegBatteryTimeout,Disable,Value,PLATFORM_BATTERYTIMEOUT2);
			ChangeRegEntry(0,RegBacklight,RegACTimeout,Disable,Value,PLATFORM_ACTIMEOUT2);
		}
	
		Handle = CreateEvent( NULL, FALSE, FALSE, T("BackLightChangeEvent") );
		if (Handle) 
		{
			SetEvent(Handle);

⌨️ 快捷键说明

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