/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2006 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

/* Pocket PC GAPI SDL video driver implementation;
Implemented by Dmitry Yakimov - support@activekitten.com
Inspired by http://arisme.free.fr/ports/SDL.php
*/

// TODO: copy surface on window when lost focus
// TODO: test buttons rotation
// TODO: test on be300 and HPC ( check WinDib fullscreen keys catching )
// TODO: test on smartphones
// TODO: windib on SH3 PPC2000 landscape test
// TODO: optimize 8bpp landscape mode

// there is some problems in runnings apps from a device landscape mode
// due to WinCE bugs. Some works and some - does not.
// TODO: finish Axim Dell X30 and user landscape mode, device landscape mode
// TODO: finish Axim Dell X30 user portrait, device landscape stylus conversion
// TODO: fix running GAPI apps from landscape mode - 
//       wince goes to portrait mode, but does not update video memory


#include "SDL.h"
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "../wincommon/SDL_syswm_c.h"
#include "../wincommon/SDL_sysmouse_c.h"
#include "../windib/SDL_dibevents_c.h" 

#include "SDL_gapivideo.h"

#define GAPIVID_DRIVER_NAME "gapi"

#if defined(DEBUG) || defined (_DEBUG) || defined(NDEBUG)
#define REPORT_VIDEO_INFO 1
#else
#define REPORT_VIDEO_INFO 0
#endif

// for testing with GapiEmu
#define USE_GAPI_EMU 0
#define EMULATE_AXIM_X30 0
#define WITHOUT_GAPI 0

#if USE_GAPI_EMU && !REPORT_VIDEO_INFO
#pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.")
#endif

// defined and used in SDL_sysevents.c
extern HINSTANCE aygshell;
extern void SDL_UnregisterApp();
extern int DIB_AddMode(_THIS, int bpp, int w, int h);

/* Initialization/Query functions */
static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
static void GAPI_VideoQuit(_THIS);

/* Hardware surface functions */
static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface);
static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface);
static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface);

/* Windows message handling functions, will not be processed */
static void GAPI_RealizePalette(_THIS);
static void GAPI_PaletteChanged(_THIS, HWND window);
static void GAPI_WinPAINT(_THIS, HDC hdc); 

/* etc. */
static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects);

static HMODULE g_hGapiLib = 0;
#define LINK(type,name,import) \
	if( g_hGapiLib ) \
		name = (PFN##type)GetProcAddress( g_hGapiLib, _T(import) ); 

static char g_bRawBufferAvailable = 0;

/* GAPI driver bootstrap functions */

/* hi res definitions */
typedef struct _RawFrameBufferInfo
{
   WORD wFormat;
   WORD wBPP;
   VOID *pFramePointer;
   int  cxStride;
   int  cyStride;
   int  cxPixels;
   int  cyPixels;
} RawFrameBufferInfo; 

static struct _RawFrameBufferInfo g_RawFrameBufferInfo = {0};

#define GETRAWFRAMEBUFFER   0x00020001

#define FORMAT_565 1
#define FORMAT_555 2
#define FORMAT_OTHER 3

/* Dell Axim x30 hangs when we use GAPI from landscape,
   so lets avoid using GxOpenDisplay there via GETGXINFO trick 
   It seems that GAPI subsystem use the same ExtEscape code.
*/
#define GETGXINFO 0x00020000

typedef struct GXDeviceInfo
{
long Version; //00 (should filled with 100 before calling ExtEscape)
void * pvFrameBuffer; //04
unsigned long cbStride; //08
unsigned long cxWidth; //0c
unsigned long cyHeight; //10
unsigned long cBPP; //14
unsigned long ffFormat; //18
char Unused[0x84-7*4];
} GXDeviceInfo; 

static int GAPI_Available(void)
{
	// try to use VGA display, even on emulator
	HDC hdc = GetDC(NULL); 
	int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&g_RawFrameBufferInfo);
	ReleaseDC(NULL, hdc);
	g_bRawBufferAvailable = result > 0;

#if WITHOUT_GAPI
	return g_bRawBufferAvailable;
#endif

#if USE_GAPI_EMU
	g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll"));
	if( !g_hGapiLib )
	{
		SDL_SetError("Gapi Emu not found!");
	}
	return g_hGapiLib != 0;
#endif

	// try to find gx.dll
	g_hGapiLib = LoadLibrary(_T("\\Windows\\gx.dll"));
	if( !g_hGapiLib )
	{
		g_hGapiLib = LoadLibrary(_T("gx.dll"));
		if( !g_hGapiLib ) return g_bRawBufferAvailable;
	}

	return(1);
}

static int cmpmodes(const void *va, const void *vb)
{
    SDL_Rect *a = *(SDL_Rect **)va;
    SDL_Rect *b = *(SDL_Rect **)vb;
    if ( a->w == b->w )
        return b->h - a->h;
    else
        return b->w - a->w;
}

static int GAPI_AddMode(_THIS, int bpp, int w, int h)
{
	SDL_Rect *mode;
	int i, index;
	int next_mode;

	/* Check to see if we already have this mode */
	if ( bpp < 8 ) {  /* Not supported */
		return(0);
	}
	index = ((bpp+7)/8)-1;
	for ( i=0; i<gapi->SDL_nummodes[index]; ++i ) {
		mode = gapi->SDL_modelist[index][i];
		if ( (mode->w == w) && (mode->h == h) ) {
			return(0);
		}
	}

	/* Set up the new video mode rectangle */
	mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
	if ( mode == NULL ) {
		SDL_OutOfMemory();
		return(-1);
	}
	mode->x = 0;
	mode->y = 0;
	mode->w = w;
	mode->h = h;

	/* Allocate the new list of modes, and fill in the new mode */
	next_mode = gapi->SDL_nummodes[index];
	gapi->SDL_modelist[index] = (SDL_Rect **)
	       SDL_realloc(gapi->SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
	if ( gapi->SDL_modelist[index] == NULL ) {
		SDL_OutOfMemory();
		gapi->SDL_nummodes[index] = 0;
		SDL_free(mode);
		return(-1);
	}
	gapi->SDL_modelist[index][next_mode] = mode;
	gapi->SDL_modelist[index][next_mode+1] = NULL;
	gapi->SDL_nummodes[index]++;

	return(0);
}

static void GAPI_DeleteDevice(SDL_VideoDevice *device)
{
	if( g_hGapiLib )
	{
		FreeLibrary(g_hGapiLib);
		g_hGapiLib = 0;
	}
	SDL_free(device->hidden);
	SDL_free(device);
}

static SDL_VideoDevice *GAPI_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	if( !g_hGapiLib && !g_bRawBufferAvailable)
	{
		if( !GAPI_Available() )
		{
			SDL_SetError("GAPI dll is not found and VGA mode is not available!");
			return 0;
		}
	}

	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, (sizeof *device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
	}
	if ( (device == NULL) || (device->hidden == NULL) ) {
		SDL_OutOfMemory();
		if ( device ) {
			SDL_free(device);
		}
		return(0);
	}
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));

	/* Set the function pointers */
	device->VideoInit = GAPI_VideoInit;
	device->ListModes = GAPI_ListModes;
	device->SetVideoMode = GAPI_SetVideoMode;
	device->UpdateMouse = WIN_UpdateMouse; 
	device->CreateYUVOverlay = NULL;
	device->SetColors = GAPI_SetColors;
	device->UpdateRects = GAPI_UpdateRects;
	device->VideoQuit = GAPI_VideoQuit;
	device->AllocHWSurface = GAPI_AllocHWSurface;
	device->CheckHWBlit = NULL;
	device->FillHWRect = NULL;
	device->SetHWColorKey = NULL;
	device->SetHWAlpha = NULL;
	device->LockHWSurface = GAPI_LockHWSurface;
	device->UnlockHWSurface = GAPI_UnlockHWSurface;
	device->FlipHWSurface = NULL;
	device->FreeHWSurface = GAPI_FreeHWSurface;
	device->SetCaption = WIN_SetWMCaption;
	device->SetIcon = WIN_SetWMIcon;
	device->IconifyWindow = WIN_IconifyWindow;
	device->GrabInput = WIN_GrabInput;
	device->GetWMInfo = WIN_GetWMInfo;
	device->FreeWMCursor = WIN_FreeWMCursor;
	device->CreateWMCursor = WIN_CreateWMCursor; 
	device->ShowWMCursor = WIN_ShowWMCursor;	
	device->WarpWMCursor = WIN_WarpWMCursor; 
    device->CheckMouseMode = WIN_CheckMouseMode;
	device->InitOSKeymap = DIB_InitOSKeymap;
	device->PumpEvents = DIB_PumpEvents;

	/* Set up the windows message handling functions */
	WIN_RealizePalette = GAPI_RealizePalette;
	WIN_PaletteChanged = GAPI_PaletteChanged;
	WIN_WinPAINT = GAPI_WinPAINT;
	HandleMessage = DIB_HandleMessage; 

	device->free = GAPI_DeleteDevice;

	/* Load gapi library */
#define gx device->hidden->gxFunc

    LINK( GXOpenDisplay, gx.GXOpenDisplay,         "?GXOpenDisplay@@YAHPAUHWND__@@K@Z" )
    LINK( GXCloseDisplay, gx.GXCloseDisplay,        "?GXCloseDisplay@@YAHXZ" )
    LINK( GXBeginDraw, gx.GXBeginDraw,           "?GXBeginDraw@@YAPAXXZ" )
    LINK( GXEndDraw, gx.GXEndDraw,             "?GXEndDraw@@YAHXZ" )
    LINK( GXOpenInput, gx.GXOpenInput,           "?GXOpenInput@@YAHXZ" )
    LINK( GXCloseInput, gx.GXCloseInput,          "?GXCloseInput@@YAHXZ" )
    LINK( GXGetDisplayProperties, gx.GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ" )
    LINK( GXGetDefaultKeys, gx.GXGetDefaultKeys,      "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z" )
    LINK( GXSuspend, gx.GXSuspend,             "?GXSuspend@@YAHXZ" )
    LINK( GXResume, gx.GXResume,              "?GXResume@@YAHXZ" )
    LINK( GXSetViewport, gx.GXSetViewport,         "?GXSetViewport@@YAHKKKK@Z" )
    LINK( GXIsDisplayDRAMBuffer, gx.GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ" )

	/* wrong gapi.dll */
	if( !gx.GXOpenDisplay )
	{
		if( g_hGapiLib ) 
		{
			FreeLibrary(g_hGapiLib);
			g_hGapiLib = 0;
		}
	}
	
	if( !gx.GXOpenDisplay && !g_bRawBufferAvailable)
	{
		SDL_SetError("Error: damaged or unknown gapi.dll!\n");
		GAPI_DeleteDevice(device);
		return 0;
	}

	return device;
}

VideoBootStrap GAPI_bootstrap = {
	GAPIVID_DRIVER_NAME, "WinCE GAPI video driver",
	GAPI_Available, GAPI_CreateDevice
};

static void FillStructs(_THIS, BOOL useVga)
{
#ifdef _ARM_
	WCHAR oemstr[100];
#endif
	/* fill a device properties */

	if( !useVga )
	{
		this->hidden->gxProperties = this->hidden->gxFunc.GXGetDisplayProperties();
		this->hidden->needUpdate = 1;
		this->hidden->hiresFix = 0;
		this->hidden->useVga = 0;
		this->hidden->useGXOpenDisplay = 1;

#ifdef _ARM_
		/* check some devices and extract addition info */
		SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr ), oemstr, 0 );

		// buggy iPaq38xx
		if ((oemstr[12] == 'H') && (oemstr[13] == '3') && (oemstr[14] == '8') && (this->hidden->gxProperties.cbxPitch > 0)) 
		{
			this->hidden->videoMem = (PIXEL*)0xac0755a0;
			this->hidden->gxProperties.cbxPitch = -640;
			this->hidden->gxProperties.cbyPitch = 2;
			this->hidden->needUpdate = 0;
		}
#if (EMULATE_AXIM_X30 == 0)
		// buggy Dell Axim X30
		if( _tcsncmp(oemstr, L"Dell Axim X30", 13) == 0 )
#endif
		{
			GXDeviceInfo gxInfo = {0};
			HDC hdc = GetDC(NULL);
			int result;

			gxInfo.Version = 100;
			result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *)&gxInfo);
			if( result > 0 )
			{
				this->hidden->useGXOpenDisplay = 0;
				this->hidden->videoMem = gxInfo.pvFrameBuffer;
				this->hidden->needUpdate = 0;
				this->hidden->gxProperties.cbxPitch = 2;
				this->hidden->gxProperties.cbyPitch = 480;
				this->hidden->gxProperties.cxWidth = gxInfo.cxWidth;
				this->hidden->gxProperties.cyHeight = gxInfo.cyHeight;
				this->hidden->gxProperties.ffFormat = gxInfo.ffFormat;
			}
		}
#endif
	} else
	{
	    this->hidden->needUpdate = 0;		
		this->hidden->hiresFix = 0;
		this->hidden->gxProperties.cBPP = g_RawFrameBufferInfo.wBPP;
		this->hidden->gxProperties.cbxPitch = g_RawFrameBufferInfo.cxStride;
		this->hidden->gxProperties.cbyPitch = g_RawFrameBufferInfo.cyStride;
		this->hidden->gxProperties.cxWidth = g_RawFrameBufferInfo.cxPixels;
		this->hidden->gxProperties.cyHeight = g_RawFrameBufferInfo.cyPixels;
		this->hidden->videoMem = g_RawFrameBufferInfo.pFramePointer;
		this->hidden->useVga = 1;

		switch( g_RawFrameBufferInfo.wFormat )
		{
		case FORMAT_565:
			this->hidden->gxProperties.ffFormat = kfDirect565;
			break;
		case FORMAT_555:
			this->hidden->gxProperties.ffFormat = kfDirect555;
			break;
		default:
			/* unknown pixel format, try define by BPP! */
			switch( g_RawFrameBufferInfo.wBPP )
			{
			case 4:
			case 8:
				this->hidden->gxProperties.ffFormat = kfDirect;
			case 16:
				this->hidden->gxProperties.ffFormat = kfDirect565;
			default:
				this->hidden->gxProperties.ffFormat = kfDirect;
				break;
			}
		}
	}

	if( this->hidden->gxProperties.cBPP != 16 )
	{
		this->hidden->gapiOrientation = SDL_ORIENTATION_UP;
	} else
	if( (this->hidden->gxProperties.cbxPitch > 0) && (this->hidden->gxProperties.cbyPitch > 0 ))
	{
		this->hidden->gapiOrientation = SDL_ORIENTATION_UP;
	} else
	if( (this->hidden->gxProperties.cbxPitch > 0) && (this->hidden->gxProperties.cbyPitch < 0 ))
	{
		this->hidden->gapiOrientation = SDL_ORIENTATION_RIGHT; // ipaq 3660
	} else
	if( (this->hidden->gxProperties.cbxPitch < 0) && (this->hidden->gxProperties.cbyPitch > 0 ))
	{
		this->hidden->gapiOrientation = SDL_ORIENTATION_LEFT; // ipaq 3800
	}
}

static void GAPI_CreatePalette(int ncolors, SDL_Color *colors)
{
  // Setup a custom color palette
   BYTE buffer[ sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY) ];
   int i;
   LOGPALETTE*   pLogical = (LOGPALETTE*)buffer;
   PALETTEENTRY* entries  = pLogical->palPalEntry;
   HPALETTE hPalette;
   HDC hdc;

   for (i = 0; i < ncolors; ++i)
   {
      // Find intensity by replicating the bit patterns over a byte
      entries[i].peRed   = colors[i].r;
      entries[i].peGreen = colors[i].g;
      entries[i].peBlue  = colors[i].b;
      entries[i].peFlags = 0;
   }

   // Create the GDI palette object
   pLogical->palVersion    = 0x0300;
   pLogical->palNumEntries = ncolors;

   hPalette = CreatePalette( pLogical );
   ASSERT(hPalette);
	

   // Realize the palette
   hdc = GetDC(0);

   SelectPalette( hdc, hPalette, FALSE );
   RealizePalette( hdc );

   ReleaseDC( 0, hdc );
   DeleteObject( hPalette );
}

int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
	int i,bpp;

	/* Create the window */
	if ( DIB_CreateWindow(this) < 0 ) {
		return(-1);
	}

	if( g_hGapiLib )
	{
		FillStructs(this, 0);

		// SDL does not supports 2/4bpp mode, so use 16 bpp
		bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;
		
		/* set up normal and landscape mode */
		GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth);	
		GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight);	
	}

	/* add hi-res mode */
	if( g_bRawBufferAvailable && 
		!((gapi->gxProperties.cxWidth == (unsigned)g_RawFrameBufferInfo.cxPixels) && (gapi->gxProperties.cyHeight == (unsigned)g_RawFrameBufferInfo.cyPixels)))
	{
		FillStructs(this, 1);

		// SDL does not supports 2/4bpp mode, so use 16 bpp
		bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;

		/* set up normal and landscape mode */
		GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth);	
		GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight);	
	}

	/* Determine the current screen size */
	this->info.current_w = gapi->gxProperties.cxWidth;
	this->info.current_h = gapi->gxProperties.cyHeight;

	/* Sort the mode lists */
	for ( i=0; i<NUM_MODELISTS; ++i ) {
		if ( gapi->SDL_nummodes[i] > 0 ) {
			SDL_qsort(gapi->SDL_modelist[i], gapi->SDL_nummodes[i], sizeof *gapi->SDL_modelist[i], cmpmodes);
		}
	}

	vformat->BitsPerPixel = this->hidden->gxProperties.cBPP < 8 ? 16 : (unsigned char)this->hidden->gxProperties.cBPP;

	// Get color mask
	if (this->hidden->gxProperties.ffFormat & kfDirect565) {
		vformat->BitsPerPixel = 16;
		vformat->Rmask = 0x0000f800;
		vformat->Gmask = 0x000007e0;
		vformat->Bmask = 0x0000001f;
		this->hidden->videoMode = GAPI_DIRECT_565;
	}
	else
	if (this->hidden->gxProperties.ffFormat & kfDirect555) {
		vformat->BitsPerPixel = 16;
		vformat->Rmask = 0x00007c00;
		vformat->Gmask = 0x000003e0;
		vformat->Bmask = 0x0000001f;
		this->hidden->videoMode = GAPI_DIRECT_555;
	}
	else
	if ((this->hidden->gxProperties.ffFormat & kfDirect) && (this->hidden->gxProperties.cBPP < 8)) {
		// We'll perform the conversion
		vformat->BitsPerPixel = 16;
		vformat->Rmask = 0x0000f800; // 16 bit 565
		vformat->Gmask = 0x000007e0;
		vformat->Bmask = 0x0000001f;
		if (this->hidden->gxProperties.ffFormat & kfDirectInverted)
			this->hidden->invert = (1 << this->hidden->gxProperties.cBPP) - 1;
		this->hidden->colorscale = this->hidden->gxProperties.cBPP < 8 ? 8 - this->hidden->gxProperties.cBPP : 0;
		this->hidden->videoMode = GAPI_MONO;
	}
	else
	if (this->hidden->gxProperties.ffFormat & kfPalette) {
		this->hidden->videoMode = GAPI_PALETTE;
	} 

	/* We're done! */
	return(0);
}

SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
	return(this->hidden->SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
//  	 return (SDL_Rect **) -1;
}

SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
	SDL_Surface *video; 
	Uint32 Rmask, Gmask, Bmask; 
	DWORD style; 
	SDL_Rect allScreen;

	if( bpp < 4 )
	{
		SDL_SetError("1 bpp and 2 bpp modes is not implemented yet!");
		return 0;
	}

	/* Recalculate bitmasks if necessary */
	if (bpp == current->format->BitsPerPixel) {
		video = current;
	}
	else {
		switch(bpp) {
			case 8:
				Rmask = 0;
				Gmask = 0;
				Bmask = 0;
				break;
			case 15:				
			case 16:
				/* Default is 565 unless the display is specifically 555 */
				if (this->hidden->gxProperties.ffFormat & kfDirect555) {
					Rmask = 0x00007c00;
					Gmask = 0x000003e0;
					Bmask = 0x0000001f;
				}
				else {
					Rmask = 0x0000f800;
					Gmask = 0x000007e0;
					Bmask = 0x0000001f;
				}
				break;
			case 24:
			case 32:
				Rmask = 0x00ff0000;
				Gmask = 0x0000ff00;
				Bmask = 0x000000ff;
				break;
			default:
				SDL_SetError("Unsupported Bits Per Pixel format requested");
				return NULL;
		}
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
		if ( video == NULL ) {
			SDL_OutOfMemory();
			return(NULL);
		}
	}

	gapi->userOrientation = SDL_ORIENTATION_UP;
	video->flags = SDL_FULLSCREEN;	/* Clear flags, GAPI supports fullscreen only */

	/* GAPI or VGA? */
	if( g_hGapiLib )
	{
		FillStructs(this, 0);
		if( (((unsigned)width != gapi->gxProperties.cxWidth) || ((unsigned)height != gapi->gxProperties.cyHeight))
			&& (((unsigned)width != gapi->gxProperties.cyHeight) || ((unsigned)height != gapi->gxProperties.cxWidth)))
			FillStructs(this, 1); // gapi is found but we use VGA resolution			
	} else
		FillStructs(this, 1);

	if ( !this->hidden->needUpdate && !this->hidden->videoMem) {
		SDL_SetError("Couldn't get address of video memory, may be unsupported device or bug");
		return(NULL);
	}

	/* detect user landscape mode */
	if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN))) 
		gapi->userOrientation = SDL_ORIENTATION_RIGHT;

	/* shall we apply hires fix? for example when we do not use hires resource */
	gapi->hiresFix = 0;
	if( gapi->userOrientation == SDL_ORIENTATION_RIGHT )
	{
		if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height > GetSystemMetrics(SM_CXSCREEN)))
			gapi->hiresFix = 1;
	} else
		if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height > GetSystemMetrics(SM_CYSCREEN)))
			if( !((width == GetSystemMetrics(SM_CYSCREEN)) && (height == GetSystemMetrics(SM_CXSCREEN)))) // user portrait, device landscape
				gapi->hiresFix = 1;

	switch( gapi->userOrientation )
	{
	case SDL_ORIENTATION_UP:
		gapi->startOffset = 0;
		gapi->dstLineStep = gapi->gxProperties.cbyPitch;
		gapi->dstPixelStep = gapi->gxProperties.cbxPitch;
		break;
	case SDL_ORIENTATION_RIGHT:
		switch( gapi->gapiOrientation )
		{
		case SDL_ORIENTATION_UP:
		case SDL_ORIENTATION_RIGHT:
		case SDL_ORIENTATION_LEFT:
			if( (this->hidden->videoMode == GAPI_MONO) )
				gapi->startOffset = -gapi->gxProperties.cbxPitch + 1; // monochrome mode
			else
				gapi->startOffset = gapi->gxProperties.cbyPitch * (gapi->gxProperties.cyHeight - 1);
				
			gapi->dstLineStep = gapi->gxProperties.cbxPitch;
			gapi->dstPixelStep = -gapi->gxProperties.cbyPitch;
			break;
		}
	}

	video->w = this->hidden->w = width;
	video->h = this->hidden->h = height;
	video->pitch = SDL_CalculatePitch(video); 

	/* Small fix for WinCE/Win32 - when activating window
	   SDL_VideoSurface is equal to zero, so activating code
	   is not called properly for fullscreen windows because
	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
	*/
	SDL_VideoSurface = video;

	/* GAPI is always fullscreen, title bar is useless */
	style = 0;

	if (!SDL_windowid)
		SetWindowLong(SDL_Window, GWL_STYLE, style);

	/* Allocate bitmap */
	if(gapiBuffer) 
	{
		SDL_free(gapiBuffer);
		gapiBuffer = NULL;
	}
	gapiBuffer = SDL_malloc(video->h * video->pitch);
	video->pixels = gapiBuffer; 

	if ( ! this->hidden->buffer ) {
		SDL_SetError("Couldn't allocate buffer for requested mode");
		return(NULL);
	}

	SDL_memset(gapiBuffer, 255, video->h * video->pitch);
	MoveWindow(SDL_Window, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE);
	ShowWindow(SDL_Window, SW_SHOW);
	SetForegroundWindow(SDL_Window);

	/* JC 14 Mar 2006
		Flush the message loop or this can cause big problems later
		Especially if the user decides to use dialog boxes or assert()!
	*/
	WIN_FlushMessageQueue();

	/* Open GAPI display */
	if( !gapi->useVga && this->hidden->useGXOpenDisplay )
		if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) )
		{
			SDL_SetError("Couldn't initialize GAPI");
			return(NULL);
		}

#if REPORT_VIDEO_INFO
	printf("Video properties:\n");
	printf("display bpp: %d\n", gapi->gxProperties.cBPP);
	printf("display width: %d\n", gapi->gxProperties.cxWidth);
	printf("display height: %d\n", gapi->gxProperties.cyHeight);
	printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
	printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
	printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);

	if( !gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate)
	{
		gapi->videoMem = gapi->gxFunc.GXBeginDraw(); 
		gapi->gxFunc.GXEndDraw();
	}

	printf("video memory: 0x%x\n", gapi->videoMem);
	printf("need update: %d\n", gapi->needUpdate);
	printf("hi-res fix: %d\n", gapi->hiresFix);
	printf("VGA is available on the device: %d\n", g_bRawBufferAvailable);
	printf("use raw framebuffer: %d\n", gapi->useVga);
	printf("video surface bpp: %d\n", video->format->BitsPerPixel);
	printf("video surface width: %d\n", video->w);
	printf("video surface height: %d\n", video->h);
#endif


	/* Blank screen */
	allScreen.x = allScreen.y = 0;
	allScreen.w = video->w - 1;
	allScreen.h = video->h - 1;
	GAPI_UpdateRects(this, 1, &allScreen);

	/* We're done */
	return(video);
}

/* We don't actually allow hardware surfaces other than the main one */
static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}
static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

/* We need to wait for vertical retrace on page flipped displays */
static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}

static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static int updateLine8to8(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width, int height, int lines)
{
	if( gapi->dstPixelStep == 1) /* optimized blitting on most devices */
	{
		SDL_memcpy(destPointer, srcPointer, width);
		return 1;
	} else
	{
		// TODO: read 4 pixels, write DWORD
		int step = gapi->dstPixelStep;
		while(width--)
		{
			*destPointer = *srcPointer++;
			destPointer += step;
		}
	}
	return 1;
}

/* Video memory is very slow so lets optimize as much as possible */
static int updateLine16to16(_THIS, PIXEL *srcPointer, PIXEL *destPointer, int width, int height, int lines)
{
	PIXEL *line1, *line2;
	int step = gapi->dstPixelStep / 2;

	if( step == 1 ) /* optimized blitting on most devices */
	{
		SDL_memcpy(destPointer, srcPointer, width * sizeof(PIXEL));
		return 1;
	}
	else
	{
		if( (gapi->gapiOrientation != SDL_ORIENTATION_UP) &&
			(gapi->userOrientation == SDL_ORIENTATION_UP )) // iPaq 3660/3800 and user orientation up
		{	
			// to prevent data misalignment copy only one line
			if( ((((unsigned)destPointer & 3) != 0) && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT)) 
				|| ((((unsigned)destPointer & 3) == 0) && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT))
				|| (lines == 1) ) 
			{
				while(width--)
				{
					*destPointer = *srcPointer++;
					destPointer += step;
				}
				return 1;
			}

			/* read two lines at the same time, write DWORD */
			line1 = srcPointer;
			line2 = srcPointer + SDL_VideoSurface->pitch / 2;

			if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT )
				while(width--) // iPaq 3800
				{
					*(DWORD*)destPointer =(*line2++ << 16) | *line1++;
					destPointer += step;
				}
			else
			{
				destPointer += gapi->gxProperties.cbyPitch / 2;

				while(width--) // iPaq 3660
				{
					*(DWORD*)destPointer =(*line1++ << 16) | *line2++;
					destPointer += step;
				}
			}
			return 2;
		} else
		{
			// iPaq 3800 and user orientation landscape
			if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT )
			{
				int w1;

				// to prevent data misalignment copy only one pixel
				if( (((unsigned)destPointer & 3) == 0) && (width > 0)) 
				{
					*destPointer-- = *srcPointer++;
					width--;
				}

				destPointer--;

				w1 = width / 2;

				while(w1--)
				{
					DWORD p = *(DWORD*)srcPointer;
					*((DWORD*)destPointer) = (p << 16) | (p >> 16);
					destPointer -= 2;
					srcPointer += 2;
				}

				if( width & 1 ) // copy the last pixel
				{
					destPointer++;
					*destPointer = *srcPointer;
				}

				return 1;
			}

			// modern iPaqs and user orientation landscape
			// read two pixels, write DWORD

			line1 = srcPointer;
			line2 = srcPointer + SDL_VideoSurface->pitch / 2;

			if( (((unsigned)destPointer & 3) != 0) || (lines == 1) ) 
			{
				while(width--)
				{
					*destPointer = *srcPointer++;
					destPointer += step;
				}
				return 1;
			}
			
			while(width--)
			{
				*(DWORD*)destPointer =(*line2++ << 16) | *line1++;
				destPointer -= gapi->gxProperties.cbyPitch / 2;
			}
			return 2;
		}
	}
}

// Color component masks for 565
#define REDMASK (31<<11)
#define GREENMASK (63<<5)
#define BLUEMASK (31)


static int updateLine16to4(_THIS, PIXEL *srcPointer, unsigned char *destPointer, int width, int height, int lines, int yNibble, int xNibble)
{
	PIXEL *line1, *line2;
	int step = gapi->dstPixelStep;

	if( gapi->userOrientation == SDL_ORIENTATION_UP )
	{
		if( yNibble ) // copy bottom half of a line
		{
			while(width--)
			{
				PIXEL c1 = *srcPointer++;
				c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);			
				*destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
				destPointer += step;
			}
			return 1;
		}

		// either 1 pixel picture or tail, anyway this is the last line
		if( lines == 1 )
		{
			while(width--)
			{
				PIXEL c1 = *srcPointer++;
				c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);			
				*destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
				destPointer += step;
			}
			return 1;
		}

		line1 = srcPointer;
		line2 = srcPointer + SDL_VideoSurface->pitch / 2;

		while(width--)
		{
			PIXEL c1 = *line1++;
			PIXEL c2 = *line2++;
			c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
			c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK);
			*destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4));
			destPointer += step;
		}
		return 2;
	} else
	{
		int w1;
		w1 = width / 2;

		if( xNibble )
		{
			// copy one pixel
			PIXEL c1 = *srcPointer++;
			c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);			
			*destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
			destPointer++;
		}

		while(w1--)
		{
			PIXEL c1 = *srcPointer;
			PIXEL c2 = *(srcPointer + 1);
			c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);
			c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK);
			*destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4));
			srcPointer += 2;
		}

		// copy tail
		if( (width & 1) && !xNibble )
		{
			PIXEL c1 = *srcPointer;
			c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK);			
			*destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
		}

		return 1;
	}
}

static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects)
{
	int i, height;
	int linesProcessed;
	int xNibble, yNibble;

	for (i=0; i<numrects; i++)
	{
		unsigned char *destPointer;
		unsigned char *srcPointer;

		if( gapi->userOrientation == SDL_ORIENTATION_UP )
			destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset - rects[i].y * gapi->gxProperties.cBPP / 8 + rects[i].x * gapi->dstPixelStep;
		else
			destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].x * gapi->gxProperties.cBPP / 8 + rects[i].y * gapi->dstLineStep;

		srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2;
		yNibble = rects[i].y & 1; // TODO: only for 4 bpp
		xNibble = rects[i].x & 1;
		height = rects[i].h;
		while (height > 0)
		{
			switch(gapi->gxProperties.cBPP)
			{
			case 2: // TODO
			case 4:
					linesProcessed = updateLine16to4(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height, yNibble, xNibble);
					yNibble = 0;
			}
			height -= linesProcessed;
			if( gapi->userOrientation == SDL_ORIENTATION_UP )
				destPointer--; // always fill 1 byte
			else destPointer += gapi->dstLineStep;
			srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes
		}
	}
}

static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects)
{
	int i, height;
	int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8;
	int linesProcessed;
	for (i=0; i<numrects; i++) {
		unsigned char *destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep;
		unsigned char *srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel;
		height = rects[i].h;

//		fprintf(stderr, "Starting rect %dx%d, dst=0x%x, w = %d, h = %d\n", rects[i].w, rects[i].h,destPointer,rects[i].w,rects[i].h);
//		fflush(stderr);
		linesProcessed = height;

		while (height > 0) {
			switch(bytesPerPixel)
			{
			case 1:
				linesProcessed = updateLine8to8(this, srcPointer, (unsigned char *) destPointer, rects[i].w, rects[i].h, height);
				break;
			case 2:
#pragma warning(disable: 4133)
				linesProcessed = updateLine16to16(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height);
				break;
			}
			height -= linesProcessed;
			destPointer += gapi->dstLineStep * linesProcessed;
			srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes
		}
//		fprintf(stderr, "End of rect\n");
//		fflush(stderr);
	}
}


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 )
		gapi->videoMem = gapi->gxFunc.GXBeginDraw(); 

	if( gapi->gxProperties.cBPP < 8 )
		GAPI_UpdateRectsMono(this, numrects, rects);
	else
		GAPI_UpdateRectsColor(this, numrects, rects);

	if( gapi->needUpdate )
		gapi->gxFunc.GXEndDraw();
}

/* Note:  If we are terminated, this could be called in the middle of
   another SDL video routine -- notably UpdateRects.
*/
void GAPI_VideoQuit(_THIS)
{
	int i, j;
	/* Destroy the window and everything associated with it */
	if ( SDL_Window ) 
	{
	    if ((g_hGapiLib != 0) && this && this->hidden && this->hidden->gxFunc.GXCloseDisplay && !this->hidden->useVga)
			this->hidden->gxFunc.GXCloseDisplay(); 

		if (this->screen->pixels != NULL)
		{
			SDL_free(this->screen->pixels);
			this->screen->pixels = NULL;
		}
		if ( screen_icn ) {
			DestroyIcon(screen_icn);
			screen_icn = NULL;
		}

		DIB_DestroyWindow(this);
		SDL_UnregisterApp();

		SDL_Window = NULL;
#if defined(_WIN32_WCE)

// Unload wince aygshell library to prevent leak
		if( aygshell ) 
		{
			FreeLibrary(aygshell);
			aygshell = NULL;
		}
#endif

	/* Free video mode lists */
	for ( i=0; i<NUM_MODELISTS; ++i ) {
		if ( gapi->SDL_modelist[i] != NULL ) {
			for ( j=0; gapi->SDL_modelist[i][j]; ++j )
				SDL_free(gapi->SDL_modelist[i][j]);
			SDL_free(gapi->SDL_modelist[i]);
			gapi->SDL_modelist[i] = NULL;
		}
	}

	}

}

static void GAPI_RealizePalette(_THIS)
{
	OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
}

static void GAPI_PaletteChanged(_THIS, HWND window)
{
	OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
}

static void GAPI_WinPAINT(_THIS, HDC hdc)
{
	// draw current offscreen buffer on hdc

	int bpp = 16; // we always use either 8 or 16 bpp internally
	HGDIOBJ prevObject;
	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);
	prevObject = SelectObject(srcDC, hb);

	BitBlt(hdc, 0, 0, this->hidden->w, this->hidden->h, srcDC, 0, 0, SRCCOPY);

	SelectObject(srcDC, prevObject);
	DeleteObject(hb);
	DeleteDC(srcDC);
}

int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 
{
	GAPI_CreatePalette(ncolors, colors);
	return 1;
}
