Commit cd3a1db9 authored by Sam Lantinga's avatar Sam Lantinga

Fixes from Dmitry Yakimov:

fixed bugs 159 and 160:

+ added threaded timers support
! fixed restoring sdl window focus (AV in windows message handler)
! disabled forgotten cdrom and joystick in config file.
* disabled minimizing sdl window while loosing focus.
  PocketPC does not have a task bar, so it is an inconvenient and unusual
  behaviour for PPC users.
+ added WIN_Paint handler for GAPI
! fixed loosing focus while using GAPI videi driver

+ added TestTimer project
* removed unnecessary macros (ENABLE_WINDIB ...) from projects

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401501
parent a5db090e
No preview for this file type
...@@ -117,10 +117,18 @@ typedef unsigned int uintptr_t; ...@@ -117,10 +117,18 @@ typedef unsigned int uintptr_t;
#define SDL_AUDIO_DRIVER_WAVEOUT 1 #define SDL_AUDIO_DRIVER_WAVEOUT 1
/* Enable various cdrom drivers */ /* Enable various cdrom drivers */
#define SDL_CDROM_WIN32 1 #ifdef _WIN32_WCE
#define SDL_CDROM_DISABLED 1
#else
#define SDL_CDROM_WIN32 1
#endif
/* Enable various input drivers */ /* Enable various input drivers */
#ifdef _WIN32_WCE
#define SDL_JOYSTICK_DISABLED 1
#else
#define SDL_JOYSTICK_WINMM 1 #define SDL_JOYSTICK_WINMM 1
#endif
/* Enable various shared object loading systems */ /* Enable various shared object loading systems */
#define SDL_LOADSO_WIN32 1 #define SDL_LOADSO_WIN32 1
...@@ -136,12 +144,12 @@ typedef unsigned int uintptr_t; ...@@ -136,12 +144,12 @@ typedef unsigned int uintptr_t;
#endif #endif
/* Enable various video drivers */ /* Enable various video drivers */
#ifndef _WIN32_WCE
#define SDL_VIDEO_DRIVER_DDRAW 1
#endif
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
#define SDL_VIDEO_DRIVER_GAPI 1 #define SDL_VIDEO_DRIVER_GAPI 1
#endif #endif
#ifndef _WIN32_WCE
#define SDL_VIDEO_DRIVER_DDRAW 1
#endif
#define SDL_VIDEO_DRIVER_WINDIB 1 #define SDL_VIDEO_DRIVER_WINDIB 1
/* Enable OpenGL support */ /* Enable OpenGL support */
......
...@@ -30,10 +30,6 @@ ...@@ -30,10 +30,6 @@
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead. #error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead.
/* but if you really want to use this file, use these #defines... */
#define USE_GETTICKCOUNT
#define USE_SETTIMER
#endif #endif
#define TIME_WRAP_VALUE (~(DWORD)0) #define TIME_WRAP_VALUE (~(DWORD)0)
...@@ -111,62 +107,6 @@ void SDL_Delay(Uint32 ms) ...@@ -111,62 +107,6 @@ void SDL_Delay(Uint32 ms)
Sleep(ms); Sleep(ms);
} }
#ifdef USE_SETTIMER
static UINT WIN_timer;
int SDL_SYS_TimerInit(void)
{
return(0);
}
void SDL_SYS_TimerQuit(void)
{
return;
}
/* Forward declaration because this is called by the timer callback */
int SDL_SYS_StartTimer(void);
static VOID CALLBACK TimerCallbackProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
Uint32 ms;
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms != SDL_alarm_interval ) {
KillTimer(NULL, idEvent);
if ( ms ) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
SDL_SYS_StartTimer();
} else {
SDL_alarm_interval = 0;
}
}
}
int SDL_SYS_StartTimer(void)
{
int retval;
WIN_timer = SetTimer(NULL, 0, SDL_alarm_interval, TimerCallbackProc);
if ( WIN_timer ) {
retval = 0;
} else {
retval = -1;
}
return retval;
}
void SDL_SYS_StopTimer(void)
{
if ( WIN_timer ) {
KillTimer(NULL, WIN_timer);
WIN_timer = 0;
}
}
#else /* !USE_SETTIMER */
/* Data to handle a single periodic alarm */ /* Data to handle a single periodic alarm */
static UINT timerID = 0; static UINT timerID = 0;
...@@ -215,4 +155,3 @@ void SDL_SYS_StopTimer(void) ...@@ -215,4 +155,3 @@ void SDL_SYS_StopTimer(void)
return; return;
} }
#endif /* USE_SETTIMER */
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#include "SDL_thread.h"
#include "SDL_timer.h" #include "SDL_timer.h"
#include "../SDL_timer_c.h" #include "../SDL_timer_c.h"
...@@ -91,53 +92,103 @@ void SDL_StartTicks(void) ...@@ -91,53 +92,103 @@ void SDL_StartTicks(void)
static UINT WIN_timer; static UINT WIN_timer;
#if ( _WIN32_WCE <= 420 )
static HANDLE timersThread = 0;
static HANDLE timersQuitEvent = 0;
DWORD TimersThreadProc(void *data)
{
while(WaitForSingleObject(timersQuitEvent, 10) == WAIT_TIMEOUT)
{
SDL_ThreadedTimerCheck();
}
return 0;
}
int SDL_SYS_TimerInit(void) int SDL_SYS_TimerInit(void)
{ {
return(0); // create a thread to process a threaded timers
// SetTimer does not suit the needs because
// TimerCallbackProc will be called only when WM_TIMER occured
timersQuitEvent = CreateEvent(0, TRUE, FALSE, 0);
if( !timersQuitEvent )
{
SDL_SetError("Cannot create event for timers thread");
return -1;
}
timersThread = CreateThread(NULL, 0, TimersThreadProc, 0, 0, 0);
if( !timersThread )
{
SDL_SetError("Cannot create timers thread, check amount of RAM available");
return -1;
}
SetThreadPriority(timersThread, THREAD_PRIORITY_HIGHEST);
return(SDL_SetTimerThreaded(1));
} }
void SDL_SYS_TimerQuit(void) void SDL_SYS_TimerQuit(void)
{ {
SetEvent(timersQuitEvent);
if( WaitForSingleObject(timersThread, 2000) == WAIT_TIMEOUT )
TerminateThread(timersThread, 0);
CloseHandle(timersThread);
CloseHandle(timersQuitEvent);
return; return;
} }
/* Forward declaration because this is called by the timer callback */ #else
int SDL_SYS_StartTimer(void);
#pragma comment(lib, "mmtimer.lib")
/* Data to handle a single periodic alarm */
static UINT timerID = 0;
static VOID CALLBACK TimerCallbackProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) static void CALLBACK HandleAlarm(UINT uID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2)
{ {
Uint32 ms; SDL_ThreadedTimerCheck();
ms = SDL_alarm_callback(SDL_alarm_interval);
if ( ms != SDL_alarm_interval ) {
KillTimer(NULL, idEvent);
if ( ms ) {
SDL_alarm_interval = ROUND_RESOLUTION(ms);
SDL_SYS_StartTimer();
} else {
SDL_alarm_interval = 0;
}
}
} }
int SDL_SYS_StartTimer(void)
int SDL_SYS_TimerInit(void)
{ {
int retval; MMRESULT result;
WIN_timer = SetTimer(NULL, 0, SDL_alarm_interval, TimerCallbackProc); /* Set timer resolution */
if ( WIN_timer ) { result = timeBeginPeriod(TIMER_RESOLUTION);
retval = 0; if ( result != TIMERR_NOERROR ) {
} else { SDL_SetError("Warning: Can't set %d ms timer resolution",
retval = -1; TIMER_RESOLUTION);
}
/* Allow 10 ms of drift so we don't chew on CPU */
timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
if ( ! timerID ) {
SDL_SetError("timeSetEvent() failed");
return(-1);
} }
return retval; return(SDL_SetTimerThreaded(1));
} }
void SDL_SYS_StopTimer(void) void SDL_SYS_TimerQuit(void)
{ {
if ( WIN_timer ) { if ( timerID ) {
KillTimer(NULL, WIN_timer); timeKillEvent(timerID);
WIN_timer = 0;
} }
timeEndPeriod(TIMER_RESOLUTION);
} }
#endif
int SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: WinCE uses threaded timer");
return(-1);
}
void SDL_SYS_StopTimer(void)
{
return;
}
...@@ -1088,6 +1088,9 @@ static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects) ...@@ -1088,6 +1088,9 @@ static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects)
static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects) static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{ {
// we do not want to corrupt video memory
if( gapi->suspended ) return;
if( gapi->needUpdate ) if( gapi->needUpdate )
gapi->videoMem = gapi->gxFunc.GXBeginDraw(); gapi->videoMem = gapi->gxFunc.GXBeginDraw();
...@@ -1172,10 +1175,55 @@ static void GAPI_PaletteChanged(_THIS, HWND window) ...@@ -1172,10 +1175,55 @@ static void GAPI_PaletteChanged(_THIS, HWND window)
OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n")); OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
} }
/* Exported for the windows message loop only */
static void GAPI_WinPAINT(_THIS, HDC hdc) static void GAPI_WinPAINT(_THIS, HDC hdc)
{ {
OutputDebugString(TEXT("GAPI_WinPAINT NOT IMPLEMENTED !\r\n")); // draw current offscreen buffer on hdc
int bpp = 16; // we always use either 8 or 16 bpp internally
unsigned short *bitmapData;
HBITMAP hb;
HDC srcDC;
// Create a DIB
BYTE buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)] = {0};
BITMAPINFO* pBMI = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* pHeader = &pBMI->bmiHeader;
DWORD* pColors = (DWORD*)&pBMI->bmiColors;
// CreateDIBSection does not support 332 pixel format on wce
if( gapi->gxProperties.cBPP == 8 ) return;
// DIB Header
pHeader->biSize = sizeof(BITMAPINFOHEADER);
pHeader->biWidth = this->hidden->w;
pHeader->biHeight = -this->hidden->h;
pHeader->biPlanes = 1;
pHeader->biBitCount = bpp;
pHeader->biCompression = BI_RGB;
pHeader->biSizeImage = (this->hidden->w * this->hidden->h * bpp) / 8;
// Color masks
if( bpp == 16 )
{
pColors[0] = REDMASK;
pColors[1] = GREENMASK;
pColors[2] = BLUEMASK;
pHeader->biCompression = BI_BITFIELDS;
}
// Create the DIB
hb = CreateDIBSection( 0, pBMI, DIB_RGB_COLORS, (void**)&bitmapData, 0, 0 );
// copy data
// FIXME: prevent misalignment, but I've never seen non aligned width of screen
memcpy(bitmapData, this->hidden->buffer, pHeader->biSizeImage);
srcDC = CreateCompatibleDC(hdc);
SelectObject(srcDC, hb);
BitBlt(hdc, 0, 0, this->hidden->w, this->hidden->h, srcDC, 0, 0, SRCCOPY);
DeleteObject(hb);
DeleteDC(srcDC);
} }
int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
......
...@@ -152,6 +152,7 @@ struct SDL_PrivateVideoData { ...@@ -152,6 +152,7 @@ struct SDL_PrivateVideoData {
int dstPixelStep; // in bytes int dstPixelStep; // in bytes
int startOffset; // in bytes int startOffset; // in bytes
int useVga; int useVga;
int suspended; // do not pu anything into video memory
}; };
......
...@@ -106,7 +106,7 @@ static void LoadAygshell(void) ...@@ -106,7 +106,7 @@ static void LoadAygshell(void)
{ {
if( !aygshell ) if( !aygshell )
aygshell = SDL_LoadObject("aygshell.dll"); aygshell = SDL_LoadObject("aygshell.dll");
if( aygshell ) if( (aygshell != 0) && (SHFullScreen == 0) )
{ {
SHFullScreen = (int (WINAPI *)(struct HWND__ *,unsigned long)) SDL_LoadFunction(aygshell, "SHFullScreen"); SHFullScreen = (int (WINAPI *)(struct HWND__ *,unsigned long)) SDL_LoadFunction(aygshell, "SHFullScreen");
} }
...@@ -171,7 +171,19 @@ static void GapiTransform(SDL_ScreenOrientation rotate, char hires, Sint16 *x, S ...@@ -171,7 +171,19 @@ static void GapiTransform(SDL_ScreenOrientation rotate, char hires, Sint16 *x, S
static void SDL_RestoreGameMode(void) static void SDL_RestoreGameMode(void)
{ {
#ifdef _WIN32_WCE
SDL_VideoDevice *this = current_video;
if(SDL_strcmp(this->name, "gapi") == 0)
{
if( this->hidden->suspended )
{
this->hidden->suspended = 0;
}
}
#else
ShowWindow(SDL_Window, SW_RESTORE); ShowWindow(SDL_Window, SW_RESTORE);
#endif
#ifndef NO_CHANGEDISPLAYSETTINGS #ifndef NO_CHANGEDISPLAYSETTINGS
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN); ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
...@@ -180,7 +192,21 @@ static void SDL_RestoreGameMode(void) ...@@ -180,7 +192,21 @@ static void SDL_RestoreGameMode(void)
} }
static void SDL_RestoreDesktopMode(void) static void SDL_RestoreDesktopMode(void)
{ {
#ifdef _WIN32_WCE
SDL_VideoDevice *this = current_video;
if(SDL_strcmp(this->name, "gapi") == 0)
{
if( !this->hidden->suspended )
{
this->hidden->suspended = 1;
}
}
#else
/* WinCE does not have a taskbar, so minimizing is not convenient */
ShowWindow(SDL_Window, SW_MINIMIZE); ShowWindow(SDL_Window, SW_MINIMIZE);
#endif
#ifndef NO_CHANGEDISPLAYSETTINGS #ifndef NO_CHANGEDISPLAYSETTINGS
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
ChangeDisplaySettings(NULL, 0); ChangeDisplaySettings(NULL, 0);
...@@ -318,7 +344,7 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -318,7 +344,7 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
if ( WINDIB_FULLSCREEN() ) if ( WINDIB_FULLSCREEN() )
{ {
LoadAygshell(); LoadAygshell();
if( aygshell ) if( SHFullScreen )
SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON); SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
else else
ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
...@@ -345,7 +371,7 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -345,7 +371,7 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SDL_RestoreDesktopMode(); SDL_RestoreDesktopMode();
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
LoadAygshell(); LoadAygshell();
if( aygshell ) if( SHFullScreen )
SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON); SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
else else
ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW); ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment