move around - flatter.
[profile/ivi/evas.git] / src / modules / engines / software_16_wince / evas_wince_gapi_buffer.c
1 #include "evas_common.h"
2 #include "evas_engine.h"
3
4
5 typedef int (*evas_engine_wince_close_display)();
6
7 typedef struct Evas_Engine_WinCE_GAPI_Priv Evas_Engine_WinCE_GAPI_Priv;
8
9
10 #define GETGXINFO 0x00020000
11
12 typedef struct
13 {
14     long Version;               //00 (should filled with 100 before calling ExtEscape)
15     void *pvFrameBuffer;        //04
16     unsigned long cbStride;     //08
17     unsigned long cxWidth;      //0c
18     unsigned long cyHeight;     //10
19     unsigned long cBPP;         //14
20     unsigned long ffFormat;     //18
21     char Unused[0x84 - 7 * 4];
22 } _GXDeviceInfo;
23
24
25 #define LINK(type,name,import) \
26   name = (gapi_##type)GetProcAddress (gapi_lib, import)
27
28 #define GX_FULLSCREEN 0x01
29 #define GX_NORMALKEYS 0x02
30
31 #define kfDirect555   0x40
32 #define kfDirect565   0x80
33
34
35 typedef struct
36 {
37    DWORD cxWidth;
38    DWORD cyHeight;
39    LONG  cbxPitch;
40    LONG  cbyPitch;
41    LONG  cBPP;
42    DWORD ffFormat;
43 } _GAPI_Display_Properties;
44
45 typedef int                      (*gapi_display_open)(HWND hWnd, DWORD dwFlags);
46 typedef int                      (*gapi_display_close)();
47 typedef _GAPI_Display_Properties (*gapi_display_properties_get)(void);
48 typedef void*                    (*gapi_draw_begin)(void);
49 typedef int                      (*gapi_draw_end)(void);
50 typedef int                      (*gapi_suspend)(void);
51 typedef int                      (*gapi_resume)(void);
52
53 gapi_suspend          suspend = NULL;
54 gapi_resume           resume = NULL;
55
56 int
57 evas_software_wince_gapi_suspend(void)
58 {
59    if (suspend)
60      return suspend();
61    else
62      return 0;
63 }
64
65 int
66 evas_software_wince_gapi_resume(void)
67 {
68    if (resume)
69      return resume();
70    else
71      return 0;
72 }
73
74
75 struct Evas_Engine_WinCE_GAPI_Priv
76 {
77    HMODULE            lib;
78    gapi_display_close close_display;
79    gapi_draw_begin    draw_begin;
80    gapi_draw_end      draw_end;
81    void              *buffer;
82    int                width;
83    int                height;
84    int                stride;
85 };
86
87 void *
88 evas_software_wince_gapi_init(HWND window,
89                               int  width,
90                               int  height)
91 {
92    WCHAR                        oemstr[100];
93    _GAPI_Display_Properties     prop;
94    HMODULE                      gapi_lib;
95    Evas_Engine_WinCE_GAPI_Priv *priv;
96
97    gapi_display_open            display_open = NULL;
98    gapi_display_close           display_close = NULL;
99    gapi_display_properties_get  display_properties_get = NULL;
100    gapi_draw_begin              draw_begin = NULL;
101    gapi_draw_end                draw_end = NULL;
102
103    priv = (Evas_Engine_WinCE_GAPI_Priv *)malloc(sizeof(Evas_Engine_WinCE_GAPI_Priv));
104    if (!priv)
105      return NULL;
106
107    gapi_lib = LoadLibrary(L"\\Windows\\gx.dll");
108    if (!gapi_lib)
109      {
110         gapi_lib = LoadLibrary(L"gx.dll");
111         if (!gapi_lib)
112           {
113              fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] Can not load gx.dll\n");
114              goto free_priv;
115           }
116      }
117
118    LINK(display_open, display_open, L"?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
119    LINK(display_close, display_close, L"?GXCloseDisplay@@YAHXZ");
120    LINK(display_properties_get, display_properties_get, L"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
121    LINK(draw_begin, draw_begin, L"?GXBeginDraw@@YAPAXXZ");
122    LINK(draw_end, draw_end, L"?GXEndDraw@@YAHXZ");
123    LINK(suspend, suspend, L"?GXSuspend@@YAHXZ" );
124    LINK(resume, resume, L"?GXResume@@YAHXZ" );
125
126    if (!display_open ||
127        !display_close ||
128        !display_properties_get ||
129        !draw_begin ||
130        !draw_end ||
131        !suspend ||
132        !resume)
133      {
134         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] Can not find valid symbols\n");
135         goto free_lib;
136      }
137
138    if (!display_open(window, GX_FULLSCREEN))
139      {
140         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] Can not open display\n");
141         goto free_lib;
142      }
143
144    prop = display_properties_get();
145
146    // verify pixel format
147    if(!(prop.ffFormat & kfDirect565) || (prop.cBPP != 16))
148      {
149         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] display format mismatch\n");
150         goto close_display;
151      }
152
153    // verify we have a vga device
154    if ((GetSystemMetrics(SM_CXSCREEN) != (int)prop.cxWidth) ||
155        (GetSystemMetrics(SM_CYSCREEN) != (int)prop.cyHeight))
156      {
157         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] display size mismatch\n");
158         goto close_display;
159      }
160
161    priv->lib = gapi_lib;
162    priv->close_display = display_close;
163    priv->draw_begin = draw_begin;
164    priv->draw_end = draw_end;
165
166    /* GAPI on Ipaq H38** and H39** is completely buggy */
167    /* They are detected as portrait device (width = 240 and height = 320) */
168    /* but the framebuffer is managed like a landscape device : */
169    /*
170      240
171  +---------+
172  |         |
173  |         |
174  |         |
175  |         |
176  |         | 320
177  | ^^^     |
178  | |||     |
179  | |||     |
180  | |||     |
181  +---------+
182   ---->
183
184    */
185    /* So these devices are considered as landscape devices */
186    /* and width and height are switched. */
187    /* Other devices are managed normally : */
188    /*
189      240
190   +---------+
191 | |--->     |
192 | |--->     |
193 | |--->     |
194 v |         |
195   |         | 320
196   |         |
197   |         |
198   |         |
199   |         |
200   +---------+
201
202     */
203
204    SystemParametersInfo (SPI_GETOEMINFO, sizeof (oemstr), oemstr, 0);
205
206    if (((oemstr[12] == 'H') &&
207         (oemstr[13] == '3') &&
208         (oemstr[14] == '8')) ||
209        ((oemstr[12] == 'H') &&
210         (oemstr[13] == '3') &&
211         (oemstr[14] == '9')))
212      {
213         _GXDeviceInfo gxInfo = { 0 };
214         HDC           dc;
215         int           result;
216
217         priv->width = prop.cyHeight;
218         priv->height = prop.cxWidth;
219         priv->stride = prop.cbxPitch;
220
221         dc = GetDC (window);
222         if (!dc)
223           {
224              fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] Can not get device\n");
225              goto close_display;
226           }
227
228         gxInfo.Version = 100;
229         result = ExtEscape(dc, GETGXINFO, 0, NULL, sizeof(gxInfo),
230                            (char *) &gxInfo);
231         if (result <= 0)
232           {
233              fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] ExtEscape failed\n");
234              ReleaseDC(window, dc);
235              goto close_display;
236           }
237
238         priv->buffer = gxInfo.pvFrameBuffer;
239         ReleaseDC(window, dc);
240      }
241    else
242      {
243         priv->width = prop.cxWidth;
244         priv->height = prop.cyHeight;
245         priv->stride = prop.cbyPitch;
246         priv->buffer = NULL;
247      }
248
249    if ((priv->width != width) ||
250        (priv->height != height))
251      {
252         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] Size mismatch\n");
253         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] asked: %dx%d\n", width, height);
254         fprintf (stderr, "[Evas] [Engine] [WinCE GAPI] got  : %dx%d\n", priv->width, priv->height);
255         goto close_display;
256      }
257
258    return priv;
259
260  close_display:
261    display_close();
262  free_lib:
263    FreeLibrary(gapi_lib);
264  free_priv:
265    free(priv);
266    return NULL;
267 }
268
269 void
270 evas_software_wince_gapi_shutdown(void *priv)
271 {
272    Evas_Engine_WinCE_GAPI_Priv *p;
273
274    p = (Evas_Engine_WinCE_GAPI_Priv *)priv;
275    p->close_display();
276    suspend = NULL;
277    resume = NULL;
278    FreeLibrary(p->lib);
279    free(p);
280 }
281
282
283 FB_Output_Buffer *
284 evas_software_wince_gapi_output_buffer_new(void *priv,
285                                            int   width,
286                                            int   height)
287 {
288    FB_Output_Buffer *fbob;
289    void             *buffer;
290
291    fbob = calloc(1, sizeof(FB_Output_Buffer));
292    if (!fbob) return NULL;
293
294    buffer = malloc (width * height * 2); /* we are sure to have 16bpp */
295    if (!buffer)
296      {
297         free(fbob);
298         return NULL;
299      }
300
301    fbob->priv = priv;
302
303    fbob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *)buffer, 0, EVAS_COLORSPACE_RGB565_A5P);
304    if (fbob->im)
305      fbob->im->stride = ((Evas_Engine_WinCE_GAPI_Priv *)priv)->stride >> 1;
306
307    return fbob;
308 }
309
310 void
311 evas_software_wince_gapi_output_buffer_free(FB_Output_Buffer *fbob)
312 {
313    free(fbob->im->pixels);
314    free(fbob);
315 }
316
317 void
318 evas_software_wince_gapi_output_buffer_paste(FB_Output_Buffer *fbob)
319 {
320    Evas_Engine_WinCE_GAPI_Priv *priv;
321    void                        *buffer;
322
323    priv = (Evas_Engine_WinCE_GAPI_Priv *)fbob->priv;
324
325    buffer = priv->draw_begin();
326    if (!buffer)
327      return;
328
329    if (priv->buffer) buffer = priv->buffer;
330
331    if ((fbob->im->cache_entry.w == priv->width) &&
332        (fbob->im->cache_entry.h == priv->height))
333      memcpy(buffer, fbob->im->pixels,
334             priv->width * priv->height * 2);
335
336    priv->draw_end();
337 }
338
339 void
340 evas_software_wince_gapi_surface_resize(FB_Output_Buffer *fbob)
341 {
342 }