2008-04-23 12:17:59 -07:00
|
|
|
#include "evas_common.h"
|
|
|
|
#include "evas_engine.h"
|
|
|
|
|
|
|
|
|
|
|
|
typedef int (*evas_engine_wince_close_display)();
|
|
|
|
|
|
|
|
typedef struct Evas_Engine_WinCE_GAPI_Priv Evas_Engine_WinCE_GAPI_Priv;
|
|
|
|
|
|
|
|
|
2008-05-22 04:00:01 -07:00
|
|
|
#define GETGXINFO 0x00020000
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
2008-04-23 12:17:59 -07:00
|
|
|
#define LINK(type,name,import) \
|
|
|
|
name = (gapi_##type)GetProcAddress (gapi_lib, import)
|
|
|
|
|
|
|
|
#define GX_FULLSCREEN 0x01
|
|
|
|
#define GX_NORMALKEYS 0x02
|
|
|
|
|
|
|
|
#define kfDirect555 0x40
|
|
|
|
#define kfDirect565 0x80
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
DWORD cxWidth;
|
|
|
|
DWORD cyHeight;
|
|
|
|
LONG cbxPitch;
|
|
|
|
LONG cbyPitch;
|
|
|
|
LONG cBPP;
|
|
|
|
DWORD ffFormat;
|
|
|
|
} _GAPI_Display_Properties;
|
|
|
|
|
|
|
|
typedef int (*gapi_display_open)(HWND hWnd, DWORD dwFlags);
|
|
|
|
typedef int (*gapi_display_close)();
|
|
|
|
typedef _GAPI_Display_Properties (*gapi_display_properties_get)(void);
|
|
|
|
typedef void* (*gapi_draw_begin)(void);
|
|
|
|
typedef int (*gapi_draw_end)(void);
|
|
|
|
typedef int (*gapi_suspend)(void);
|
|
|
|
typedef int (*gapi_resume)(void);
|
|
|
|
|
|
|
|
gapi_suspend suspend = NULL;
|
|
|
|
gapi_resume resume = NULL;
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_software_wince_gapi_suspend(void)
|
|
|
|
{
|
2008-05-07 23:46:26 -07:00
|
|
|
if (suspend)
|
|
|
|
return suspend();
|
|
|
|
else
|
|
|
|
return 0;
|
2008-04-23 12:17:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_software_wince_gapi_resume(void)
|
|
|
|
{
|
2008-05-07 23:46:26 -07:00
|
|
|
if (resume)
|
|
|
|
return resume();
|
|
|
|
else
|
|
|
|
return 0;
|
2008-04-23 12:17:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct Evas_Engine_WinCE_GAPI_Priv
|
|
|
|
{
|
|
|
|
HMODULE lib;
|
|
|
|
gapi_display_close close_display;
|
|
|
|
gapi_draw_begin draw_begin;
|
|
|
|
gapi_draw_end draw_end;
|
2008-05-22 04:00:01 -07:00
|
|
|
void *buffer;
|
2008-04-23 12:17:59 -07:00
|
|
|
int width;
|
|
|
|
int height;
|
2008-05-09 16:12:00 -07:00
|
|
|
int stride;
|
2008-04-23 12:17:59 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
void *
|
2008-07-17 16:08:29 -07:00
|
|
|
evas_software_wince_gapi_init(HWND window,
|
|
|
|
int width,
|
|
|
|
int height)
|
2008-04-23 12:17:59 -07:00
|
|
|
{
|
2008-07-17 16:08:29 -07:00
|
|
|
WCHAR oemstr[100];
|
2008-04-23 12:17:59 -07:00
|
|
|
_GAPI_Display_Properties prop;
|
|
|
|
HMODULE gapi_lib;
|
|
|
|
Evas_Engine_WinCE_GAPI_Priv *priv;
|
|
|
|
|
|
|
|
gapi_display_open display_open = NULL;
|
|
|
|
gapi_display_close display_close = NULL;
|
|
|
|
gapi_display_properties_get display_properties_get = NULL;
|
|
|
|
gapi_draw_begin draw_begin = NULL;
|
|
|
|
gapi_draw_end draw_end = NULL;
|
|
|
|
|
|
|
|
priv = (Evas_Engine_WinCE_GAPI_Priv *)malloc(sizeof(Evas_Engine_WinCE_GAPI_Priv));
|
|
|
|
if (!priv)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
gapi_lib = LoadLibrary(L"\\Windows\\gx.dll");
|
|
|
|
if (!gapi_lib)
|
|
|
|
{
|
|
|
|
gapi_lib = LoadLibrary(L"gx.dll");
|
2008-06-06 05:14:01 -07:00
|
|
|
if (!gapi_lib)
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
ERR("[Engine] [WinCE GAPI] Can not load gx.dll");
|
2008-06-06 05:14:01 -07:00
|
|
|
goto free_priv;
|
|
|
|
}
|
2008-04-23 12:17:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
LINK(display_open, display_open, L"?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
|
|
|
|
LINK(display_close, display_close, L"?GXCloseDisplay@@YAHXZ");
|
|
|
|
LINK(display_properties_get, display_properties_get, L"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
|
|
|
|
LINK(draw_begin, draw_begin, L"?GXBeginDraw@@YAPAXXZ");
|
|
|
|
LINK(draw_end, draw_end, L"?GXEndDraw@@YAHXZ");
|
|
|
|
LINK(suspend, suspend, L"?GXSuspend@@YAHXZ" );
|
|
|
|
LINK(resume, resume, L"?GXResume@@YAHXZ" );
|
|
|
|
|
|
|
|
if (!display_open ||
|
|
|
|
!display_close ||
|
|
|
|
!display_properties_get ||
|
|
|
|
!draw_begin ||
|
|
|
|
!draw_end ||
|
|
|
|
!suspend ||
|
|
|
|
!resume)
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
ERR("[Engine] [WinCE GAPI] Can not find valid symbols");
|
2008-04-23 12:17:59 -07:00
|
|
|
goto free_lib;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!display_open(window, GX_FULLSCREEN))
|
|
|
|
{
|
2009-10-22 08:22:22 -07:00
|
|
|
ERR("[Engine] [WinCE GAPI] Can not open display");
|
2008-04-23 12:17:59 -07:00
|
|
|
goto free_lib;
|
|
|
|
}
|
|
|
|
|
|
|
|
prop = display_properties_get();
|
|
|
|
|
|
|
|
// verify pixel format
|
|
|
|
if(!(prop.ffFormat & kfDirect565) || (prop.cBPP != 16))
|
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
ERR("display format mismatch");
|
2008-04-23 12:17:59 -07:00
|
|
|
goto close_display;
|
|
|
|
}
|
|
|
|
|
|
|
|
// verify we have a vga device
|
|
|
|
if ((GetSystemMetrics(SM_CXSCREEN) != (int)prop.cxWidth) ||
|
|
|
|
(GetSystemMetrics(SM_CYSCREEN) != (int)prop.cyHeight))
|
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
ERR("display size mismatch");
|
2008-04-23 12:17:59 -07:00
|
|
|
goto close_display;
|
|
|
|
}
|
|
|
|
|
|
|
|
priv->lib = gapi_lib;
|
|
|
|
priv->close_display = display_close;
|
|
|
|
priv->draw_begin = draw_begin;
|
|
|
|
priv->draw_end = draw_end;
|
2008-05-09 16:12:00 -07:00
|
|
|
|
2008-05-22 03:40:40 -07:00
|
|
|
/* GAPI on Ipaq H38** and H39** is completely buggy */
|
2008-05-09 16:12:00 -07:00
|
|
|
/* They are detected as portrait device (width = 240 and height = 320) */
|
|
|
|
/* but the framebuffer is managed like a landscape device : */
|
|
|
|
/*
|
|
|
|
240
|
|
|
|
+---------+
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| | 320
|
|
|
|
| ^^^ |
|
|
|
|
| ||| |
|
|
|
|
| ||| |
|
|
|
|
| ||| |
|
|
|
|
+---------+
|
|
|
|
---->
|
|
|
|
|
|
|
|
*/
|
|
|
|
/* So these devices are considered as landscape devices */
|
|
|
|
/* and width and height are switched. */
|
|
|
|
/* Other devices are managed normally : */
|
|
|
|
/*
|
|
|
|
240
|
|
|
|
+---------+
|
|
|
|
| |---> |
|
|
|
|
| |---> |
|
|
|
|
| |---> |
|
|
|
|
v | |
|
|
|
|
| | 320
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
| |
|
|
|
|
+---------+
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
SystemParametersInfo (SPI_GETOEMINFO, sizeof (oemstr), oemstr, 0);
|
|
|
|
|
|
|
|
if (((oemstr[12] == 'H') &&
|
|
|
|
(oemstr[13] == '3') &&
|
|
|
|
(oemstr[14] == '8')) ||
|
|
|
|
((oemstr[12] == 'H') &&
|
|
|
|
(oemstr[13] == '3') &&
|
|
|
|
(oemstr[14] == '9')))
|
|
|
|
{
|
2008-05-22 04:00:01 -07:00
|
|
|
_GXDeviceInfo gxInfo = { 0 };
|
|
|
|
HDC dc;
|
|
|
|
int result;
|
|
|
|
|
2008-05-09 16:12:00 -07:00
|
|
|
priv->width = prop.cyHeight;
|
|
|
|
priv->height = prop.cxWidth;
|
|
|
|
priv->stride = prop.cbxPitch;
|
2008-05-22 04:00:01 -07:00
|
|
|
|
|
|
|
dc = GetDC (window);
|
|
|
|
if (!dc)
|
2008-06-06 05:14:01 -07:00
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
ERR("Can not get device");
|
2008-06-06 05:14:01 -07:00
|
|
|
goto close_display;
|
|
|
|
}
|
2008-05-22 04:00:01 -07:00
|
|
|
|
|
|
|
gxInfo.Version = 100;
|
|
|
|
result = ExtEscape(dc, GETGXINFO, 0, NULL, sizeof(gxInfo),
|
|
|
|
(char *) &gxInfo);
|
|
|
|
if (result <= 0)
|
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
ERR("ExtEscape failed");
|
2008-05-22 04:00:01 -07:00
|
|
|
ReleaseDC(window, dc);
|
2008-05-23 11:26:41 -07:00
|
|
|
goto close_display;
|
2008-05-22 04:00:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
priv->buffer = gxInfo.pvFrameBuffer;
|
|
|
|
ReleaseDC(window, dc);
|
2008-05-09 16:12:00 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
priv->width = prop.cxWidth;
|
|
|
|
priv->height = prop.cyHeight;
|
|
|
|
priv->stride = prop.cbyPitch;
|
2008-05-22 04:00:01 -07:00
|
|
|
priv->buffer = NULL;
|
2008-05-09 16:12:00 -07:00
|
|
|
}
|
2008-04-23 12:17:59 -07:00
|
|
|
|
2008-07-17 16:08:29 -07:00
|
|
|
if ((priv->width != width) ||
|
|
|
|
(priv->height != height))
|
|
|
|
{
|
2010-10-07 16:46:42 -07:00
|
|
|
ERR("Size mismatch: asked: %dx%d, got: %dx%d",
|
|
|
|
width, height, priv->width, priv->height);
|
2008-07-17 16:08:29 -07:00
|
|
|
goto close_display;
|
|
|
|
}
|
|
|
|
|
2008-04-23 12:17:59 -07:00
|
|
|
return priv;
|
|
|
|
|
|
|
|
close_display:
|
|
|
|
display_close();
|
|
|
|
free_lib:
|
|
|
|
FreeLibrary(gapi_lib);
|
|
|
|
free_priv:
|
|
|
|
free(priv);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_software_wince_gapi_shutdown(void *priv)
|
|
|
|
{
|
|
|
|
Evas_Engine_WinCE_GAPI_Priv *p;
|
|
|
|
|
|
|
|
p = (Evas_Engine_WinCE_GAPI_Priv *)priv;
|
|
|
|
p->close_display();
|
2008-05-07 23:46:26 -07:00
|
|
|
suspend = NULL;
|
|
|
|
resume = NULL;
|
2008-04-23 12:17:59 -07:00
|
|
|
FreeLibrary(p->lib);
|
|
|
|
free(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FB_Output_Buffer *
|
|
|
|
evas_software_wince_gapi_output_buffer_new(void *priv,
|
|
|
|
int width,
|
|
|
|
int height)
|
|
|
|
{
|
|
|
|
FB_Output_Buffer *fbob;
|
|
|
|
void *buffer;
|
|
|
|
|
|
|
|
fbob = calloc(1, sizeof(FB_Output_Buffer));
|
|
|
|
if (!fbob) return NULL;
|
|
|
|
|
|
|
|
buffer = malloc (width * height * 2); /* we are sure to have 16bpp */
|
|
|
|
if (!buffer)
|
|
|
|
{
|
|
|
|
free(fbob);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fbob->priv = priv;
|
|
|
|
|
|
|
|
fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
|
|
|
|
if (fbob->im)
|
2008-05-09 16:12:00 -07:00
|
|
|
fbob->im->stride = ((Evas_Engine_WinCE_GAPI_Priv *)priv)->stride >> 1;
|
2008-04-23 12:17:59 -07:00
|
|
|
|
|
|
|
return fbob;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_software_wince_gapi_output_buffer_free(FB_Output_Buffer *fbob)
|
|
|
|
{
|
|
|
|
free(fbob->im->pixels);
|
|
|
|
free(fbob);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_software_wince_gapi_output_buffer_paste(FB_Output_Buffer *fbob)
|
|
|
|
{
|
|
|
|
Evas_Engine_WinCE_GAPI_Priv *priv;
|
|
|
|
void *buffer;
|
|
|
|
|
|
|
|
priv = (Evas_Engine_WinCE_GAPI_Priv *)fbob->priv;
|
|
|
|
|
|
|
|
buffer = priv->draw_begin();
|
2008-04-26 05:32:29 -07:00
|
|
|
if (!buffer)
|
|
|
|
return;
|
2008-04-23 12:17:59 -07:00
|
|
|
|
2008-05-22 04:00:01 -07:00
|
|
|
if (priv->buffer) buffer = priv->buffer;
|
|
|
|
|
2008-04-23 12:17:59 -07:00
|
|
|
if ((fbob->im->cache_entry.w == priv->width) &&
|
|
|
|
(fbob->im->cache_entry.h == priv->height))
|
|
|
|
memcpy(buffer, fbob->im->pixels,
|
|
|
|
priv->width * priv->height * 2);
|
|
|
|
|
|
|
|
priv->draw_end();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-05-25 10:39:48 -07:00
|
|
|
evas_software_wince_gapi_surface_resize(FB_Output_Buffer *fbob)
|
2008-04-23 12:17:59 -07:00
|
|
|
{
|
|
|
|
}
|