root/sys/arch/hpcmips/stand/pbsdboot/palette.c
/*      $NetBSD: palette.c,v 1.3 2001/02/25 12:58:38 takemura Exp $     */

/*-
 * Copyright (c) 1999 Shin Takemura.
 * All rights reserved.
 *
 * This software is part of the PocketBSD.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the PocketBSD project
 *      and its contributors.
 * 4. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include <pbsdboot.h>

#include <dev/hpc/hpccmapvar.h>

/*
 * If Windows have no color palette, we have nothing to do here.
 */
#if ( _WIN32_WCE >= 200 ) // WIN CE Ver 2.00 or greater
#define HAVE_COLOR_PALETTE
#endif

#ifndef ASSERT
#define ASSERT(a) \
        if (!(a)) { \
                msg_printf(MSG_ERROR, TEXT("assertion failure"), \
                        TEXT(#a)); \
        }
#endif /* !ASSERT */

#ifdef HAVE_COLOR_PALETTE
enum palette_status palette_succeeded = PAL_ERROR;
static void palette_setup(PALETTEENTRY *pal);
#else
enum palette_status palette_succeeded = PAL_NOERROR;
#endif

static HPALETTE pal = NULL;

void
palette_init(HWND hWnd)
{
#ifdef HAVE_COLOR_PALETTE
        HDC hdc;
        PAINTSTRUCT ps;
        LOGPALETTE* logpal;

        debug_printf(TEXT("*** palette init ***\n"));
        
        hdc = BeginPaint(hWnd, &ps);
        if (GetDeviceCaps(hdc, TECHNOLOGY) == DT_RASDISPLAY &&
            (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) &&
            GetDeviceCaps(hdc, COLORRES) == 8) {
                ASSERT(GetDeviceCaps(hdc, BITSPIXEL) == 8);
                ASSERT(GetDeviceCaps(hdc, PLANES) == 1);
                /*
                 * create logical palette
                 */
                logpal = LocalAlloc (LPTR,
                                     (sizeof(LOGPALETTE) +
                                      sizeof(PALETTEENTRY) * 256));
                logpal->palVersion = 0x300;
                logpal->palNumEntries = 256;
                palette_setup(logpal->palPalEntry);

                pal = CreatePalette(logpal);
                if (pal == NULL) {
                        debug_printf(TEXT("CreatePalette() failed"));
                        msg_printf(MSG_ERROR, TEXT("Error"),
                                   TEXT("CreatePalette() failed: %d"),
                                   GetLastError());
                }
                LocalFree((HLOCAL)logpal);
        } else {
                /*
                 * The screen is not 8 bit depth nor indexed color.
                 */
                palette_succeeded = PAL_NOERROR;
        }
        EndPaint(hWnd, &ps);
#endif /* HAVE_COLOR_PALETTE */
}

#ifdef HAVE_COLOR_PALETTE
static void
palette_setup(PALETTEENTRY *pal)
{
        int i;

        for (i = 0; i < 256; i++) {
                pal[i].peFlags = PC_EXPLICIT;
                pal[i].peRed = bivideo_cmap_r[i];
                pal[i].peGreen = bivideo_cmap_g[i];
                pal[i].peBlue = bivideo_cmap_b[i];
        }
}
#endif /* HAVE_COLOR_PALETTE */

void
palette_set(HWND hWnd)
{
#ifdef HAVE_COLOR_PALETTE
        int n;
        HDC hdc;
        PAINTSTRUCT ps;
        HPALETTE prev_pal;

        debug_printf(TEXT("*** palette set ***\n"));

        if (pal != NULL) {
                hdc = BeginPaint(hWnd, &ps);
                prev_pal = SelectPalette(hdc, pal, FALSE);
                if (prev_pal == NULL) {
                        debug_printf(TEXT("SelectPalette() failed"));
                        msg_printf(MSG_ERROR, TEXT("Error"),
                            TEXT("SelectPalette() failed: %d"),
                            GetLastError());
                } else {
                        n = RealizePalette(hdc);
                        debug_printf(TEXT("RealizePalette() = %d\n"), n);
                        if (n == GDI_ERROR) {
                                debug_printf(TEXT("RealizePalette() failed"));
                                msg_printf(MSG_ERROR, TEXT("Error"),
                                    TEXT("RealizePalette() failed: %d"),
                                    GetLastError());
                        }
                }
                EndPaint(hWnd, &ps);
        }
#endif /* HAVE_COLOR_PALETTE */
}

void
palette_check(HWND hWnd)
{
#ifdef HAVE_COLOR_PALETTE
        HDC hdc;
        PAINTSTRUCT ps;
        PALETTEENTRY syspal[256];
        PALETTEENTRY canonpal[256];
        int i, n, error;

        debug_printf(TEXT("*** palette check ***\n"));

        error = 0;
        if (pal != NULL) {
                hdc = BeginPaint(hWnd, &ps);

                palette_setup(canonpal);

                n = GetSystemPaletteEntries(hdc, 0, 256, syspal);
                if (n == 0) {
                        msg_printf(MSG_ERROR, TEXT("Error"),
                            TEXT("GetSystemPaletteEntries() failed: %d"),
                            GetLastError());
                        error++;
                } else {
                        for (i = 0; i < n; i++) {
                                debug_printf(TEXT("%3d: %02x %02x %02x"),
                                    i,
                                    syspal[i].peRed,
                                    syspal[i].peGreen,
                                    syspal[i].peBlue);
                                if (syspal[i].peRed != canonpal[i].peRed ||
                                    syspal[i].peGreen != canonpal[i].peGreen ||
                                    syspal[i].peBlue != canonpal[i].peBlue ) {
                                        debug_printf(TEXT(" *"));
                                        error++;
                                }
                                debug_printf(TEXT("\n"));
                        }                       
                }
                EndPaint(hWnd, &ps);
                if (error) {
                        palette_succeeded = PAL_ERROR;
                } else {
                        palette_succeeded = PAL_SUCCEEDED;
                }
        }
#endif /* HAVE_COLOR_PALETTE */
}