📄 platform_win32.c
字号:
phymem* p;
for (p=PhyMem;p!=PhyMem+MAXPHY;++p)
if (p->Length)
{
Free(p->Blocks);
VirtualFree(p->Virt,0,MEM_RELEASE);
memset(p,0,sizeof(phymem));
}
}
if (BacklightEvent) CloseHandle(BacklightEvent);
if (AygShellDLL) FreeLibrary(AygShellDLL);
if (CoreDLL) FreeLibrary(CoreDLL);
if (CEShellDLL) FreeLibrary(CEShellDLL);
#endif
#ifndef NDEBUG
assert(BlockCount==0);
#endif
if (Debug)
Debug->Delete(Debug);
}
int QueryOrientation()
{
#if defined(_WIN32_WCE)
if (Orientation < 0)
{
HKEY Key;
char Buffer[256];
DEVMODE* Mode = (DEVMODE*)Buffer;
int i,No;
node* Node;
Mode->dmSize = 192;
Mode->dmFields = DM_DISPLAYQUERYORIENTATION;
if (Platform.Ver >= 421 && // we don't trust this method on pre wm2003se systems
FuncChangeDisplaySettingsEx &&
FuncChangeDisplaySettingsEx(NULL, Mode, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL)
{
Mode->dmFields = DM_DISPLAYORIENTATION;
FuncChangeDisplaySettingsEx(NULL, Mode, NULL, CDS_TEST, NULL);
switch ((&Mode->dmDisplayFrequency)[1]) //(Mode->dmDisplayOrientation)
{
case DMDO_0: Orientation = 0; break;
case DMDO_90: Orientation = DIR_SWAPXY | DIR_MIRRORUPDOWN; break;
case DMDO_270: Orientation = DIR_SWAPXY | DIR_MIRRORLEFTRIGHT; break;
case DMDO_180: Orientation = DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT; break;
}
}
if (Orientation < 0)
for (No=0;(Node = NodeEnum(VOUT_CLASS,No))!=NULL;++No)
if (Node->Get(Node,VOUT_ORIENTATION,&i,sizeof(int))==ERR_NONE)
{
Orientation = i;
break;
}
if (Orientation < 0 && RegOpenKeyEx( HKEY_LOCAL_MACHINE, T("System\\GDI\\ROTATION"), 0, ACCESS_LOAD, &Key ) == ERROR_SUCCESS)
{
DWORD Value;
DWORD RegSize = sizeof(Value);
DWORD RegType;
if (RegQueryValueEx(Key, T("Angle"), 0, &RegType, (LPBYTE) &Value, &RegSize) == ERROR_SUCCESS)
switch (Value)
{
case 0: Orientation = 0; break;
case 90: Orientation = DIR_SWAPXY | DIR_MIRRORUPDOWN; break;
case 270: Orientation = DIR_SWAPXY | DIR_MIRRORLEFTRIGHT; break;
case 180: Orientation = DIR_MIRRORUPDOWN | DIR_MIRRORLEFTRIGHT; break;
}
RegCloseKey( Key );
}
if (Orientation < 0)
Orientation = 0;
}
#else
Orientation = 0;
#endif
return Orientation;
}
void QueryDesktop( video* p )
{
HDC DC = GetDC(0);
memset(p,0,sizeof(video));
p->Width = GetDeviceCaps(DC,HORZRES);
p->Height = GetDeviceCaps(DC,VERTRES);
p->Aspect = ASPECT_ONE;
p->Direction = 0;
if (GetDeviceCaps(DC,BITSPIXEL)*GetDeviceCaps(DC,PLANES) <= 8)
{
int n,i;
p->Pixel.Flags = PF_PALETTE;
p->Pixel.BitCount = 1;
n=GetSystemPaletteEntries(DC,0,256,NULL);
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;
}
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -