📄 platform_win32.c
字号:
{
Power = FuncRequestPowerNotifications(PowerMsgQueue,PBT_TRANSITION);
if (Power)
PowerThreadHandle = CreateThread(NULL,0,PowerThread,0,0,&Id);
}
}
}
}
static void Power_Done()
{
if (PowerThreadHandle)
{
SetEvent(PowerExitEvent);
if (WaitForSingleObject(PowerThreadHandle,1000) == WAIT_TIMEOUT)
TerminateThread(PowerThreadHandle,0);
PowerThreadHandle = NULL;
}
if (Power)
{
FuncStopPowerNotifications(Power);
Power = NULL;
}
if (PowerMsgQueue)
{
FuncCloseMsgQueue(PowerMsgQueue);
PowerMsgQueue = NULL;
}
if (PowerExitEvent)
{
CloseHandle(PowerExitEvent);
PowerExitEvent = NULL;
}
}
*/
static void Power_Init() {}
static void Power_Done() {}
#endif
void Platform_Init()
{
#if defined(TARGET_WINCE)
AygShellDLL = LoadLibrary(T("aygshell.dll"));
if (AygShellDLL)
*(FARPROC*)&FuncSHIdleTimerReset = GetProcAddress(AygShellDLL,MAKEINTRESOURCE(2006));
CoreDLL = LoadLibrary(T("coredll.dll"));
if (CoreDLL)
{
*(FARPROC*)&FuncChangeDisplaySettingsEx = GetProcAddress(CoreDLL,T("ChangeDisplaySettingsEx"));
*(FARPROC*)&FuncCeSetThreadQuantum = GetProcAddress(CoreDLL,T("CeSetThreadQuantum"));
*(FARPROC*)&FuncSetKMode = GetProcAddress(CoreDLL,T("SetKMode"));
*(FARPROC*)&FuncRedrawWindow = GetProcAddress(CoreDLL,T("RedrawWindow"));
*(FARPROC*)&FuncSHGetSpecialFolderPath = GetProcAddress(CoreDLL,T("SHGetSpecialFolderPath"));
*(FARPROC*)&FuncSetPowerRequirement = GetProcAddress(CoreDLL,T("SetPowerRequirement"));
*(FARPROC*)&FuncReleasePowerRequirement = GetProcAddress(CoreDLL,T("ReleasePowerRequirement"));
*(FARPROC*)&FuncSetDevicePower = GetProcAddress(CoreDLL,T("SetDevicePower"));
*(FARPROC*)&FuncGetDevicePower = GetProcAddress(CoreDLL,T("GetDevicePower"));
*(FARPROC*)&FuncReadMsgQueue = GetProcAddress(CoreDLL,T("ReadMsgQueue"));
*(FARPROC*)&FuncCreateMsgQueue = GetProcAddress(CoreDLL,T("CreateMsgQueue"));
*(FARPROC*)&FuncCloseMsgQueue = GetProcAddress(CoreDLL,T("CloseMsgQueue"));
*(FARPROC*)&FuncRequestPowerNotifications = GetProcAddress(CoreDLL,T("RequestPowerNotifications"));
*(FARPROC*)&FuncStopPowerNotifications = GetProcAddress(CoreDLL,T("StopPowerNotifications"));
}
CEShellDLL = LoadLibrary(T("ceshell.dll"));
if (CEShellDLL)
*(FARPROC*)&FuncSHGetDocumentsFolder = GetProcAddress(CEShellDLL,MAKEINTRESOURCE(75));
SystemPath[0] = 0;
if (FuncSHGetSpecialFolderPath)
FuncSHGetSpecialFolderPath(NULL,SystemPath,0x24/*CSIDL_WINDOWS*/,FALSE);
DocumentPath[0] = 0;
if (FuncSHGetDocumentsFolder)
FuncSHGetDocumentsFolder(T("\\"),DocumentPath);
BacklightEvent = CreateEvent(NULL, FALSE, FALSE, T("TIMEOUTDISPLAYOFF"));
Power_Init();
#endif
if (!Context()->CodePage)
Context()->CodePage = CP_ACP; //CP_OEMCP;
NodeRegisterClass(&Platform);
Context()->Platform = NodeEnumObject(NULL,PLATFORM_ID);
SleepTimeout(0,0); // restore backlight settings (if last time crashed)
File_Init();
DMO_Init();
}
void Platform_Done()
{
File_Done();
DMO_Done();
NodeUnRegisterClass(PLATFORM_ID);
SetDisplayPower(1,0);
SetKeyboardBacklight(1);
#if defined(TARGET_WINCE)
Power_Done();
if (BacklightEvent) CloseHandle(BacklightEvent);
if (AygShellDLL) FreeLibrary(AygShellDLL);
if (CoreDLL) FreeLibrary(CoreDLL);
if (CEShellDLL) FreeLibrary(CEShellDLL);
#endif
}
void Log_Done()
{
if (Debug)
{
StreamClose(Debug);
Debug = NULL;
}
}
void WinUpdate()
{
HWND Wnd = Context()->Wnd;
if (Wnd)
UpdateWindow(Wnd);
}
void WinInvalidate(const rect* Rect, bool_t Local)
{
POINT o;
RECT r;
HWND Wnd = Context()->Wnd;
if (Rect->Height>0 && Rect->Width>0)
{
DEBUG_MSG5(DEBUG_VIDEO,T("Invalidate %d,%d,%d,%d (%d)"),Rect->x,Rect->y,Rect->Width,Rect->Height,Local);
if (Local && Wnd)
{
// only local invalidate
o.x = 0;
o.y = 0;
ClientToScreen(Wnd,&o);
DEBUG_MSG2(DEBUG_VIDEO,T("Invalidate local offset %d,%d"),o.x,o.y);
r.left = Rect->x - o.x;
r.top = Rect->y - o.y;
r.right = r.left + Rect->Width;
r.bottom = r.top + Rect->Height;
InvalidateRect(Wnd,&r,0);
}
else
GlobalInvalidate(Rect);
}
}
void WinValidate(const rect* Rect)
{
POINT o;
RECT r;
HWND Wnd = Context()->Wnd;
if (Rect->Height>0 && Rect->Width>0 && Wnd)
{
DEBUG_MSG4(DEBUG_VIDEO,T("Validate %d,%d,%d,%d"),Rect->x,Rect->y,Rect->Width,Rect->Height);
o.x = 0;
o.y = 0;
ClientToScreen(Wnd,&o);
DEBUG_MSG2(DEBUG_VIDEO,T("Validate offset %d,%d"),o.x,o.y);
r.left = Rect->x - o.x;
r.top = Rect->y - o.y;
r.right = r.left+Rect->Width;
r.bottom = r.top+Rect->Height;
ValidateRect(Wnd,&r);
}
}
void AdjustOrientation(video* p, bool_t Combine)
{
int Width = GetSystemMetrics(SM_CXSCREEN);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Orientation;
rect Virt;
if ((Width == p->Width*2 && Height == p->Height*2) ||
(Width == p->Height*2 && Height == p->Width*2))
p->Pixel.Flags |= PF_PIXELDOUBLE;
Orientation = GetOrientation();
if (Combine)
p->Direction = CombineDir(0,p->Direction,Orientation);
// still rotated?
PhyToVirt(NULL,&Virt,p);
if (Width != Height && Virt.Width == Height && Virt.Height == Width)
{
if (Orientation & DIR_MIRRORLEFTRIGHT)
p->Direction ^= DIR_SWAPXY | DIR_MIRRORLEFTRIGHT;
else
p->Direction ^= DIR_SWAPXY | DIR_MIRRORUPDOWN;
}
}
bool_t IsOrientationChanged()
{
int Old = Orientation;
Orientation = -1;
return GetOrientation() != Old;
}
int SetOrientation(int Orientation)
{
return ERR_NOT_SUPPORTED;
}
bool_t GetHandedness()
{
return 0;
}
int GetOrientation()
{
#if defined(TARGET_WINCE)
if (Orientation < 0)
{
HKEY Key;
context* p;
char Buffer[256];
DEVMODE* Mode = (DEVMODE*)Buffer;
Mode->dmSize = 192;
Mode->dmFields = DM_DISPLAYQUERYORIENTATION;
if (QueryPlatform(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;
}
}
p = Context();
if (Orientation < 0 && p->HwOrientation)
Orientation = p->HwOrientation(p->HwOrientationContext);
if (Orientation < 0 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, T("System\\GDI\\ROTATION"), 0, KEY_READ, &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)
{
p->Pixel.Flags = PF_PALETTE;
p->Pixel.BitCount = GetDeviceCaps(DC,BITSPIXEL);
if (p->Pixel.BitCount>4) //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);
}
#if defined(TARGET_WINCE)
bool_t KernelMode(bool_t v)
{
if (FuncSetKMode)
return FuncSetKMode(v);
return 0;
}
#endif
bool_t GetKeyboardBacklight()
{
#if defined(TARGET_WINCE)
int DeviceState;
// Treo700w
if (FuncGetDevicePower && FuncGetDevicePower(T("kyl0:"),POWER_NAME,&DeviceState)==ERROR_SUCCESS)
return DeviceState == POWER_D4 ? 0:1;
#endif
return 0;
}
int SetKeyboardBacklight(bool_t State)
{
#if defined(TARGET_WINCE)
if (FuncSetDevicePower)
{
// Treo700w
if (FuncSetDevicePower(T("kyl0:"),POWER_NAME,State?POWER_UNSPEC:POWER_D4)==ERROR_SUCCESS)
return ERR_NONE;
}
#endif
return ERR_NOT_SUPPORTED;
}
bool_t GetDisplayPower()
{
return DisplayPower;
}
int 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);
}
return ERR_NONE;
}
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, KEY_READ|KEY_WRITE, &Key) == ERROR_SUCCESS)
{
if (State)
{
// save old value
Size = sizeof(Value);
if (RegQueryValueEx(Key, Name,NULL,NULL,(LPBYTE)&Value,&Size) == ERROR_SUCCESS)
NodeRegSaveValue(0,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 (NodeRegLoadValue(0,BackupId,&Value,sizeof(Value),TYPE_INT))
{
// restore value (and delete old value)
Size = sizeof(Value);
RegSetValueEx(Key, Name,0,REG_DWORD,(LPBYTE)&Value,Size);
NodeRegSaveValue(0,BackupId,NULL,0,0);
}
RegCloseKey(Key);
}
return Key != 0;
}
static BOOL ScreenSaveActive = -1;
static BOOL PowerOffActive = -1;
static BOOL LowPowerActive = -1;
static bool_t BacklightTimeoutDisabled = -1;
void SleepTimerReset()
{
#if defined(TARGET_WINCE)
SystemIdleTimerReset();
if (FuncSHIdleTimerReset)
if (BacklightTimeoutDisabled || !QueryAdvanced(ADVANCED_HOMESCREEN))
FuncSHIdleTimerReset();
if (BacklightTimeoutDisabled)
SetEvent(BacklightEvent);
#endif
}
void SleepTimeout(bool_t KeepProcess,bool_t KeepDisplay)
{
if (!KeepProcess)
KeepDisplay = 0;
if (KeepDisplay && QueryAdvanced(ADVANCED_NOBACKLIGHT))
KeepDisplay = 0;
#if defined(TARGET_WIN32)
if (KeepDisplay)
{
if (ScreenSaveActive == -1)
{
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE,0,&ScreenSaveActive,0);
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,FALSE,NULL,0);
}
if (PowerOffActive == -1)
{
SystemParametersInfo(SPI_GETPOWEROFFACTIVE,0,&PowerOffActive,0);
SystemParametersInfo(SPI_SETPOWEROFFACTIVE,FALSE,NULL,0);
}
if (LowPowerActive == -1)
{
SystemParametersInfo(SPI_GETLOWPOWERACTIVE,0,&LowPowerActive,0);
SystemParametersInfo(SPI_SETLOWPOWERACTIVE,FALSE,NULL,0);
}
}
else
{
if (ScreenSaveActive != -1)
{
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,ScreenSaveActive,NULL,0);
ScreenSaveActive = -1;
}
if (PowerOffActive != -1)
{
SystemParametersInfo(SPI_SETPOWEROFFACTIVE,PowerOffActive,NULL,0);
PowerOffActive = -1;
}
if (LowPowerActive != -1)
{
SystemParametersInfo(SPI_SETLOWPOWERACTIVE,LowPowerActive,NULL,0);
LowPowerActive = -1;
}
}
#endif
if (KeepDisplay != BacklightTimeoutDisabled)
{
HANDLE Handle;
int Value;
int Model = QueryPlatform(PLATFORM_MODEL);
BacklightTimeoutDisabled = KeepDisplay;
#ifdef MIPS
if (Model == MODEL_CASIO_E125 ||
Model == MODEL_CASIO_EM500 ||
Model == MODEL_CASIO_E115 ||
Model == MODEL_CASIO_BE300 ||
Model == MODEL_CASIO_E105)
{
Value = 0;
ChangeRegEntry(0,RegCASIOBacklight,RegTimeoutBattery,KeepDisplay,Value,REG_BATTERYTIMEOUT);
ChangeRegEntry(0,RegCASIOBacklight,RegTimeoutExPower,KeepDisplay,Value,REG_ACTIMEOUT);
}
else
#endif
{
Value = (QueryPlatform(PLATFORM_TYPENO) == TYPE_SMARTPHONE) ? 7199999 /*10*3600*1000*/ : 0x7FFFFFFF;
if (Model == MODEL_AXIM_X5)
Value = 0;
ChangeRegEntry(1,RegScreenSaver,RegMode,KeepDisplay,1,REG_SCREENSAVER);
ChangeRegEntry(1,RegBacklight,RegBatteryTimeout,KeepDisplay,Value,REG_BATTERYTIMEOUT);
ChangeRegEntry(1,RegBacklight,RegACTimeout,KeepDisplay,Value,REG_ACTIMEOUT);
ChangeRegEntry(1,RegPower,RegDisplay,KeepDisplay,-1,REG_DISPPOWER);
// just in case try HKEY_LOCAL_MACHINE as well
ChangeRegEntry(0,RegBacklight,RegBatteryTimeout,KeepDisplay,Value,REG_BATTERYTIMEOUT2);
ChangeRegEntry(0,RegBacklight,RegACTimeout,KeepDisplay,Value,REG_ACTIMEOUT2);
}
Handle = CreateEvent(NULL, FALSE, FALSE, T("BackLightChangeEvent"));
if (Handle)
{
SetEvent(Handle);
CloseHandle(Handle);
}
// support for sample Power Manager implementation
// maybe if they use the sample code, there might be bugs with SystemIdleTimerReset()...
if (ChangeRegEntry(0,RegPowerTimouts,RegACUserIdle,KeepDisplay,0,REG_ACUSERIDLE))
{
ChangeRegEntry(0,RegPowerTimouts,RegBattUserIdle,KeepDisplay,0,REG_BATTUSERIDLE);
ChangeRegEntry(0,RegPowerTimouts,RegACSystemIdle,KeepDisplay,0,REG_ACSYSTEMIDLE);
ChangeRegEntry(0,RegPowerTimouts,RegBattSystemIdle,KeepDisplay,0,REG_BATTSYSTEMIDLE);
ChangeRegEntry(0,RegPowerTimouts,RegACSuspend,KeepDisplay,0,REG_ACSUSPEND);
ChangeRegEntry(0,RegPowerTimouts,RegBattSuspend,KeepDisplay,0,REG_BATTSUSPEND);
Handle = CreateEvent(NULL, FALSE, FALSE, T("PowerManager/ReloadActivityTimeouts"));
if (Handle)
{
SetEvent(Handle);
CloseHandle(Handle);
}
}
#if defined(TARGET_WINCE)
if (FuncSetPowerRequirement && FuncReleasePowerRequirement)
{
if (KeepDisplay && !PowerHandle)
{
PowerHandle = FuncSetPowerRequirement(T("BKL1:"),POWER_D0,POWER_NAME,NULL,0);
}
else if (!KeepDisplay && PowerHandle)
{
FuncReleasePowerRequirement(PowerHandle);
PowerHandle = NULL;
}
}
#endif
}
}
void _Assert(const char* Exp,const char* File,int Line)
{
TCHAR TExp[MAXPATH];
TCHAR TFile[MAXPATH];
AsciiToTcs(TExp,TSIZEOF(TExp),File);
stprintf_s(TFile,TSIZEOF(TFile),T("%s:%d"),TExp,Line);
AsciiToTcs(TExp,TSIZEOF(TExp),Exp);
#ifndef NDEBUG
DebugBreak();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -