Skip to content

Commit

Permalink
Fixed bug #335
Browse files Browse the repository at this point in the history
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. :)
  • Loading branch information
slouken committed Jul 3, 2007
1 parent c16df4b commit 725697e
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 63 deletions.
3 changes: 3 additions & 0 deletions src/video/wincommon/SDL_lowvideo.h
Expand Up @@ -84,6 +84,9 @@ extern BOOL SDL_windowid;
*/
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 */
extern void (*WIN_RealizePalette)(_THIS);

Expand Down
25 changes: 12 additions & 13 deletions src/video/wincommon/SDL_sysevents.c
Expand Up @@ -84,6 +84,7 @@ WORD *gamma_saved = NULL;

/* Functions called by the message processing function */
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_PaletteChanged)(_THIS, HWND window);
void (*WIN_WinPAINT)(_THIS, HDC hdc);
Expand Down Expand Up @@ -348,11 +349,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

case WM_ACTIVATE: {
SDL_VideoDevice *this = current_video;
BOOL minimized;
BOOL active, minimized;
Uint8 appstate;

minimized = HIWORD(wParam);
if ( !minimized && (LOWORD(wParam) != WA_INACTIVE) ) {
active = (LOWORD(wParam) != WA_INACTIVE) && !minimized;
if ( active ) {
/* Gain the following states */
appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS;
if ( this->input_grab != SDL_GRAB_OFF ) {
Expand All @@ -367,17 +369,14 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
}
#if defined(_WIN32_WCE)
if ( WINDIB_FULLSCREEN() )
{
LoadAygshell();
if( SHFullScreen )
SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
else
ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);

}
if ( WINDIB_FULLSCREEN() ) {
LoadAygshell();
if( SHFullScreen )
SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON);
else
ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
}
#endif

posted = SDL_PrivateAppActive(1, appstate);
WIN_GetKeyboardState();
} else {
Expand All @@ -401,12 +400,12 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON);
else
ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW);

#endif
}
}
posted = SDL_PrivateAppActive(0, appstate);
}
WIN_Activate(this, active, minimized);
return(0);
}
break;
Expand Down
186 changes: 136 additions & 50 deletions src/video/windib/SDL_dibvideo.c
Expand Up @@ -87,6 +87,9 @@ static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);

/* 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_PaletteChanged(_THIS, HWND window);
static void DIB_WinPAINT(_THIS, HDC hdc);
Expand Down Expand Up @@ -176,6 +179,7 @@ static SDL_VideoDevice *DIB_CreateDevice(int devindex)
device->PumpEvents = DIB_PumpEvents;

/* Set up the windows message handling functions */
WIN_Activate = DIB_Activate;
WIN_RealizePalette = DIB_RealizePalette;
WIN_PaletteChanged = DIB_PaletteChanged;
WIN_WinPAINT = DIB_WinPAINT;
Expand Down Expand Up @@ -248,36 +252,25 @@ static int DIB_AddMode(_THIS, int bpp, int w, int h)
return(0);
}

static HPALETTE DIB_CreatePalette(int bpp)
static void DIB_CreatePalette(_THIS, int bpp)
{
/* RJR: March 28, 2000
moved palette creation here from "DIB_VideoInit" */

HPALETTE handle = NULL;

if ( bpp <= 8 )
{
LOGPALETTE *palette;
HDC hdc;
int ncolors;
int i;
LOGPALETTE *palette;
HDC hdc;
int ncolors;

ncolors = 1;
for ( i=0; i<bpp; ++i ) {
ncolors *= 2;
}
palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
ncolors*sizeof(PALETTEENTRY));
palette->palVersion = 0x300;
palette->palNumEntries = ncolors;
hdc = GetDC(SDL_Window);
GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
ReleaseDC(SDL_Window, hdc);
handle = CreatePalette(palette);
SDL_free(palette);
}

return handle;
ncolors = (1 << bpp);
palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
ncolors*sizeof(PALETTEENTRY));
palette->palVersion = 0x300;
palette->palNumEntries = ncolors;
hdc = GetDC(SDL_Window);
GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
ReleaseDC(SDL_Window, hdc);
screen_pal = CreatePalette(palette);
screen_logpal = palette;
}

int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
Expand Down Expand Up @@ -371,7 +364,7 @@ int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
if ( vformat->BitsPerPixel <= 8 ) {
/* RJR: March 28, 2000
moved palette creation to "DIB_CreatePalette" */
screen_pal = DIB_CreatePalette(vformat->BitsPerPixel);
DIB_CreatePalette(this, vformat->BitsPerPixel);
}

/* Fill in some window manager capabilities */
Expand Down Expand Up @@ -645,16 +638,23 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,

/* Reset the palette and create a new one if necessary */
if ( screen_pal != NULL ) {
if ( video->flags & SDL_HWPALETTE ) {
DIB_ReleaseStaticColors(SDL_Window);
}
/* RJR: March 28, 2000
delete identity palette if switching from a palettized mode */
DeleteObject(screen_pal);
screen_pal = NULL;
}
if ( screen_logpal != NULL ) {
SDL_free(screen_logpal);
screen_logpal = NULL;
}
if ( bpp <= 8 )
{
/* RJR: March 28, 2000
create identity palette switching to a palettized mode */
screen_pal = DIB_CreatePalette(bpp);
DIB_CreatePalette(this, bpp);
}

style = GetWindowLong(SDL_Window, GWL_STYLE);
Expand Down Expand Up @@ -755,12 +755,7 @@ SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
this->UpdateRects = DIB_NormalUpdate;

/* Set video surface flags */
if ( bpp <= 8 ) {
if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
hdc = GetDC(SDL_Window);
SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
ReleaseDC(SDL_Window, hdc);
}
if ( (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) != 0 ) {
/* BitBlt() maps colors for us */
video->flags |= SDL_HWPALETTE;
}
Expand Down Expand Up @@ -885,6 +880,41 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
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)
{
Expand All @@ -895,23 +925,37 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
HDC hdc;
#endif
int i;
int moved_entries = 0;

/* Update the display palette */
hdc = GetDC(SDL_Window);
if ( screen_pal ) {
PALETTEENTRY *entries;
PALETTEENTRY *entry;

entries = SDL_stack_alloc(PALETTEENTRY, ncolors);
for ( i=0; i<ncolors; ++i ) {
entries[i].peRed = colors[i].r;
entries[i].peGreen = colors[i].g;
entries[i].peBlue = colors[i].b;
entries[i].peFlags = PC_NOCOLLAPSE;
entry = &screen_logpal->palPalEntry[firstcolor+i];
entry->peRed = colors[i].r;
entry->peGreen = colors[i].g;
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);
RealizePalette(hdc);
SDL_stack_free(entries);
}

#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
Expand All @@ -928,8 +972,10 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
mdc = CreateCompatibleDC(hdc);
SelectObject(mdc, screen_bmp);
SetDIBColorTable(mdc, firstcolor, ncolors, pal);
BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
mdc, 0, 0, SRCCOPY);
if ( moved_entries || !(this->screen->flags & SDL_HWPALETTE) ) {
BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
mdc, 0, 0, SRCCOPY);
}
DeleteDC(mdc);
SDL_stack_free(pal);
#endif
Expand Down Expand Up @@ -1048,6 +1094,9 @@ void DIB_VideoQuit(_THIS)
if ( SDL_Window ) {
/* Delete the screen bitmap (also frees screen->pixels) */
if ( this->screen ) {
if ( this->screen->flags & SDL_HWPALETTE ) {
DIB_ReleaseStaticColors(SDL_Window);
}
#ifndef NO_CHANGEDISPLAYSETTINGS
if ( this->screen->flags & SDL_FULLSCREEN ) {
ChangeDisplaySettings(NULL, 0);
Expand All @@ -1059,6 +1108,14 @@ void DIB_VideoQuit(_THIS)
}
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 ) {
DeleteObject(screen_bmp);
screen_bmp = NULL;
Expand Down Expand Up @@ -1097,26 +1154,55 @@ void DIB_VideoQuit(_THIS)
}

/* 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 ) {
HDC hdc;

hdc = GetDC(SDL_Window);
UnrealizeObject(screen_pal);
SelectPalette(hdc, screen_pal, FALSE);
if ( RealizePalette(hdc) )
if ( RealizePalette(hdc) ) {
InvalidateRect(SDL_Window, NULL, FALSE);
}
ReleaseDC(SDL_Window, hdc);
}
}
static void DIB_RealizePalette(_THIS)
{
DIB_FocusPalette(this, 1);
}
static void DIB_PaletteChanged(_THIS, HWND window)
{
if ( window != SDL_Window ) {
DIB_FocusPalette(this, 0);
DIB_RealizePalette(this);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/video/windib/SDL_dibvideo.h
Expand Up @@ -40,6 +40,7 @@ typedef enum
struct SDL_PrivateVideoData {
HBITMAP screen_bmp;
HPALETTE screen_pal;
LOGPALETTE *screen_logpal;

int allow_screensaver;

Expand All @@ -58,6 +59,7 @@ struct SDL_PrivateVideoData {
/* Old variable names */
#define screen_bmp (this->hidden->screen_bmp)
#define screen_pal (this->hidden->screen_pal)
#define screen_logpal (this->hidden->screen_logpal)
#define SDL_nummodes (this->hidden->SDL_nummodes)
#define SDL_modelist (this->hidden->SDL_modelist)

Expand Down

0 comments on commit 725697e

Please sign in to comment.