Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*	$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 */
}