Commit 30606315 authored by Sam Lantinga's avatar Sam Lantinga

Fixed bug #335

Use SetSystemPaletteUse() to get better access to the system palette.

We can still do better palette matching in the case where we aren't
using fullscreen mode or a hardware palette, but that can wait for
another day. :)

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402398
parent 2ec93d3f
...@@ -84,6 +84,9 @@ extern BOOL SDL_windowid; ...@@ -84,6 +84,9 @@ extern BOOL SDL_windowid;
*/ */
extern void WIN_FlushMessageQueue(); extern void WIN_FlushMessageQueue();
/* Called by windows message loop when application is activated */
extern void (*WIN_Activate)(_THIS, BOOL active, BOOL minimized);
/* Called by windows message loop when system palette is available */ /* Called by windows message loop when system palette is available */
extern void (*WIN_RealizePalette)(_THIS); extern void (*WIN_RealizePalette)(_THIS);
......
...@@ -84,6 +84,7 @@ WORD *gamma_saved = NULL; ...@@ -84,6 +84,7 @@ WORD *gamma_saved = NULL;
/* Functions called by the message processing function */ /* Functions called by the message processing function */
LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL; LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL;
void (*WIN_Activate)(_THIS, BOOL active, BOOL iconic);
void (*WIN_RealizePalette)(_THIS); void (*WIN_RealizePalette)(_THIS);
void (*WIN_PaletteChanged)(_THIS, HWND window); void (*WIN_PaletteChanged)(_THIS, HWND window);
void (*WIN_WinPAINT)(_THIS, HDC hdc); void (*WIN_WinPAINT)(_THIS, HDC hdc);
...@@ -348,11 +349,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -348,11 +349,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_ACTIVATE: { case WM_ACTIVATE: {
SDL_VideoDevice *this = current_video; SDL_VideoDevice *this = current_video;
BOOL minimized; BOOL active, minimized;
Uint8 appstate; Uint8 appstate;
minimized = HIWORD(wParam); minimized = HIWORD(wParam);
if ( !minimized && (LOWORD(wParam) != WA_INACTIVE) ) { active = (LOWORD(wParam) != WA_INACTIVE) && !minimized;
if ( active ) {
/* Gain the following states */ /* Gain the following states */
appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS; appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS;
if ( this->input_grab != SDL_GRAB_OFF ) { if ( this->input_grab != SDL_GRAB_OFF ) {
...@@ -367,17 +369,14 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -367,17 +369,14 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
} }
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
if ( WINDIB_FULLSCREEN() ) if ( WINDIB_FULLSCREEN() ) {
{ LoadAygshell();
LoadAygshell(); if( SHFullScreen )
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); }
}
#endif #endif
posted = SDL_PrivateAppActive(1, appstate); posted = SDL_PrivateAppActive(1, appstate);
WIN_GetKeyboardState(); WIN_GetKeyboardState();
} else { } else {
...@@ -401,12 +400,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -401,12 +400,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
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);
#endif #endif
} }
} }
posted = SDL_PrivateAppActive(0, appstate); posted = SDL_PrivateAppActive(0, appstate);
} }
WIN_Activate(this, active, minimized);
return(0); return(0);
} }
break; break;
......
...@@ -87,6 +87,9 @@ static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface); ...@@ -87,6 +87,9 @@ static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface); static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);
/* Windows message handling functions */ /* Windows message handling functions */
static void DIB_GrabStaticColors(HWND window);
static void DIB_ReleaseStaticColors(HWND window);
static void DIB_Activate(_THIS, BOOL active, BOOL minimized);
static void DIB_RealizePalette(_THIS); static void DIB_RealizePalette(_THIS);
static void DIB_PaletteChanged(_THIS, HWND window); static void DIB_PaletteChanged(_THIS, HWND window);
static void DIB_WinPAINT(_THIS, HDC hdc); static void DIB_WinPAINT(_THIS, HDC hdc);
...@@ -176,6 +179,7 @@ static SDL_VideoDevice *DIB_CreateDevice(int devindex) ...@@ -176,6 +179,7 @@ static SDL_VideoDevice *DIB_CreateDevice(int devindex)
device->PumpEvents = DIB_PumpEvents; device->PumpEvents = DIB_PumpEvents;
/* Set up the windows message handling functions */ /* Set up the windows message handling functions */
WIN_Activate = DIB_Activate;
WIN_RealizePalette = DIB_RealizePalette; WIN_RealizePalette = DIB_RealizePalette;
WIN_PaletteChanged = DIB_PaletteChanged; WIN_PaletteChanged = DIB_PaletteChanged;
WIN_WinPAINT = DIB_WinPAINT; WIN_WinPAINT = DIB_WinPAINT;
...@@ -248,36 +252,25 @@ static int DIB_AddMode(_THIS, int bpp, int w, int h) ...@@ -248,36 +252,25 @@ static int DIB_AddMode(_THIS, int bpp, int w, int h)
return(0); return(0);
} }
static HPALETTE DIB_CreatePalette(int bpp) static void DIB_CreatePalette(_THIS, int bpp)
{ {
/* RJR: March 28, 2000 /* RJR: March 28, 2000
moved palette creation here from "DIB_VideoInit" */ moved palette creation here from "DIB_VideoInit" */
HPALETTE handle = NULL; LOGPALETTE *palette;
HDC hdc;
if ( bpp <= 8 ) int ncolors;
{
LOGPALETTE *palette;
HDC hdc;
int ncolors;
int i;
ncolors = 1; ncolors = (1 << bpp);
for ( i=0; i<bpp; ++i ) { palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
ncolors *= 2; ncolors*sizeof(PALETTEENTRY));
} palette->palVersion = 0x300;
palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+ palette->palNumEntries = ncolors;
ncolors*sizeof(PALETTEENTRY)); hdc = GetDC(SDL_Window);
palette->palVersion = 0x300; GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
palette->palNumEntries = ncolors; ReleaseDC(SDL_Window, hdc);
hdc = GetDC(SDL_Window); screen_pal = CreatePalette(palette);
GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry); screen_logpal = palette;
ReleaseDC(SDL_Window, hdc);
handle = CreatePalette(palette);
SDL_free(palette);
}
return handle;
} }
int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
...@@ -371,7 +364,7 @@ int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -371,7 +364,7 @@ int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
if ( vformat->BitsPerPixel <= 8 ) { if ( vformat->BitsPerPixel <= 8 ) {
/* RJR: March 28, 2000 /* RJR: March 28, 2000
moved palette creation to "DIB_CreatePalette" */ moved palette creation to "DIB_CreatePalette" */
screen_pal = DIB_CreatePalette(vformat->BitsPerPixel); DIB_CreatePalette(this, vformat->BitsPerPixel);
} }
/* Fill in some window manager capabilities */ /* Fill in some window manager capabilities */
...@@ -645,16 +638,23 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -645,16 +638,23 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
/* Reset the palette and create a new one if necessary */ /* Reset the palette and create a new one if necessary */
if ( screen_pal != NULL ) { if ( screen_pal != NULL ) {
if ( video->flags & SDL_HWPALETTE ) {
DIB_ReleaseStaticColors(SDL_Window);
}
/* RJR: March 28, 2000 /* RJR: March 28, 2000
delete identity palette if switching from a palettized mode */ delete identity palette if switching from a palettized mode */
DeleteObject(screen_pal); DeleteObject(screen_pal);
screen_pal = NULL; screen_pal = NULL;
} }
if ( screen_logpal != NULL ) {
SDL_free(screen_logpal);
screen_logpal = NULL;
}
if ( bpp <= 8 ) if ( bpp <= 8 )
{ {
/* RJR: March 28, 2000 /* RJR: March 28, 2000
create identity palette switching to a palettized mode */ create identity palette switching to a palettized mode */
screen_pal = DIB_CreatePalette(bpp); DIB_CreatePalette(this, bpp);
} }
style = GetWindowLong(SDL_Window, GWL_STYLE); style = GetWindowLong(SDL_Window, GWL_STYLE);
...@@ -755,12 +755,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -755,12 +755,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
this->UpdateRects = DIB_NormalUpdate; this->UpdateRects = DIB_NormalUpdate;
/* Set video surface flags */ /* Set video surface flags */
if ( bpp <= 8 ) { if ( (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) != 0 ) {
if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
hdc = GetDC(SDL_Window);
SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
ReleaseDC(SDL_Window, hdc);
}
/* BitBlt() maps colors for us */ /* BitBlt() maps colors for us */
video->flags |= SDL_HWPALETTE; video->flags |= SDL_HWPALETTE;
} }
...@@ -885,6 +880,41 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -885,6 +880,41 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
ReleaseDC(SDL_Window, hdc); ReleaseDC(SDL_Window, hdc);
} }
static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b)
{
PALETTEENTRY *entry;
int i;
int nentries = pal->palNumEntries;
for ( i = 0; i < nentries; ++i ) {
entry = &pal->palPalEntry[i];
if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) {
return i;
}
}
return -1;
}
static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b)
{
PALETTEENTRY *entry;
BOOL moved = 0;
entry = &pal->palPalEntry[index];
if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) {
int found = FindPaletteIndex(pal, r, g, b);
if ( found >= 0 ) {
pal->palPalEntry[found] = *entry;
}
entry->peRed = r;
entry->peGreen = g;
entry->peBlue = b;
moved = 1;
}
entry->peFlags = 0;
return moved;
}
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
...@@ -895,23 +925,37 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -895,23 +925,37 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
HDC hdc; HDC hdc;
#endif #endif
int i; int i;
int moved_entries = 0;
/* Update the display palette */ /* Update the display palette */
hdc = GetDC(SDL_Window); hdc = GetDC(SDL_Window);
if ( screen_pal ) { if ( screen_pal ) {
PALETTEENTRY *entries; PALETTEENTRY *entry;
entries = SDL_stack_alloc(PALETTEENTRY, ncolors);
for ( i=0; i<ncolors; ++i ) { for ( i=0; i<ncolors; ++i ) {
entries[i].peRed = colors[i].r; entry = &screen_logpal->palPalEntry[firstcolor+i];
entries[i].peGreen = colors[i].g; entry->peRed = colors[i].r;
entries[i].peBlue = colors[i].b; entry->peGreen = colors[i].g;
entries[i].peFlags = PC_NOCOLLAPSE; entry->peBlue = colors[i].b;
entry->peFlags = PC_NOCOLLAPSE;
}
/* Check to make sure black and white are in position */
if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00);
moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff);
} }
SetPaletteEntries(screen_pal, firstcolor, ncolors, entries); /* FIXME:
If we don't have full access to the palette, what we
really want to do is find the 236 most diverse colors
in the desired palette, set those entries (10-245) and
then map everything into the new system palette.
*/
/* Copy the entries into the system palette */
UnrealizeObject(screen_pal);
SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry);
SelectPalette(hdc, screen_pal, FALSE); SelectPalette(hdc, screen_pal, FALSE);
RealizePalette(hdc); RealizePalette(hdc);
SDL_stack_free(entries);
} }
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
...@@ -928,8 +972,10 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -928,8 +972,10 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
mdc = CreateCompatibleDC(hdc); mdc = CreateCompatibleDC(hdc);
SelectObject(mdc, screen_bmp); SelectObject(mdc, screen_bmp);
SetDIBColorTable(mdc, firstcolor, ncolors, pal); SetDIBColorTable(mdc, firstcolor, ncolors, pal);
BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, if ( moved_entries || !(this->screen->flags & SDL_HWPALETTE) ) {
mdc, 0, 0, SRCCOPY); BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
mdc, 0, 0, SRCCOPY);
}
DeleteDC(mdc); DeleteDC(mdc);
SDL_stack_free(pal); SDL_stack_free(pal);
#endif #endif
...@@ -1048,6 +1094,9 @@ void DIB_VideoQuit(_THIS) ...@@ -1048,6 +1094,9 @@ void DIB_VideoQuit(_THIS)
if ( SDL_Window ) { if ( SDL_Window ) {
/* Delete the screen bitmap (also frees screen->pixels) */ /* Delete the screen bitmap (also frees screen->pixels) */
if ( this->screen ) { if ( this->screen ) {
if ( this->screen->flags & SDL_HWPALETTE ) {
DIB_ReleaseStaticColors(SDL_Window);
}
#ifndef NO_CHANGEDISPLAYSETTINGS #ifndef NO_CHANGEDISPLAYSETTINGS
if ( this->screen->flags & SDL_FULLSCREEN ) { if ( this->screen->flags & SDL_FULLSCREEN ) {
ChangeDisplaySettings(NULL, 0); ChangeDisplaySettings(NULL, 0);
...@@ -1059,6 +1108,14 @@ void DIB_VideoQuit(_THIS) ...@@ -1059,6 +1108,14 @@ void DIB_VideoQuit(_THIS)
} }
this->screen->pixels = NULL; this->screen->pixels = NULL;
} }
if ( screen_pal != NULL ) {
DeleteObject(screen_pal);
screen_pal = NULL;
}
if ( screen_logpal != NULL ) {
SDL_free(screen_logpal);
screen_logpal = NULL;
}
if ( screen_bmp ) { if ( screen_bmp ) {
DeleteObject(screen_bmp); DeleteObject(screen_bmp);
screen_bmp = NULL; screen_bmp = NULL;
...@@ -1097,26 +1154,55 @@ void DIB_VideoQuit(_THIS) ...@@ -1097,26 +1154,55 @@ void DIB_VideoQuit(_THIS)
} }
/* Exported for the windows message loop only */ /* Exported for the windows message loop only */
static void DIB_FocusPalette(_THIS, int foreground) static void DIB_GrabStaticColors(HWND window)
{
HDC hdc;
hdc = GetDC(window);
SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
}
ReleaseDC(window, hdc);
}
static void DIB_ReleaseStaticColors(HWND window)
{
HDC hdc;
hdc = GetDC(window);
SetSystemPaletteUse(hdc, SYSPAL_STATIC);
ReleaseDC(window, hdc);
}
static void DIB_Activate(_THIS, BOOL active, BOOL minimized)
{
if ( screen_pal && (this->screen->flags & SDL_HWPALETTE) ) {
if ( !active ) {
DIB_ReleaseStaticColors(SDL_Window);
DIB_RealizePalette(this);
} else if ( !minimized ) {
DIB_GrabStaticColors(SDL_Window);
DIB_RealizePalette(this);
}
}
}
static void DIB_RealizePalette(_THIS)
{ {
if ( screen_pal != NULL ) { if ( screen_pal != NULL ) {
HDC hdc; HDC hdc;
hdc = GetDC(SDL_Window); hdc = GetDC(SDL_Window);
UnrealizeObject(screen_pal);
SelectPalette(hdc, screen_pal, FALSE); SelectPalette(hdc, screen_pal, FALSE);
if ( RealizePalette(hdc) ) if ( RealizePalette(hdc) ) {
InvalidateRect(SDL_Window, NULL, FALSE); InvalidateRect(SDL_Window, NULL, FALSE);
}
ReleaseDC(SDL_Window, hdc); ReleaseDC(SDL_Window, hdc);
} }
} }
static void DIB_RealizePalette(_THIS)
{
DIB_FocusPalette(this, 1);
}
static void DIB_PaletteChanged(_THIS, HWND window) static void DIB_PaletteChanged(_THIS, HWND window)
{ {
if ( window != SDL_Window ) { if ( window != SDL_Window ) {
DIB_FocusPalette(this, 0); DIB_RealizePalette(this);
} }
} }
......
...@@ -40,6 +40,7 @@ typedef enum ...@@ -40,6 +40,7 @@ typedef enum
struct SDL_PrivateVideoData { struct SDL_PrivateVideoData {
HBITMAP screen_bmp; HBITMAP screen_bmp;
HPALETTE screen_pal; HPALETTE screen_pal;
LOGPALETTE *screen_logpal;
int allow_screensaver; int allow_screensaver;
...@@ -58,6 +59,7 @@ struct SDL_PrivateVideoData { ...@@ -58,6 +59,7 @@ struct SDL_PrivateVideoData {
/* Old variable names */ /* Old variable names */
#define screen_bmp (this->hidden->screen_bmp) #define screen_bmp (this->hidden->screen_bmp)
#define screen_pal (this->hidden->screen_pal) #define screen_pal (this->hidden->screen_pal)
#define screen_logpal (this->hidden->screen_logpal)
#define SDL_nummodes (this->hidden->SDL_nummodes) #define SDL_nummodes (this->hidden->SDL_nummodes)
#define SDL_modelist (this->hidden->SDL_modelist) #define SDL_modelist (this->hidden->SDL_modelist)
......
...@@ -427,6 +427,7 @@ static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface, ...@@ -427,6 +427,7 @@ static int DX5_AllocDDSurface(_THIS, SDL_Surface *surface,
LPDIRECTDRAWSURFACE3 requested, Uint32 flag); LPDIRECTDRAWSURFACE3 requested, Uint32 flag);
/* Windows message handling functions */ /* Windows message handling functions */
static void DX5_Activate(_THIS, BOOL active, BOOL minimized);
static void DX5_RealizePalette(_THIS); static void DX5_RealizePalette(_THIS);
static void DX5_PaletteChanged(_THIS, HWND window); static void DX5_PaletteChanged(_THIS, HWND window);
static void DX5_WinPAINT(_THIS, HDC hdc); static void DX5_WinPAINT(_THIS, HDC hdc);
...@@ -620,6 +621,7 @@ static SDL_VideoDevice *DX5_CreateDevice(int devindex) ...@@ -620,6 +621,7 @@ static SDL_VideoDevice *DX5_CreateDevice(int devindex)
device->PumpEvents = DX5_PumpEvents; device->PumpEvents = DX5_PumpEvents;
/* Set up the windows message handling functions */ /* Set up the windows message handling functions */
WIN_Activate = DX5_Activate;
WIN_RealizePalette = DX5_RealizePalette; WIN_RealizePalette = DX5_RealizePalette;
WIN_PaletteChanged = DX5_PaletteChanged; WIN_PaletteChanged = DX5_PaletteChanged;
WIN_WinPAINT = DX5_WinPAINT; WIN_WinPAINT = DX5_WinPAINT;
...@@ -2421,6 +2423,9 @@ void DX5_VideoQuit(_THIS) ...@@ -2421,6 +2423,9 @@ void DX5_VideoQuit(_THIS)
} }
/* Exported for the windows message loop only */ /* Exported for the windows message loop only */
void DX5_Activate(_THIS, BOOL active, BOOL minimized)
{
}
void DX5_RealizePalette(_THIS) void DX5_RealizePalette(_THIS)
{ {
if ( SDL_palette ) { if ( SDL_palette ) {
......
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