PageRenderTime 27ms CodeModel.GetById 2ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/src/backend/wince/ftk_display_wince_gles.c

http://ftk.googlecode.com/
C | 569 lines | 482 code | 77 blank | 10 comment | 61 complexity | 85c9adc289f6fe72bb58eb016618a96b MD5 | raw file
  1
  2#include "ftk_typedef.h"
  3#include "ftk.h"
  4#include "ftk_log.h"
  5#include "ftk_event.h"
  6#include "ftk_globals.h"
  7#include "ftk_display_wince.h"
  8#include "ftk_input_method_manager.h"
  9#include "ftk_input_method_wince.h"
 10#include "GLES/egl.h"
 11#include "GLES/gl.h"
 12#include <aygshell.h>
 13
 14#define FTK_EGL_FUNC(ret, func, params) ret (WINAPI *func) params;
 15#define FTK_GLES_FUNC(ret, func, params) ret (WINAPI *func) params;
 16#include "ftk_gles_funcs.h"
 17#undef FTK_EGL_FUNC
 18#undef FTK_GLES_FUNC
 19
 20typedef struct _PrivInfo
 21{
 22	HWND wnd;
 23	HDC dc;
 24	HANDLE egl_dll;
 25	HANDLE gles_dll;
 26	EGLDisplay display;
 27	EGLContext context;
 28	EGLSurface surface;
 29	EGLConfig config;
 30	int width;
 31	int height;
 32	int screen_width;
 33	int screen_height;
 34	void* bits;
 35	FtkEvent event;
 36}PrivInfo;
 37
 38static int s_key_map[0xff] = {0};
 39static wchar_t szClassName[] = L"FtkEmulator";
 40
 41static Ret ftk_display_wince_gles_get_funcs(PrivInfo* priv)
 42{
 43#define FTK_EGL_FUNC(ret, func, params) \
 44	func = (ret (WINAPI *) params)GetProcAddress(priv->egl_dll, L#func); \
 45	if(func == NULL) \
 46	{ \
 47		ftk_loge("GetProcAddress(\"%s\") failed\n", #func); \
 48		return RET_FAIL; \
 49	}
 50#define FTK_GLES_FUNC(ret, func, params) \
 51	func = (ret (WINAPI *) params)GetProcAddress(priv->gles_dll, L#func); \
 52	if(func == NULL) \
 53	{ \
 54		ftk_loge("GetProcAddress(\"%s\") failed\n", #func); \
 55		return RET_FAIL; \
 56	}
 57#include "ftk_gles_funcs.h"
 58#undef FTK_EGL_FUNC
 59#undef FTK_GLES_FUNC
 60	return RET_OK;
 61}
 62
 63static void ftk_display_wince_gles_set_fullscreen(PrivInfo* priv)
 64{
 65	SHFullScreen(priv->wnd, SHFS_HIDESIPBUTTON|SHFS_HIDETASKBAR|SHFS_HIDESTARTICON);
 66	SetWindowPos(priv->wnd, HWND_TOPMOST, 0, 0, priv->screen_width, priv->screen_height, SWP_NOOWNERZORDER|SWP_SHOWWINDOW);
 67}
 68
 69static void ftk_display_wince_gles_keymap_init(void)
 70{
 71	s_key_map[0xBD] = FTK_KEY_MINUS;
 72	s_key_map[0x20] = FTK_KEY_SPACE;
 73	s_key_map[0xBB] = FTK_KEY_EQUAL;
 74	s_key_map[0x08] = FTK_KEY_BACKSPACE;
 75	s_key_map[0x09] = FTK_KEY_TAB;
 76	s_key_map[0xC0] = FTK_KEY_QUOTELEFT;
 77	s_key_map[0xDE] = FTK_KEY_QUOTERIGHT;
 78	s_key_map[0xDB] = FTK_KEY_BRACKETLEFT;
 79	s_key_map[0xDD] = FTK_KEY_BRACKETRIGHT;
 80	s_key_map[0x0d] = FTK_KEY_ENTER;
 81	s_key_map[0xBA] = FTK_KEY_SEMICOLON;
 82	s_key_map[0x30] = FTK_KEY_0;
 83	s_key_map[0x31] = FTK_KEY_1; 
 84	s_key_map[0x32] = FTK_KEY_2;
 85	s_key_map[0x33] = FTK_KEY_3;
 86	s_key_map[0x34] = FTK_KEY_4;
 87	s_key_map[0x35] = FTK_KEY_5;
 88	s_key_map[0x36] = FTK_KEY_6;
 89	s_key_map[0x37] = FTK_KEY_7;
 90	s_key_map[0x38] = FTK_KEY_8;
 91	s_key_map[0x39] = FTK_KEY_9;
 92	s_key_map[0x70] = FTK_KEY_F1; 
 93	s_key_map[0x71] = FTK_KEY_F2;
 94	s_key_map[0x72] = FTK_KEY_F3;
 95	s_key_map[0x73] = FTK_KEY_F4;
 96	s_key_map[0x74] = FTK_KEY_F5;
 97	s_key_map[0x75] = FTK_KEY_F6;
 98	s_key_map[0x76] = FTK_KEY_F7;
 99	s_key_map[0x77] = FTK_KEY_F8;
100	s_key_map[0x78] = FTK_KEY_F9;
101	s_key_map[0xBC] = FTK_KEY_COMMA;
102	s_key_map[0xBE] = FTK_KEY_DOT;
103	s_key_map[0xBF] = FTK_KEY_SLASH;
104	s_key_map[0x10] = FTK_KEY_RIGHTSHIFT;
105	s_key_map[0x11] = FTK_KEY_LEFTCTRL;
106	s_key_map[0x14] = FTK_KEY_CAPSLOCK;
107	s_key_map[0x40] = FTK_KEY_LEFTALT;
108	s_key_map[0x41] = FTK_KEY_a;
109	s_key_map[0x42] = FTK_KEY_b;
110	s_key_map[0x43] = FTK_KEY_c;
111	s_key_map[0x44] = FTK_KEY_d;
112	s_key_map[0x45] = FTK_KEY_e;
113	s_key_map[0x46] = FTK_KEY_f;
114	s_key_map[0x47] = FTK_KEY_g;
115	s_key_map[0x48] = FTK_KEY_h;
116	s_key_map[0x49] = FTK_KEY_i;
117	s_key_map[0x4a] = FTK_KEY_j;
118	s_key_map[0x4b] = FTK_KEY_k;
119	s_key_map[0x4c] = FTK_KEY_l;
120	s_key_map[0x4d] = FTK_KEY_m;
121	s_key_map[0x4e] = FTK_KEY_n;
122	s_key_map[0x4f] = FTK_KEY_o;
123	s_key_map[0x50] = FTK_KEY_p;
124	s_key_map[0x51] = FTK_KEY_q;
125	s_key_map[0x52] = FTK_KEY_r;
126	s_key_map[0x53] = FTK_KEY_s;
127	s_key_map[0x54] = FTK_KEY_t;
128	s_key_map[0x55] = FTK_KEY_u;
129	s_key_map[0x56] = FTK_KEY_v;
130	s_key_map[0x57] = FTK_KEY_w;
131	s_key_map[0x58] = FTK_KEY_x;
132	s_key_map[0x59] = FTK_KEY_y;
133	s_key_map[0x5a] = FTK_KEY_z;
134	s_key_map[0x21] = FTK_KEY_PAGEUP;
135	s_key_map[0x25] = FTK_KEY_LEFT;
136	s_key_map[0x27] = FTK_KEY_RIGHT;
137	s_key_map[0x24] = FTK_KEY_HOME;
138	s_key_map[0x23] = FTK_KEY_END;
139	s_key_map[0x28] = FTK_KEY_DOWN;
140	s_key_map[0x22] = FTK_KEY_PAGEDOWN;
141	s_key_map[0x2d] = FTK_KEY_INSERT;
142	s_key_map[0x2e] = FTK_KEY_DELETE;
143	s_key_map[0x26] = FTK_KEY_UP;
144}
145
146static char* ftk_display_wince_gles_on_ime(HWND hwnd, LPARAM lParam)
147{
148	LONG n;
149	wchar_t* unicode;
150	char* utf8;
151	HIMC himc;
152	FtkInputMethod* im = NULL;
153
154	if(!(lParam & GCS_RESULTSTR))
155	{
156		return NULL;
157	}
158	if(ftk_input_method_manager_get_current(ftk_default_input_method_manager(), &im) == RET_FAIL || im == NULL)
159	{
160		return NULL;
161	}
162	if(ftk_input_method_wince_get_editor(im) == NULL)
163	{
164		return NULL;
165	}
166
167	himc = ImmGetContext(hwnd);
168	if((void*)himc == NULL)
169	{
170		return NULL;
171	}
172	n = ImmGetCompositionStringW(himc, GCS_RESULTSTR, NULL, 0);
173	if(n <= 0)
174	{
175		ImmReleaseContext(hwnd, himc);
176		return NULL;
177	}
178	unicode = (wchar_t*)FTK_ALLOC(n + 2);
179	if(unicode == NULL)
180	{
181		ImmReleaseContext(hwnd, himc);
182		return NULL;
183	}
184	if(ImmGetCompositionStringW(himc, GCS_RESULTSTR, unicode, n) != n)
185	{
186		FTK_FREE(unicode);
187		ImmReleaseContext(hwnd, himc);
188		return NULL;
189	}
190	ImmReleaseContext(hwnd, himc);
191
192	ftk_logd("%s:%d WM_IME_COMPOSITION:%s\n", __FILE__, __LINE__, unicode);
193	unicode[n / 2] = L'\0';
194	ftk_logd("%s:%d WM_IME_COMPOSITION:%s\n", __FILE__, __LINE__, unicode);
195	n = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
196	if(n < 1)
197	{
198		FTK_FREE(unicode);
199		return NULL;
200	}
201	utf8 = (char*) FTK_ALLOC(n);
202	if(utf8 == NULL)
203	{
204		FTK_FREE(unicode);
205		return NULL;
206	}
207	n = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, n, NULL, NULL);
208	if(n < 1)
209	{
210		FTK_FREE(unicode);
211		FTK_FREE(utf8);
212		return NULL;
213	}
214
215	FTK_FREE(unicode);
216
217	ftk_logd("%s:%d WM_IME_COMPOSITION:%s\n", __FILE__, __LINE__, utf8);
218
219	return utf8;
220}
221
222static void ftk_display_wince_gles_on_paint(PrivInfo* priv)
223{
224	GLfloat	coordinates[] = { 0, priv->screen_height / (float)priv->height,
225				  priv->screen_width / (float)priv->width, priv->screen_height / (float)priv->height,
226				  0, 0,
227				  priv->screen_width / (float)priv->width, 0 };
228	GLfloat	vertices[] = {
229		0.0f,				0.0f,	0.0,
230		0.0f + priv->screen_width,	0.0f,	0.0,
231		0.0f,				0.0f + priv->screen_height, 0.0,
232		0.0f + priv->screen_width,	0.0f + priv->screen_height, 0.0 };
233
234	glClear(GL_COLOR_BUFFER_BIT);
235	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
236	glBindTexture(GL_TEXTURE_2D, 0);
237	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
238	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, priv->width, priv->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, priv->bits);
239	glVertexPointer(3, GL_FLOAT, 0, vertices);
240	glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
241	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
242
243	//eglWaitNative(EGL_NATIVE_RENDERABLE);
244	//eglWaitGL();
245	eglSwapBuffers(priv->display, priv->surface);
246}
247
248static LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
249{
250	char* buf = NULL;
251	HDC dc;
252	PAINTSTRUCT ps;
253	PrivInfo* priv = (PrivInfo*)GetWindowLongW(hwnd, GWL_USERDATA);
254
255	switch(message)
256	{
257		case WM_DESTROY:
258			PostQuitMessage(0);
259			FTK_QUIT();
260			break;
261		//case WM_ACTIVATE:
262		//	set_fullscreen(priv);
263		//	break;
264		case WM_PAINT:
265			dc = BeginPaint(hwnd, &ps);
266			EndPaint(hwnd, &ps);
267			if(priv != NULL)
268			{
269				ftk_display_wince_gles_on_paint(priv);
270			}
271			break;
272		case WM_KEYDOWN:
273		case WM_KEYUP:
274			priv->event.type = message == WM_KEYDOWN ? FTK_EVT_KEY_DOWN : FTK_EVT_KEY_UP;
275			priv->event.u.key.code = s_key_map[0xFF & wParam];
276			break;
277		case WM_LBUTTONUP:
278		case WM_LBUTTONDOWN:
279			priv->event.u.mouse.x = LOWORD(lParam);
280			priv->event.u.mouse.y = HIWORD(lParam);
281			priv->event.type = message == WM_LBUTTONUP? FTK_EVT_MOUSE_UP : FTK_EVT_MOUSE_DOWN;
282			break;
283		case WM_MOUSEMOVE:
284			priv->event.u.mouse.x = LOWORD(lParam);
285			priv->event.u.mouse.y = HIWORD(lParam);
286			priv->event.type = FTK_EVT_MOUSE_MOVE;
287			break;
288		case WM_IME_COMPOSITION:
289			buf = ftk_display_wince_gles_on_ime(hwnd, lParam);
290			if(buf == NULL)
291			{
292				return DefWindowProcW(hwnd, message, wParam, lParam);
293			}
294			priv->event.u.extra = buf;
295			priv->event.type = FTK_EVT_OS_IM_COMMIT;
296			break;
297		default:
298			return DefWindowProcW(hwnd, message, wParam, lParam);
299	}
300
301	if(priv->event.type != FTK_EVT_NOP)
302	{
303		ftk_wnd_manager_queue_event_auto_rotate(ftk_default_wnd_manager(), &priv->event);
304		priv->event.type = FTK_EVT_NOP;
305	}
306
307	return 0;
308}
309
310static HWND ftk_display_wince_gles_create_win(PrivInfo* priv)
311{
312	HWND hwnd;
313	WNDCLASSW wincl;
314
315	wincl.hInstance = NULL;
316	wincl.lpszClassName = szClassName;
317	wincl.lpfnWndProc = WinProc;
318	wincl.style = CS_DBLCLKS;
319	wincl.hIcon = NULL;
320	wincl.hCursor = LoadCursorW(NULL, IDC_ARROW);
321	wincl.lpszMenuName = NULL;
322	wincl.cbClsExtra = 0;
323	wincl.cbWndExtra = 64;
324	wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
325
326	if (!RegisterClassW(&wincl))
327	{
328		return NULL;
329	}
330
331	hwnd = CreateWindowExW(0, szClassName, L"FtkEmulator", WS_DLGFRAME,
332		CW_USEDEFAULT, CW_USEDEFAULT, priv->width, priv->height,
333		HWND_DESKTOP, NULL, NULL, NULL);
334
335	return hwnd;
336}
337
338static Ret ftk_display_wince_gles_update(FtkDisplay* thiz, FtkBitmap* bitmap, FtkRect* rect, int xoffset, int yoffset)
339{
340	Ret ret = RET_OK;
341	DECL_PRIV(thiz, priv);
342
343	ret = ftk_bitmap_copy_to_data_rgba32(bitmap, rect, priv->bits, xoffset, yoffset, priv->width, priv->height);
344
345	ftk_display_wince_gles_on_paint(priv);
346
347	return ret;
348}
349
350static int ftk_display_wince_gles_width(FtkDisplay* thiz)
351{
352	DECL_PRIV(thiz, priv);
353	return_val_if_fail(priv != NULL, 0);
354	return priv->screen_width;
355}
356
357static int ftk_display_wince_gles_height(FtkDisplay* thiz)
358{
359	DECL_PRIV(thiz, priv);
360	return_val_if_fail(priv != NULL, 0);
361	return priv->screen_height;
362}
363
364static Ret ftk_display_wince_gles_snap(FtkDisplay* thiz, FtkRect* r, FtkBitmap* bitmap)
365{
366#if 0
367	FtkRect rect = {0};
368	DECL_PRIV(thiz, priv);
369	int w = ftk_display_width(thiz);
370	int h = ftk_display_height(thiz);
371	int bw = ftk_bitmap_width(bitmap);
372	int bh = ftk_bitmap_height(bitmap);
373
374	rect.x = r->x;
375	rect.y = r->y;
376	rect.width = FTK_MIN(bw, r->width);
377	rect.height = FTK_MIN(bh, r->height);
378
379	return ftk_bitmap_copy_from_data_bgra32(bitmap, priv->bits, w, h, &rect);
380#else
381	//DECL_PRIV(thiz, priv);
382
383	/*TODO*/
384	/*snap_bitmap(priv, bitmap, r->x, r->y, r->width, r->height);*/
385
386	return RET_OK;
387#endif
388}
389
390static void ftk_display_wince_gles_destroy(FtkDisplay* thiz)
391{
392	if(thiz != NULL)
393	{
394		DECL_PRIV(thiz, priv);
395
396		eglMakeCurrent(priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
397		eglDestroySurface(priv->display, priv->surface);
398		eglDestroyContext(priv->display, priv->context);
399		eglTerminate(priv->display);
400
401		FreeLibrary(priv->egl_dll);
402		FreeLibrary(priv->gles_dll);
403
404		ReleaseDC(priv->wnd, priv->dc);
405
406		FTK_FREE(priv->bits);
407		FTK_ZFREE(thiz, sizeof(FtkDisplay) + sizeof(PrivInfo));
408	}
409}
410
411FtkDisplay* ftk_display_wince_create(void)
412{
413	EGLint i, n, attrs[64];
414	EGLint major = 0;
415	EGLint minor = 0;
416	FtkDisplay* thiz;
417
418	thiz = (FtkDisplay*)FTK_ZALLOC(sizeof(FtkDisplay) + sizeof(PrivInfo));
419	if(thiz != NULL)
420	{
421		DECL_PRIV(thiz, priv);
422		thiz->update = ftk_display_wince_gles_update;
423		thiz->snap = ftk_display_wince_gles_snap;
424		thiz->width = ftk_display_wince_gles_width;
425		thiz->height = ftk_display_wince_gles_height;
426		thiz->destroy = ftk_display_wince_gles_destroy;
427
428#if 0
429		priv->egl_dll = LoadLibraryW(L"/Windows/libEGL.dll");
430		if(priv->egl_dll == NULL)
431		{
432			ftk_loge("%s: LoadLibrary(\"libEGL.dll\") failed (%d)\n", __func__, GetLastError());
433			return NULL;
434		}
435#endif
436
437		priv->gles_dll = LoadLibraryW(L"/Windows/libGLESv1_CM.dll");
438		if(priv->gles_dll == NULL)
439		{
440			ftk_loge("%s: LoadLibrary(\"libGLESv1_CM.dll\") failed (%d)\n", __func__, GetLastError());
441			return NULL;
442		}
443
444#if 1
445		priv->egl_dll = priv->gles_dll;
446#endif
447
448		if(ftk_display_wince_gles_get_funcs(priv) != RET_OK)
449		{
450			return NULL;
451		}
452
453		priv->screen_width = GetSystemMetrics(SM_CXSCREEN);
454		priv->screen_height = GetSystemMetrics(SM_CYSCREEN);
455		priv->width = 512;
456		priv->height = 512;
457
458		priv->bits = FTK_ZALLOC(priv->width * priv->height * 4);
459		if(priv->bits == NULL)
460		{
461			ftk_loge("%s: FTK_ZALLOC() failed\n", __func__);
462			return NULL;
463		}
464
465		priv->wnd = ftk_display_wince_gles_create_win(priv);
466		if(priv->wnd == NULL)
467		{
468			ftk_loge("%s: ftk_display_wince_gles_create_win() failed\n", __func__);
469			FTK_FREE(priv->bits);
470			return NULL;
471		}
472
473		priv->dc = GetDC(priv->wnd);
474
475		priv->display = eglGetDisplay((NativeDisplayType)priv->dc);
476		if(priv->display == EGL_NO_DISPLAY)
477		{
478			ftk_loge("%s:%d eglGetDisplay() failed\n", __FILE__, __LINE__);
479			return NULL;
480		}
481
482		if(eglInitialize(priv->display, &major, &minor) != EGL_TRUE)
483		{
484			ftk_loge("%s:%d eglInitialize() failed\n", __FILE__, __LINE__);
485			return NULL;
486		}
487
488		i = 0;
489
490		attrs[i++] = EGL_RED_SIZE;
491		attrs[i++] = 8;
492		attrs[i++] = EGL_GREEN_SIZE;
493		attrs[i++] = 8;
494		attrs[i++] = EGL_BLUE_SIZE;
495		attrs[i++] = 8;
496		attrs[i++] = EGL_ALPHA_SIZE;
497		attrs[i++] = EGL_DONT_CARE;
498
499		attrs[i++] = EGL_SURFACE_TYPE;
500		attrs[i++] = EGL_WINDOW_BIT;
501
502		attrs[i++] = EGL_DEPTH_SIZE;
503		attrs[i++] = 16;
504
505		attrs[i++] = EGL_STENCIL_SIZE;
506		attrs[i++] = EGL_DONT_CARE;
507
508		attrs[i] = EGL_NONE;
509
510		n = 0;
511
512		if(eglChooseConfig(priv->display, attrs, &priv->config, 1, &n) != EGL_TRUE || n == 0)
513		{
514			ftk_loge("%s:%d eglChooseConfig() failed\n", __FILE__, __LINE__);
515			return NULL;
516		}
517
518		priv->surface = eglCreateWindowSurface(priv->display, priv->config, priv->wnd, NULL);
519		if(priv->surface == EGL_NO_SURFACE)
520		{
521			ftk_loge("%s:%d eglCreateWindowSurface() failed\n", __FILE__, __LINE__);
522			return NULL;
523		}
524
525		priv->context = eglCreateContext(priv->display, priv->config, EGL_NO_CONTEXT, NULL);
526		if(priv->context == EGL_NO_CONTEXT)
527		{
528			ftk_loge("%s:%d eglCreateContext() failed\n", __FILE__, __LINE__);
529			return NULL;
530		}
531
532		if(eglMakeCurrent(priv->display, priv->surface, priv->surface, priv->context) != EGL_TRUE)
533		{
534			ftk_loge("%s:%d eglMakeCurrent() failed\n", __FILE__, __LINE__);
535			return NULL;
536		}
537
538
539		glViewport(0, 0, priv->screen_width, priv->screen_height);
540
541		glMatrixMode(GL_PROJECTION);
542		glLoadIdentity();
543		glOrthof(0, (float)priv->screen_width, 0, (float)priv->screen_height, 0, 100);
544
545		glMatrixMode(GL_MODELVIEW);
546		glLoadIdentity();
547
548		glEnable(GL_TEXTURE_2D);
549		glEnable(GL_BLEND);
550		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
551
552		glEnableClientState (GL_VERTEX_ARRAY);
553		glEnableClientState (GL_TEXTURE_COORD_ARRAY);
554
555		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
556
557		//ftk_logd("%s:%d %s\n", __FILE__, __LINE__, glGetString(GL_EXTENSIONS));
558
559		ftk_display_wince_gles_keymap_init();
560
561		SetWindowLongW(priv->wnd, GWL_USERDATA, (LONG)priv);
562		ShowWindow(priv->wnd, SW_SHOW);
563		//UpdateWindow(priv->wnd);
564
565		ftk_display_wince_gles_set_fullscreen(priv);
566	}
567
568	return thiz;
569}