1775 lines
44 KiB
C
Executable File
1775 lines
44 KiB
C
Executable File
/*****************************************************************************
|
|
*
|
|
* This program is free software ; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* $Id: platform_win32.c 622 2006-01-31 19:02:53Z picard $
|
|
*
|
|
* The Core Pocket Media Player
|
|
* Copyright (c) 2004-2005 Gabor Kovacs
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "../common.h"
|
|
|
|
#if defined(TARGET_WIN32) || defined(TARGET_WINCE)
|
|
|
|
#ifndef STRICT
|
|
#define STRICT
|
|
#endif
|
|
#include <windows.h>
|
|
|
|
// registry backups of original value
|
|
#define REG_BATTERYTIMEOUT 0x2000
|
|
#define REG_ACTIMEOUT 0x2001
|
|
#define REG_SCREENSAVER 0x2002
|
|
#define REG_DISPPOWER 0x2003
|
|
|
|
#define REG_ACSUSPEND 0x2004
|
|
#define REG_BATTSUSPEND 0x2005
|
|
#define REG_ACUSERIDLE 0x2006
|
|
#define REG_BATTUSERIDLE 0x2007
|
|
#define REG_ACSYSTEMIDLE 0x2008
|
|
#define REG_BATTSYSTEMIDLE 0x2009
|
|
|
|
#define REG_BATTERYTIMEOUT2 0x200A
|
|
#define REG_ACTIMEOUT2 0x200B
|
|
|
|
void DMO_Init();
|
|
void DMO_Done();
|
|
void File_Init();
|
|
void File_Done();
|
|
|
|
#if defined(TARGET_WINCE)
|
|
#define HKEY_ROOT HKEY_LOCAL_MACHINE
|
|
#else
|
|
#define HKEY_ROOT HKEY_CURRENT_USER
|
|
#endif
|
|
|
|
#if defined(TARGET_WINCE)
|
|
|
|
#define POWER_NAME 1
|
|
#define POWER_UNSPEC -1
|
|
#define POWER_D0 0
|
|
#define POWER_D4 4
|
|
|
|
#ifndef DISP_CHANGE_SUCCESSFUL
|
|
#define DISP_CHANGE_SUCCESSFUL 0
|
|
#endif
|
|
#ifndef CDS_TEST
|
|
#define CDS_TEST 0x00000002
|
|
#endif
|
|
#ifndef DM_DISPLAYORIENTATION
|
|
#define DM_DISPLAYORIENTATION 0x00800000L
|
|
#endif
|
|
#ifndef DM_DISPLAYQUERYORIENTATION
|
|
#define DM_DISPLAYQUERYORIENTATION 0x01000000L
|
|
#endif
|
|
#ifndef DMDO_0
|
|
#define DMDO_0 0
|
|
#endif
|
|
#ifndef DMDO_90
|
|
#define DMDO_90 1
|
|
#endif
|
|
#ifndef DMDO_180
|
|
#define DMDO_180 2
|
|
#endif
|
|
#ifndef DMDO_270
|
|
#define DMDO_270 4
|
|
#endif
|
|
|
|
#define SPI_GETOEMINFO 258
|
|
#define SPI_GETPLATFORMTYPE 257
|
|
|
|
typedef struct MSGQUEUEOPTIONS2
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwFlags;
|
|
DWORD dwMaxMessages;
|
|
DWORD cbMaxMessage;
|
|
BOOL bReadAccess;
|
|
|
|
} MSGQUEUEOPTIONS2;
|
|
|
|
BOOL (WINAPI* FuncCeSetThreadQuantum)(HANDLE, DWORD) = NULL;
|
|
static HANDLE (WINAPI* FuncSetPowerRequirement)(PVOID,int,ULONG,PVOID,ULONG) = NULL;
|
|
static DWORD (WINAPI* FuncReleasePowerRequirement)(HANDLE) = NULL;
|
|
static DWORD (WINAPI* FuncSetDevicePower)(PVOID,DWORD,int) = NULL;
|
|
static DWORD (WINAPI* FuncGetDevicePower)(PVOID,DWORD,int*) = NULL;
|
|
static BOOL (WINAPI* FuncSHGetDocumentsFolder)(LPCTSTR,LPTSTR) = NULL;
|
|
static BOOL (WINAPI* FuncSHGetSpecialFolderPath)(HWND,LPTSTR,int,BOOL) = NULL;
|
|
static LONG (WINAPI* FuncChangeDisplaySettingsEx)(LPCTSTR,LPDEVMODE,HWND,DWORD,LPVOID) = NULL;
|
|
static BOOL (WINAPI* FuncSetKMode)(BOOL) = NULL;
|
|
static BOOL (WINAPI* FuncRedrawWindow)(HWND,CONST RECT*,HRGN,UINT) = NULL;
|
|
static void (WINAPI* FuncSHIdleTimerReset)() = NULL;
|
|
static BOOL (WINAPI* FuncReadMsgQueue)(HANDLE hMsgQ, LPVOID lpBuffer, DWORD cbBufferSize, LPDWORD lpNumberOfBytesRead, DWORD dwTimeout, DWORD *pdwFlags) = NULL;
|
|
static HANDLE (WINAPI* FuncCreateMsgQueue)(LPCWSTR lpName, MSGQUEUEOPTIONS2* lpOptions) = NULL;
|
|
static BOOL (WINAPI* FuncCloseMsgQueue)(HANDLE hMsgQ) = NULL;
|
|
static HANDLE (WINAPI* FuncRequestPowerNotifications)(HANDLE hMsgQ,DWORD Flags) = NULL;
|
|
static DWORD (WINAPI* FuncStopPowerNotifications)(HANDLE h) = NULL;
|
|
|
|
static HMODULE CoreDLL = NULL;
|
|
static HMODULE CEShellDLL = NULL;
|
|
static HANDLE BacklightEvent = NULL;
|
|
static HANDLE PowerHandle = NULL;
|
|
|
|
#endif
|
|
|
|
static HMODULE AygShellDLL = NULL;
|
|
|
|
static const tchar_t RegBacklight[] = T("ControlPanel\\Backlight");
|
|
static const tchar_t RegBatteryTimeout[] = T("BatteryTimeout");
|
|
static const tchar_t RegACTimeout[] = T("ACTimeout");
|
|
static const tchar_t RegScreenSaver[] = T("ControlPanel\\ScreenSaver");
|
|
static const tchar_t RegMode[] = T("Mode");
|
|
static const tchar_t RegPower[] = T("ControlPanel\\Power");
|
|
static const tchar_t RegDisplay[] = T("Display");
|
|
|
|
static const tchar_t RegPowerTimouts[] = T("SYSTEM\\CurrentControlSet\\Control\\Power\\Timeouts");
|
|
static const tchar_t RegBattUserIdle[] = T("BattUserIdle");
|
|
static const tchar_t RegACUserIdle[] = T("ACUserIdle");
|
|
static const tchar_t RegBattSystemIdle[] = T("BattSystemIdle");
|
|
static const tchar_t RegACSystemIdle[] = T("ACSystemIdle");
|
|
static const tchar_t RegBattSuspend[] = T("BattSuspend");
|
|
static const tchar_t RegACSuspend[] = T("ACSuspend");
|
|
|
|
static const tchar_t RegCASIOBacklight[] = T("Drivers\\CASIO\\BackLight");
|
|
static const tchar_t RegTimeoutBattery[] = T("TimeoutBattery");
|
|
static const tchar_t RegTimeoutExPower[] = T("TimeoutExPower");
|
|
|
|
#define GETVFRAMEPHYSICAL 6144
|
|
#define GETVFRAMELEN 6145
|
|
#define DBGDRIVERSTAT 6146
|
|
#define SETPOWERMANAGEMENT 6147
|
|
#define GETPOWERMANAGEMENT 6148
|
|
|
|
typedef struct VIDEO_POWER_MANAGEMENT {
|
|
ULONG Length;
|
|
ULONG DPMSVersion;
|
|
ULONG PowerState;
|
|
} VIDEO_POWER_MANAGEMENT;
|
|
|
|
static rgb Palette[256];
|
|
static tchar_t DocumentPath[MAX_PATH]; //important! has to be the MAX_PATH
|
|
static tchar_t SystemPath[MAX_PATH]; //important! has to be the MAX_PATH
|
|
static bool_t DisplayPower = 1;
|
|
static int Orientation = -1;
|
|
static bool_t WaitCursor = 0;
|
|
static bool_t WaitCursorDisable = 0;
|
|
static stream* Debug = NULL;
|
|
|
|
#if defined(MIPS)
|
|
int GetTimeFreq()
|
|
{
|
|
return 1000;
|
|
}
|
|
int GetTimeTick()
|
|
{
|
|
SYSTEMTIME t;
|
|
GetSystemTime(&t);
|
|
return (t.wDay*24+t.wHour)*60*60*1000+(t.wMinute*60+t.wSecond)*1000+t.wMilliseconds;
|
|
}
|
|
void GetTimeCycle(int* p)
|
|
{
|
|
SYSTEMTIME i,j;
|
|
int n=0;
|
|
GetSystemTime(&i);
|
|
do
|
|
{
|
|
++n;
|
|
GetSystemTime(&j);
|
|
}
|
|
while (j.wMilliseconds==i.wMilliseconds);
|
|
p[0] = (j.wDay*24+j.wHour)*60*60*1000+(j.wMinute*60+j.wSecond)*1000+j.wMilliseconds;
|
|
p[1] = n;
|
|
}
|
|
#elif defined(TARGET_WINCE)
|
|
int GetTimeFreq()
|
|
{
|
|
return 1000;
|
|
}
|
|
int GetTimeTick()
|
|
{
|
|
return GetTickCount();
|
|
}
|
|
void GetTimeCycle(int* p)
|
|
{
|
|
int n=1;
|
|
int j;
|
|
int i = GetTickCount();
|
|
while ((j = GetTickCount())==i)
|
|
++n;
|
|
p[0] = j;
|
|
p[1] = n;
|
|
}
|
|
#else
|
|
int GetTimeFreq()
|
|
{
|
|
return 1000;
|
|
}
|
|
int GetTimeTick()
|
|
{
|
|
return timeGetTime();
|
|
}
|
|
void GetTimeCycle(int* p)
|
|
{
|
|
int n=1;
|
|
int j;
|
|
int i = timeGetTime();
|
|
while ((j = timeGetTime())==i)
|
|
++n;
|
|
p[0] = j;
|
|
p[1] = n;
|
|
}
|
|
#endif
|
|
|
|
void ReleaseModule(void** Module)
|
|
{
|
|
if (*Module)
|
|
{
|
|
FreeLibrary(*Module);
|
|
*Module = NULL;
|
|
}
|
|
}
|
|
|
|
void GetProc(void** Module,void* Ptr,const tchar_t* ProcName,int Optional)
|
|
{
|
|
FARPROC* Func = (FARPROC*)Ptr;
|
|
if (*Module)
|
|
{
|
|
#if !defined(TARGET_WINCE) && defined(UNICODE)
|
|
char ProcName8[256];
|
|
TcsToStr(ProcName8,sizeof(ProcName8),ProcName);
|
|
*Func = GetProcAddress(*Module,ProcName8);
|
|
#else
|
|
*Func = GetProcAddress(*Module,ProcName);
|
|
#endif
|
|
if (!*Func && !Optional)
|
|
ReleaseModule(Module);
|
|
}
|
|
else
|
|
*Func = NULL;
|
|
}
|
|
|
|
int DefaultLang()
|
|
{
|
|
tchar_t Lang[16];
|
|
if (GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SABBREVLANGNAME,Lang,TSIZEOF(Lang)) >= 2)
|
|
{
|
|
tcsupr(Lang);
|
|
if (tcscmp(Lang,T("JPN"))==0) tcscpy_s(Lang,TSIZEOF(Lang),T("JA"));
|
|
if (tcscmp(Lang,T("GER"))==0) tcscpy_s(Lang,TSIZEOF(Lang),T("DE"));
|
|
if (tcscmp(Lang,T("SPA"))==0) tcscpy_s(Lang,TSIZEOF(Lang),T("ES"));
|
|
|
|
// special three letter cases: Chinese traditional (CHT) and Chinese simplified (CHS)
|
|
if (tcscmp(Lang,T("CHS"))==0 || tcscmp(Lang,T("ZHI"))==0 || tcscmp(Lang,T("ZHM"))==0)
|
|
return FOURCC('C','H','S','_');
|
|
else
|
|
if (tcscmp(Lang,T("CHT"))==0 || tcscmp(Lang,T("ZHH"))==0)
|
|
return FOURCC('C','H','T','_');
|
|
else
|
|
if (tcscmp(Lang,T("PTB"))==0)
|
|
return FOURCC('P','T','B','_');
|
|
else
|
|
return FOURCC(Lang[0],Lang[1],'_','_'); // two letter version
|
|
}
|
|
return LANG_DEFAULT;
|
|
}
|
|
|
|
void PlatformDetect(platform* p)
|
|
{
|
|
#if defined(TARGET_WINCE)
|
|
tchar_t OemUpper[64];
|
|
HKEY Key;
|
|
RECT WorkArea;
|
|
#endif
|
|
OSVERSIONINFO Ver;
|
|
|
|
Ver.dwOSVersionInfoSize = sizeof(Ver);
|
|
GetVersionEx(&Ver);
|
|
p->Ver = Ver.dwMajorVersion*100 + Ver.dwMinorVersion;
|
|
stprintf_s(p->Version,TSIZEOF(p->Version),T("%d.%02d"),p->Ver/100,p->Ver%100);
|
|
|
|
#if defined(TARGET_WINCE)
|
|
|
|
p->WMPVersion = 9;
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, T("SOFTWARE\\Microsoft\\MediaPlayer\\ASFCodecs"), 0, KEY_READ, &Key) == ERROR_SUCCESS)
|
|
{
|
|
p->WMPVersion = 10;
|
|
RegCloseKey(Key);
|
|
}
|
|
|
|
p->Type = TYPE_WINCE;
|
|
if (SystemParametersInfo(SPI_GETPLATFORMTYPE,sizeof(p->PlatformType),p->PlatformType,0)!=0)
|
|
{
|
|
if (tcsicmp(p->PlatformType,T("PocketPC"))==0)
|
|
p->Type = TYPE_POCKETPC;
|
|
else
|
|
if (tcsicmp(p->PlatformType,T("Smartphone"))==0)
|
|
p->Type = TYPE_SMARTPHONE;
|
|
}
|
|
else
|
|
if (GetLastError()==ERROR_ACCESS_DENIED)
|
|
{
|
|
tcscpy_s(p->PlatformType,TSIZEOF(p->PlatformType),T("Smartphone"));
|
|
p->Type = TYPE_SMARTPHONE;
|
|
}
|
|
else
|
|
tcscpy_s(p->PlatformType,TSIZEOF(p->PlatformType),T("Windows CE"));
|
|
|
|
SystemParametersInfo(SPI_GETOEMINFO,sizeof(p->OemInfo),p->OemInfo,0);
|
|
tcscpy_s(OemUpper,TSIZEOF(OemUpper),p->OemInfo);
|
|
tcsupr(OemUpper);
|
|
|
|
#if defined(ARM)
|
|
if (tcsstr(OemUpper,T("NOVOGO")))
|
|
p->Model = MODEL_NOVOGO; // more models...
|
|
else
|
|
if (tcsstr(OemUpper,T("TYPHOON")))
|
|
p->Model = MODEL_SPV_C500_ORIGROM;
|
|
else
|
|
if (tcsstr(OemUpper,T("PW10B")) ||
|
|
tcsstr(OemUpper,T("PW10A")))
|
|
{
|
|
p->Model = MODEL_O2_XDA;
|
|
p->Caps |= CAPS_ONLY12BITRGB;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("Compal P6C")))
|
|
p->Model = MODEL_AMIGO_600C;
|
|
else
|
|
if (tcsstr(OemUpper,T("Pocket PC J710")))
|
|
p->Model = MODEL_CASIO_E200;
|
|
else
|
|
if (tcsstr(OemUpper,T("JORNADA")))
|
|
{
|
|
p->Caps |= CAPS_LANDSCAPE;
|
|
if (tcsstr(OemUpper,T("680")))
|
|
p->Model = MODEL_JORNADA_680;
|
|
else
|
|
if (tcsstr(OemUpper,T("690")))
|
|
p->Model = MODEL_JORNADA_690;
|
|
else
|
|
if (tcsstr(OemUpper,T("710")))
|
|
p->Model = MODEL_JORNADA_710;
|
|
else
|
|
if (tcsstr(OemUpper,T("720")))
|
|
p->Model = MODEL_JORNADA_720;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("IPAQ")))
|
|
{
|
|
p->Caps |= CAPS_PORTRAIT;
|
|
if (tcsstr(OemUpper,T("H3600")))
|
|
{
|
|
p->Model = MODEL_IPAQ_H3600;
|
|
p->Caps |= CAPS_ONLY12BITRGB;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("H3700")))
|
|
{
|
|
p->Model = MODEL_IPAQ_H3700;
|
|
p->Caps |= CAPS_ONLY12BITRGB;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("H3800")))
|
|
p->Model = MODEL_IPAQ_H3800;
|
|
else
|
|
if (tcsstr(OemUpper,T("H3900")))
|
|
p->Model = MODEL_IPAQ_H3900;
|
|
else
|
|
if (tcsstr(OemUpper,T("HX4700")))
|
|
p->Model = MODEL_IPAQ_HX4700;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("TOSHIBA")))
|
|
{
|
|
p->Caps |= CAPS_PORTRAIT;
|
|
if (tcsstr(OemUpper,T("E740")))
|
|
p->Model = MODEL_TOSHIBA_E740;
|
|
else
|
|
if (tcsstr(OemUpper,T("E750")))
|
|
p->Model = MODEL_TOSHIBA_E750;
|
|
else
|
|
if (tcsstr(OemUpper,T("E80")))
|
|
p->Model = MODEL_TOSHIBA_E800;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("AXIM")))
|
|
{
|
|
if (tcscmp(OemUpper+tcslen(OemUpper)-2,T("X5"))==0)
|
|
p->Model = MODEL_AXIM_X5;
|
|
|
|
if (tcscmp(OemUpper+tcslen(OemUpper)-3,T("X50"))==0 ||
|
|
tcscmp(OemUpper+tcslen(OemUpper)-4,T("X50V"))==0)
|
|
p->Model = MODEL_AXIM_X50;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("LOOX")))
|
|
{
|
|
if (tcsstr(OemUpper,T("720")))
|
|
p->Model = MODEL_LOOX_720;
|
|
}
|
|
else
|
|
if (tcsstr(OemUpper,T("NEXIO")))
|
|
{
|
|
if (tcsstr(OemUpper,T("XP40")))
|
|
p->Model = MODEL_NEXIO_XP40;
|
|
else
|
|
if (tcsstr(OemUpper,T("XP30")))
|
|
p->Model = MODEL_NEXIO_XP30;
|
|
}
|
|
|
|
#elif defined(MIPS)
|
|
if (tcsstr(OemUpper,T("BSQUARE")))
|
|
{
|
|
tcscpy_s(OemUpper,TSIZEOF(OemUpper),p->PlatformType);
|
|
tcsupr(OemUpper);
|
|
|
|
if (tcsstr(OemUpper,T("ALCHEMY")))
|
|
p->Model = MODEL_BSQUARE_ALCHEMY;
|
|
|
|
tcscpy_s(OemUpper,TSIZEOF(OemUpper),p->OemInfo);
|
|
tcsupr(OemUpper);
|
|
}
|
|
|
|
if (tcsstr(OemUpper,T("POCKET")))
|
|
{
|
|
if (tcsstr(OemUpper,T(" J74")))
|
|
{
|
|
p->Model = MODEL_CASIO_BE300;
|
|
p->Caps |= CAPS_OLDSHELL;
|
|
}
|
|
}
|
|
|
|
if (tcsstr(OemUpper,T("POCKET PC")))
|
|
{
|
|
p->Caps |= CAPS_PORTRAIT;
|
|
if (tcsstr(OemUpper,T(" J67")))
|
|
p->Model = MODEL_CASIO_E125;
|
|
else
|
|
if (tcsstr(OemUpper,T(" J76")))
|
|
p->Model = MODEL_CASIO_EM500;
|
|
else
|
|
if (tcsstr(OemUpper,T(" J58")))
|
|
p->Model = MODEL_CASIO_E115;
|
|
else
|
|
if (tcsstr(OemUpper,T(" J53")) || tcsstr(OemUpper,T(" JX53")))
|
|
p->Model = MODEL_CASIO_E105;
|
|
}
|
|
|
|
if (tcsstr(OemUpper,T("HC-VJ")))
|
|
p->Model = MODEL_INTERMEC_6651;
|
|
|
|
if (tcsstr(OemUpper,T("JVC")))
|
|
{
|
|
if (tcsstr(OemUpper,T("C33")))
|
|
p->Model = MODEL_JVC_C33;
|
|
}
|
|
|
|
if (tcsstr(OemUpper,T("COMPAQ AERO 15")))
|
|
p->Model = MODEL_COMPAQ_AERO_1500;
|
|
|
|
#elif defined(SH3)
|
|
if (tcsstr(OemUpper,T("JORNADA")))
|
|
{
|
|
if (tcsstr(OemUpper,T(" 43")))
|
|
{
|
|
p->Caps |= CAPS_ONLY12BITRGB;
|
|
}
|
|
if (tcsstr(OemUpper,T(" 54")))
|
|
{
|
|
p->Model = MODEL_JORNADA_540;
|
|
p->Caps |= CAPS_ONLY12BITRGB | CAPS_PORTRAIT;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!AygShellDLL && p->Ver < 300)
|
|
p->Caps |= CAPS_OLDSHELL;
|
|
|
|
// detect fake navigator bar and use old style menu
|
|
if (p->Type != TYPE_SMARTPHONE && AygShellDLL &&
|
|
SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,0) && WorkArea.top==0)
|
|
p->Caps |= CAPS_OLDSHELL;
|
|
|
|
#else
|
|
tcscpy_s(p->PlatformType,TSIZEOF(p->PlatformType),T("Windows"));
|
|
p->Type = TYPE_WIN32;
|
|
#endif
|
|
}
|
|
|
|
#if defined(TARGET_WINCE)
|
|
|
|
/*
|
|
#define PBT_TRANSITION 1
|
|
|
|
#define POWER_STATE(i) ((i)&0xFFFF0000)
|
|
#define POWER_STATE_ON 0x00010000
|
|
#define POWER_STATE_SUSPEND 0x00200000
|
|
|
|
typedef struct POWER_BROADCAST
|
|
{
|
|
DWORD Message;
|
|
DWORD Flags;
|
|
DWORD Length;
|
|
WCHAR SystemPowerState[64];
|
|
|
|
} POWER_BROADCAST;
|
|
|
|
static HANDLE Power = NULL;
|
|
static HANDLE PowerMsgQueue = NULL;
|
|
static HANDLE PowerExitEvent = NULL;
|
|
static HANDLE PowerThreadHandle = NULL;
|
|
|
|
static DWORD WINAPI PowerThread( LPVOID Parameter )
|
|
{
|
|
DWORD PowerState = POWER_STATE_ON;
|
|
POWER_BROADCAST Msg;
|
|
DWORD Size;
|
|
DWORD Flags;
|
|
HANDLE Handles[2];
|
|
|
|
Handles[0] = PowerExitEvent;
|
|
Handles[1] = PowerMsgQueue;
|
|
|
|
for (;;)
|
|
{
|
|
DWORD Result = WaitForMultipleObjects(2, Handles, FALSE, INFINITE);
|
|
if (Result == WAIT_OBJECT_0 || Result == WAIT_ABANDONED_0)
|
|
break;
|
|
|
|
if (FuncReadMsgQueue(PowerMsgQueue,&Msg,sizeof(Msg),&Size,0,&Flags))
|
|
{
|
|
if (Size >= sizeof(DWORD)*2 && Msg.Message == PBT_TRANSITION && Msg.Flags &&
|
|
PowerState != POWER_STATE(Msg.Flags))
|
|
{
|
|
PowerState = POWER_STATE(Msg.Flags);
|
|
if (PowerState == POWER_STATE_ON || PowerState == POWER_STATE_SUSPEND)
|
|
{
|
|
bool_t b = PowerState == POWER_STATE_SUSPEND;
|
|
node* Player = Context()->Player;
|
|
if (Player)
|
|
Player->Set(Player,PLAYER_POWEROFF,&b,sizeof(b));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void Power_Init()
|
|
{
|
|
DWORD Id;
|
|
MSGQUEUEOPTIONS2 MsgOpt;
|
|
|
|
if (FuncRequestPowerNotifications && FuncReadMsgQueue && FuncStopPowerNotifications &&
|
|
FuncCreateMsgQueue && FuncCloseMsgQueue)
|
|
{
|
|
memset(&MsgOpt,0,sizeof(MsgOpt));
|
|
MsgOpt.dwSize = sizeof(MsgOpt);
|
|
MsgOpt.dwFlags = 0;
|
|
MsgOpt.dwMaxMessages = 8;
|
|
MsgOpt.cbMaxMessage = sizeof(POWER_BROADCAST);
|
|
MsgOpt.bReadAccess = TRUE;
|
|
|
|
PowerExitEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
if (PowerExitEvent)
|
|
{
|
|
PowerMsgQueue = FuncCreateMsgQueue(NULL,&MsgOpt);
|
|
if (PowerMsgQueue)
|
|
{
|
|
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();
|
|
#endif
|
|
MessageBox(NULL,TExp,TFile,MB_OK);
|
|
}
|
|
|
|
void* BrushCreate(rgbval_t Color) { return CreateSolidBrush(Color); }
|
|
void BrushDelete(void* Handle) { if (Handle) DeleteObject((HGDIOBJ)Handle); }
|
|
void WinFill(void* DC,rect* Rect,rect* Exclude,void* Brush)
|
|
{
|
|
RECT r;
|
|
if (Exclude)
|
|
ExcludeClipRect(DC,Exclude->x,Exclude->y,Exclude->x + Exclude->Width,Exclude->y + Exclude->Height);
|
|
|
|
r.left = Rect->x;
|
|
r.top = Rect->y;
|
|
r.right = Rect->x + Rect->Width;
|
|
r.bottom = Rect->y + Rect->Height;
|
|
|
|
FillRect(DC,&r,(HBRUSH)Brush);
|
|
}
|
|
|
|
void ShowMessage(const tchar_t* Title,const tchar_t* Msg,...)
|
|
{
|
|
bool_t Wait = WaitCursor;
|
|
tchar_t s[1024];
|
|
va_list Args;
|
|
va_start(Args,Msg);
|
|
vstprintf_s(s,TSIZEOF(s),Msg,Args);
|
|
va_end(Args);
|
|
if (Wait) WaitEnd();
|
|
MessageBox(NULL,s,Title,MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
|
|
if (Wait) WaitBegin();
|
|
}
|
|
|
|
void DebugMessage(const tchar_t* Msg,...)
|
|
{
|
|
va_list Args;
|
|
tchar_t s[1024];
|
|
|
|
#ifndef NDEBUG
|
|
if (!Debug)
|
|
Debug = StreamOpen(T("\\debug.txt"),1);
|
|
#else
|
|
if (!Debug)
|
|
{
|
|
GetDebugPath(s,TSIZEOF(s),T("log.txt"));
|
|
Debug = StreamOpen(s,1);
|
|
}
|
|
#endif
|
|
|
|
s[0]=0;
|
|
|
|
#if 0
|
|
//#ifdef NDEBUG
|
|
{
|
|
//SYSTEMTIME t;
|
|
//GetSystemTime(&t);
|
|
//stprintf(s+tcslen(s), T("%02d:%02d:%02d "),t.wHour,t.wMinute,t.wSecond);
|
|
int min,sec;
|
|
int t = GetTickCount();
|
|
min = t / 60000;
|
|
t -= min*60000;
|
|
sec = t / 1000;
|
|
t -= sec*1000;
|
|
stcatprintf_s(s,TSIZEOF(s),T("%02d:%02d.%03d "),min,sec,t);
|
|
}
|
|
#endif
|
|
|
|
#ifndef NDEBUG
|
|
// stprintf_s(s,TSIZEOF(s),T("%04x "),(int)GetCurrentThreadId());
|
|
#endif
|
|
va_start(Args,Msg);
|
|
vstprintf_s(s+tcslen(s),TSIZEOF(s)-tcslen(s), Msg, Args);
|
|
va_end(Args);
|
|
tcscat_s(s,TSIZEOF(s),T("\n"));
|
|
|
|
#ifndef NDEBUG
|
|
OutputDebugString(s);
|
|
#endif
|
|
StreamPrintf(Debug,T("%s"),s);
|
|
}
|
|
|
|
typedef struct contextreg
|
|
{
|
|
int Ofs;
|
|
const tchar_t* Name;
|
|
} contextreg;
|
|
|
|
#if defined(_M_IX86)
|
|
static contextreg Reg[] =
|
|
{
|
|
OFS(CONTEXT,Eax), T("eax"),
|
|
OFS(CONTEXT,Ebx), T("ebx"),
|
|
OFS(CONTEXT,Ecx), T("ecx"),
|
|
OFS(CONTEXT,Edx), T("edx"),
|
|
OFS(CONTEXT,Esi), T("esi"),
|
|
OFS(CONTEXT,Edi), T("edi"),
|
|
OFS(CONTEXT,Ebp), T("ebp"),
|
|
OFS(CONTEXT,Esp), T("esp"),
|
|
OFS(CONTEXT,Eip), T("eip"),
|
|
OFS(CONTEXT,EFlags), T("flags"),
|
|
|
|
OFS(CONTEXT,Esp), NULL,
|
|
};
|
|
#elif defined(MIPS)
|
|
static contextreg Reg[] =
|
|
{
|
|
OFS(CONTEXT,IntZero), T("Zero"),
|
|
OFS(CONTEXT,IntAt), T("At"),
|
|
OFS(CONTEXT,IntV0), T("V0"),
|
|
OFS(CONTEXT,IntV1), T("V1"),
|
|
OFS(CONTEXT,IntA0), T("A0"),
|
|
OFS(CONTEXT,IntA1), T("A1"),
|
|
OFS(CONTEXT,IntA2), T("A2"),
|
|
OFS(CONTEXT,IntA3), T("A3"),
|
|
OFS(CONTEXT,IntT0), T("T0"),
|
|
OFS(CONTEXT,IntT1), T("T1"),
|
|
OFS(CONTEXT,IntT2), T("T2"),
|
|
OFS(CONTEXT,IntT3), T("T3"),
|
|
OFS(CONTEXT,IntT4), T("T4"),
|
|
OFS(CONTEXT,IntT5), T("T5"),
|
|
OFS(CONTEXT,IntT6), T("T6"),
|
|
OFS(CONTEXT,IntT7), T("T7"),
|
|
OFS(CONTEXT,IntS0), T("S0"),
|
|
OFS(CONTEXT,IntS1), T("S1"),
|
|
OFS(CONTEXT,IntS2), T("S2"),
|
|
OFS(CONTEXT,IntS3), T("S3"),
|
|
OFS(CONTEXT,IntS4), T("S4"),
|
|
OFS(CONTEXT,IntS5), T("S5"),
|
|
OFS(CONTEXT,IntS6), T("S6"),
|
|
OFS(CONTEXT,IntS7), T("S7"),
|
|
OFS(CONTEXT,IntT8), T("T8"),
|
|
OFS(CONTEXT,IntT9), T("T9"),
|
|
OFS(CONTEXT,IntK0), T("K0"),
|
|
OFS(CONTEXT,IntK1), T("K1"),
|
|
OFS(CONTEXT,IntGp), T("Gp"),
|
|
OFS(CONTEXT,IntSp), T("Sp"),
|
|
OFS(CONTEXT,IntS8), T("S8"),
|
|
OFS(CONTEXT,IntRa), T("Ra"),
|
|
OFS(CONTEXT,IntLo), T("Lo"),
|
|
OFS(CONTEXT,IntHi), T("Hi"),
|
|
OFS(CONTEXT,IntSp), NULL,
|
|
};
|
|
#elif defined(ARM)
|
|
static contextreg Reg[] =
|
|
{
|
|
OFS(CONTEXT,R0), T("R0"),
|
|
OFS(CONTEXT,R1), T("R1"),
|
|
OFS(CONTEXT,R2), T("R2"),
|
|
OFS(CONTEXT,R3), T("R3"),
|
|
OFS(CONTEXT,R4), T("R4"),
|
|
OFS(CONTEXT,R5), T("R5"),
|
|
OFS(CONTEXT,R6), T("R6"),
|
|
OFS(CONTEXT,R7), T("R7"),
|
|
OFS(CONTEXT,R8), T("R8"),
|
|
OFS(CONTEXT,R9), T("R9"),
|
|
OFS(CONTEXT,R10),T("R10"),
|
|
OFS(CONTEXT,R11),T("R11"),
|
|
OFS(CONTEXT,R12),T("R12"),
|
|
OFS(CONTEXT,Sp), T("Sp"),
|
|
OFS(CONTEXT,Lr), T("Lr"),
|
|
OFS(CONTEXT,Pc), T("Pc"),
|
|
OFS(CONTEXT,Psr),T("Psr"),
|
|
OFS(CONTEXT,Sp), NULL,
|
|
};
|
|
#elif defined(SH3)
|
|
static contextreg Reg[] =
|
|
{
|
|
OFS(CONTEXT,PR), T("PR"),
|
|
OFS(CONTEXT,MACH), T("MACH"),
|
|
OFS(CONTEXT,MACL), T("MACL"),
|
|
OFS(CONTEXT,GBR), T("GBR"),
|
|
OFS(CONTEXT,R0), T("R0"),
|
|
OFS(CONTEXT,R1), T("R1"),
|
|
OFS(CONTEXT,R2), T("R2"),
|
|
OFS(CONTEXT,R3), T("R3"),
|
|
OFS(CONTEXT,R4), T("R4"),
|
|
OFS(CONTEXT,R5), T("R5"),
|
|
OFS(CONTEXT,R6), T("R6"),
|
|
OFS(CONTEXT,R7), T("R7"),
|
|
OFS(CONTEXT,R8), T("R8"),
|
|
OFS(CONTEXT,R9), T("R9"),
|
|
OFS(CONTEXT,R10), T("R10"),
|
|
OFS(CONTEXT,R11), T("R11"),
|
|
OFS(CONTEXT,R12), T("R12"),
|
|
OFS(CONTEXT,R13), T("R13"),
|
|
OFS(CONTEXT,R14), T("R14"),
|
|
OFS(CONTEXT,R15), T("R15"),
|
|
OFS(CONTEXT,R15), NULL,
|
|
};
|
|
#else
|
|
static contextreg Reg[] = { -1, NULL };
|
|
#endif
|
|
|
|
void FindFiles(const tchar_t* Path, const tchar_t* Mask,void(*Process)(const tchar_t*,void*),void* Param)
|
|
{
|
|
WIN32_FIND_DATA FindData;
|
|
tchar_t FindPath[MAXPATH];
|
|
HANDLE Find;
|
|
|
|
tcscpy_s(FindPath,TSIZEOF(FindPath),Path);
|
|
tcscat_s(FindPath,TSIZEOF(FindPath),Mask);
|
|
Find = FindFirstFile(FindPath,&FindData);
|
|
|
|
if (Find != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
tcscpy_s(FindPath,TSIZEOF(FindPath),Path);
|
|
tcscat_s(FindPath,TSIZEOF(FindPath),FindData.cFileName);
|
|
Process(FindPath,Param);
|
|
}
|
|
while (FindNextFile(Find,&FindData));
|
|
|
|
FindClose(Find);
|
|
}
|
|
}
|
|
|
|
void GetModulePath(tchar_t* Path,const tchar_t* Module)
|
|
{
|
|
tchar_t* s;
|
|
HANDLE Handle = NULL;
|
|
if (Module)
|
|
Handle = GetModuleHandle(Module);
|
|
GetModuleFileName(Handle,Path,MAXPATH);
|
|
s = tcsrchr(Path,'\\');
|
|
if (s) s[1]=0;
|
|
}
|
|
|
|
void GetDebugPath(tchar_t* Path, int PathLen, const tchar_t* FileName)
|
|
{
|
|
stprintf_s(Path,PathLen,T("%s\\%s"),DocumentPath,FileName);
|
|
}
|
|
|
|
void GetSystemPath(tchar_t* Path, int PathLen, const tchar_t* FileName)
|
|
{
|
|
stprintf_s(Path,PathLen,T("%s\\%s"),SystemPath,FileName);
|
|
}
|
|
|
|
int64_t GetTimeDate()
|
|
{
|
|
SYSTEMTIME t;
|
|
GetSystemTime(&t);
|
|
return (((t.wHour*100)+t.wMinute)*100+t.wSecond)*1000 +
|
|
(int64_t)(((t.wYear*100)+t.wMonth)*100+t.wDay) * 1000000000;
|
|
}
|
|
|
|
bool_t SaveDocument(const tchar_t* Name, const tchar_t* Text,tchar_t* URL,int URLLen)
|
|
{
|
|
stream* f;
|
|
stprintf_s(URL,URLLen,T("%s\\%s.txt"),DocumentPath,Name);
|
|
|
|
f = StreamOpen(URL,1);
|
|
if (!f)
|
|
return 0;
|
|
|
|
StreamText(f,Text,0);
|
|
StreamClose(f);
|
|
return 1;
|
|
}
|
|
|
|
int SafeException(void* p)
|
|
{
|
|
EXCEPTION_POINTERS* Data = (EXCEPTION_POINTERS*)p;
|
|
stream* File;
|
|
tchar_t Path[MAXPATH];
|
|
|
|
if (Context())
|
|
{
|
|
GetDebugPath(Path,TSIZEOF(Path),T("crash.txt"));
|
|
File = StreamOpen(Path,1);
|
|
if (File)
|
|
{
|
|
void** Stack;
|
|
contextreg* r;
|
|
int No;
|
|
const uint8_t* ContextRecord = (const uint8_t*) Data->ContextRecord;
|
|
EXCEPTION_RECORD* Record = Data->ExceptionRecord;
|
|
tchar_t* Name;
|
|
int DllBase;
|
|
tchar_t DllName[MAXPATH];
|
|
|
|
StreamPrintf(File,T("%s %s crash report\n----------------------------\n"),
|
|
Context()->ProgramName,Context()->ProgramVersion);
|
|
|
|
switch (Record->ExceptionCode)
|
|
{
|
|
case STATUS_ACCESS_VIOLATION: Name = T("Access violation"); break;
|
|
case STATUS_BREAKPOINT: Name = T("Breakpoint"); break;
|
|
case STATUS_DATATYPE_MISALIGNMENT: Name = T("Datatype misalignment"); break;
|
|
case STATUS_ILLEGAL_INSTRUCTION: Name = T("Illegal instruction"); break;
|
|
case STATUS_INTEGER_DIVIDE_BY_ZERO: Name = T("Int divide by zero"); break;
|
|
case STATUS_INTEGER_OVERFLOW: Name = T("Int overflow"); break;
|
|
case STATUS_PRIVILEGED_INSTRUCTION: Name = T("Priv instruction"); break;
|
|
case STATUS_STACK_OVERFLOW: Name = T("Stack overflow"); break;
|
|
default: Name = T("Unknown"); break;
|
|
}
|
|
|
|
if (!NodeLocatePtr(Record->ExceptionAddress,DllName,TSIZEOF(DllName),&DllBase))
|
|
{
|
|
DllName[0] = 0;
|
|
DllBase = (int)Record->ExceptionAddress;
|
|
}
|
|
StreamPrintf(File,T("%s(%08x) at %08x (%s:%08x)"),Name,Record->ExceptionCode,Record->ExceptionAddress,DllName,DllBase);
|
|
|
|
if (Record->ExceptionCode == STATUS_ACCESS_VIOLATION)
|
|
{
|
|
if (Record->ExceptionInformation[0])
|
|
Name = T("Write to");
|
|
else
|
|
Name = T("Read from");
|
|
StreamPrintf(File,T("\n%s %08x"),Name,Record->ExceptionInformation[1]);
|
|
if (NodeLocatePtr((void*)Record->ExceptionInformation[1],DllName,TSIZEOF(DllName),&DllBase))
|
|
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
|
|
}
|
|
|
|
// context
|
|
|
|
StreamPrintf(File,T("\n\ncpu dump:"));
|
|
|
|
for (r=Reg;r->Name;++r)
|
|
{
|
|
void* Ptr = *(void**)(ContextRecord+r->Ofs);
|
|
|
|
StreamPrintf(File,T("\n%-5s = %08x"),r->Name,Ptr);
|
|
|
|
if (NodeLocatePtr(Ptr,DllName,TSIZEOF(DllName),&DllBase))
|
|
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
|
|
}
|
|
|
|
if (r->Ofs >= 0)
|
|
{
|
|
StreamPrintf(File,T("\n\nstack dump:"));
|
|
|
|
Stack = *(void***)(ContextRecord+r->Ofs);
|
|
for (No=0;No<256;++No,++Stack)
|
|
{
|
|
if (!IsBadReadPtr(Stack,sizeof(void*)))
|
|
{
|
|
void* Ptr = *Stack;
|
|
|
|
StreamPrintf(File,T("\n%08x %08x"),Stack,Ptr);
|
|
|
|
if (NodeLocatePtr(Ptr,DllName,TSIZEOF(DllName),&DllBase))
|
|
StreamPrintf(File,T(" (%s:%08x)"),DllName,DllBase);
|
|
}
|
|
else
|
|
StreamPrintf(File,T("\n%08x ????????"),Stack);
|
|
}
|
|
}
|
|
|
|
StreamPrintf(File,T("\n\n"));
|
|
TRY_BEGIN
|
|
{
|
|
NodeBroadcast(NODE_CRASH,NULL,0);
|
|
}
|
|
TRY_END
|
|
NodeDump(File);
|
|
StreamClose(File);
|
|
}
|
|
|
|
MessageBox(NULL,LangStr(PLATFORM_ID,PLATFORM_CRASH_MESSAGE),
|
|
LangStr(PLATFORM_ID,PLATFORM_CRASH_TITLE),MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_ICONSTOP);
|
|
}
|
|
|
|
Mem_Done(); // use safevirtualfree (if done by OS, it could be buggy on O2 Atom)
|
|
TerminateProcess(GetCurrentProcess(),1);
|
|
return 1;
|
|
}
|
|
|
|
void TryInvalidate(HWND Wnd, RECT* r0)
|
|
{
|
|
RECT r;
|
|
|
|
if (IsWindowVisible(Wnd))
|
|
{
|
|
GetWindowRect(Wnd,&r);
|
|
if (r0->left < r.right && r0->right > r.left &&
|
|
r0->top < r.bottom && r0->bottom > r.top)
|
|
{
|
|
// window is visible and intersects with r0
|
|
|
|
HWND Child;
|
|
POINT o;
|
|
o.x = o.y = 0;
|
|
ClientToScreen(Wnd,&o);
|
|
|
|
r.left = r0->left - o.x;
|
|
r.right = r0->right - o.x;
|
|
r.top = r0->top - o.y;
|
|
r.bottom = r0->bottom - o.y;
|
|
InvalidateRect(Wnd,&r,0);
|
|
|
|
Child = GetWindow(Wnd,GW_CHILD);
|
|
while (Child && IsWindow(Child))
|
|
{
|
|
TryInvalidate(Child,r0);
|
|
Child = GetWindow(Child,GW_HWNDNEXT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CALLBACK EnumInvalidate(HWND Wnd, LPARAM lParam)
|
|
{
|
|
TryInvalidate(Wnd,(RECT*)lParam);
|
|
return 1;
|
|
}
|
|
|
|
void GlobalInvalidate(const rect* Rect)
|
|
{
|
|
RECT r;
|
|
r.left = Rect->x;
|
|
r.top = Rect->y;
|
|
r.right = r.left + Rect->Width;
|
|
r.bottom = r.top + Rect->Height;
|
|
|
|
#if defined(TARGET_WINCE)
|
|
if (FuncRedrawWindow) // doesn't work for mio558???
|
|
FuncRedrawWindow(NULL,&r,NULL,0x0001|0x0080); //RDW_INVALIDATE|RDW_ALLCHILDREN
|
|
else
|
|
EnumWindows(EnumInvalidate,(LPARAM)&r);
|
|
#else
|
|
RedrawWindow(NULL,&r,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN);
|
|
#endif
|
|
}
|
|
|
|
void HotKeyToString(tchar_t* Out, size_t OutLen, int HotKey)
|
|
{
|
|
int Id = 0;
|
|
|
|
Out[0] = 0;
|
|
if (HotKey)
|
|
{
|
|
bool_t Keep = (HotKey & HOTKEY_KEEP) != 0;
|
|
if ((HotKey & HOTKEY_MASK) < 0xC1 || (HotKey & HOTKEY_MASK) > 0xCF)
|
|
{
|
|
if (HotKey & HOTKEY_WIN) { tcscat_s(Out,OutLen,LangStr(PLATFORM_ID,PLATFORM_KEY_WIN)); tcscat_s(Out,OutLen,T("+")); }
|
|
if (HotKey & HOTKEY_SHIFT) { tcscat_s(Out,OutLen,LangStr(PLATFORM_ID,PLATFORM_KEY_SHIFT)); tcscat_s(Out,OutLen,T("+")); }
|
|
if (HotKey & HOTKEY_CTRL) { tcscat_s(Out,OutLen,LangStr(PLATFORM_ID,PLATFORM_KEY_CTRL)); tcscat_s(Out,OutLen,T("+")); }
|
|
if (HotKey & HOTKEY_ALT) { tcscat_s(Out,OutLen,LangStr(PLATFORM_ID,PLATFORM_KEY_ALT)); tcscat_s(Out,OutLen,T("+")); }
|
|
}
|
|
HotKey &= HOTKEY_MASK;
|
|
|
|
if ((HotKey >= '0' && HotKey <= '9') ||
|
|
(HotKey >= 'A' && HotKey <= 'Z'))
|
|
stcatprintf_s(Out,OutLen,T("%c"),HotKey);
|
|
else
|
|
if (HotKey >= 0x70 && HotKey < 0x80)
|
|
stcatprintf_s(Out,OutLen,T("F%d"),HotKey-0x70+1);
|
|
else
|
|
switch (HotKey)
|
|
{
|
|
case 0x86:
|
|
Id = PLATFORM_KEY_ACTION;
|
|
break;
|
|
case VK_RETURN:
|
|
Id = PLATFORM_KEY_ENTER;
|
|
break;
|
|
case VK_ESCAPE:
|
|
Id = PLATFORM_KEY_ESCAPE;
|
|
break;
|
|
case VK_LEFT:
|
|
Id = PLATFORM_KEY_LEFT;
|
|
break;
|
|
case VK_RIGHT:
|
|
Id = PLATFORM_KEY_RIGHT;
|
|
break;
|
|
case VK_UP:
|
|
Id = PLATFORM_KEY_UP;
|
|
break;
|
|
case VK_DOWN:
|
|
Id = PLATFORM_KEY_DOWN;
|
|
break;
|
|
case VK_SPACE:
|
|
Id = PLATFORM_KEY_SPACE;
|
|
break;
|
|
case 0xC1:
|
|
case 0xC2:
|
|
case 0xC3:
|
|
case 0xC4:
|
|
case 0xC5:
|
|
case 0xC6:
|
|
case 0xC7:
|
|
case 0xC8:
|
|
case 0xC9:
|
|
case 0xCA:
|
|
case 0xCB:
|
|
case 0xCC:
|
|
case 0xCD:
|
|
case 0xCE:
|
|
case 0xCF:
|
|
stcatprintf_s(Out,OutLen,LangStr(PLATFORM_ID,PLATFORM_KEY_APP),HotKey-0xC0);
|
|
break;
|
|
case 0xB0:
|
|
Id = PLATFORM_KEY_NEXT;
|
|
break;
|
|
case 0xB1:
|
|
Id = PLATFORM_KEY_PREV;
|
|
break;
|
|
case 0xB2:
|
|
Id = PLATFORM_KEY_STOP;
|
|
break;
|
|
case 0xB3:
|
|
Id = PLATFORM_KEY_PLAY;
|
|
break;
|
|
default:
|
|
stcatprintf_s(Out,OutLen,T("#%02X"),HotKey);
|
|
break;
|
|
}
|
|
if (Id)
|
|
tcscat_s(Out,OutLen,LangStr(PLATFORM_ID,Id));
|
|
if (Keep) { tcscat_s(Out,OutLen,T("*")); }
|
|
}
|
|
}
|
|
|
|
void WaitDisable(bool_t v)
|
|
{
|
|
WaitCursorDisable = v;
|
|
if (v && WaitCursor)
|
|
WaitEnd();
|
|
}
|
|
|
|
bool_t WaitBegin()
|
|
{
|
|
//DEBUG_MSG(DEBUG_SYS,T("WaitBegin"));
|
|
if (WaitCursorDisable)
|
|
return 0;
|
|
SetCursor(LoadCursor (NULL, IDC_WAIT));
|
|
WaitCursor = 1;
|
|
return 1;
|
|
}
|
|
|
|
void WaitEnd()
|
|
{
|
|
//DEBUG_MSG(DEBUG_SYS,T("WaitEnd"));
|
|
SetCursor(LoadCursor (NULL, IDC_ARROW));
|
|
WaitCursor = 0;
|
|
}
|
|
|
|
bool_t CheckModule(const tchar_t* Name)
|
|
{
|
|
DWORD RegType;
|
|
DWORD RegSize;
|
|
DWORD Disp;
|
|
void* Module;
|
|
tchar_t Path[MAXPATH];
|
|
HKEY Key = NULL;
|
|
|
|
if (!Name[0])
|
|
return 0;
|
|
|
|
RegSize = sizeof(Path);
|
|
stprintf_s(Path,TSIZEOF(Path),T("SOFTWARE\\%s\\DLLPath"),Context()->ProgramName);
|
|
if (RegCreateKeyEx(HKEY_ROOT, Path, 0, NULL, 0, KEY_READ|KEY_WRITE, NULL, &Key, &Disp) == ERROR_SUCCESS)
|
|
{
|
|
if (RegQueryValueEx(Key, Name, 0, &RegType, (PBYTE)Path, &RegSize) == ERROR_SUCCESS)
|
|
{
|
|
if (RegType==REG_SZ && FileExits(Path))
|
|
{
|
|
RegCloseKey(Key);
|
|
return 1;
|
|
}
|
|
RegDeleteValue(Key,Name);
|
|
}
|
|
}
|
|
|
|
Module = LoadLibrary(Name);
|
|
if (Module)
|
|
{
|
|
if (Key)
|
|
{
|
|
GetModuleFileName(Module,Path,MAXPATH);
|
|
RegSetValueEx(Key, Name, 0, REG_SZ, (PBYTE)Path, sizeof(tchar_t)*(tcslen(Path)+1));
|
|
RegCloseKey(Key);
|
|
}
|
|
FreeLibrary(Module);
|
|
return 1;
|
|
}
|
|
|
|
if (Key)
|
|
RegCloseKey(Key);
|
|
return 0;
|
|
}
|
|
|
|
bool_t HaveDPad()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
#endif
|