📄 gapi.cpp
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / GAPI WinCE-iPaq video render module * * GPAC 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, or (at your option) * any later version. * * GPAC 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <windows.h>#include <aygshell.h>#include <wingdi.h>#include <gx.h>#include "gapi.h"#ifdef GPAC_USE_OGL_ES#pragma message("Compiling GAPI with OpenGL-ES support")#endifstatic Bool is_landscape = 0;#define PRINT(__str) OutputDebugString(_T(__str))#define GAPICTX(dr) GAPIPriv *gctx = (GAPIPriv *) dr->opaque;static GF_Err GAPI_InitBackBuffer(GF_VideoOutput *dr, u32 VideoWidth, u32 VideoHeight);static GF_VideoOutput *the_video_driver = NULL;static void GAPI_GetCoordinates(DWORD lParam, GF_Event *evt){ GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; evt->mouse.x = LOWORD(lParam); evt->mouse.y = HIWORD(lParam); if (ctx->fullscreen) { POINT pt; pt.x = evt->mouse.x; pt.y = evt->mouse.y; ClientToScreen(ctx->hWnd, &pt); if (is_landscape) { evt->mouse.x = ctx->fs_w - pt.y; evt->mouse.y = pt.x; } else { evt->mouse.x = pt.x; evt->mouse.y = pt.y; } }}static void w32_translate_key(u32 wParam, u32 lParam, GF_EventKey *evt){ evt->flags = 0; evt->hw_code = wParam; switch (wParam) { case VK_BACK: evt->key_code = GF_KEY_BACKSPACE; break; case VK_TAB: evt->key_code = GF_KEY_TAB; break; case VK_CLEAR: evt->key_code = GF_KEY_CLEAR; break; case VK_RETURN: evt->key_code = GF_KEY_ENTER; break; case VK_SHIFT: evt->key_code = GF_KEY_SHIFT; break; case VK_CONTROL: evt->key_code = GF_KEY_CONTROL; break; case VK_MENU: evt->key_code = GF_KEY_ALT; break; case VK_PAUSE: evt->key_code = GF_KEY_PAUSE; break; case VK_CAPITAL: evt->key_code = GF_KEY_CAPSLOCK; break; case VK_KANA: evt->key_code = GF_KEY_KANAMODE; break; case VK_JUNJA: evt->key_code = GF_KEY_JUNJAMODE; break; case VK_FINAL: evt->key_code = GF_KEY_FINALMODE; break; case VK_KANJI: evt->key_code = GF_KEY_KANJIMODE; break; case VK_ESCAPE: evt->key_code = GF_KEY_ESCAPE; break; case VK_CONVERT: evt->key_code = GF_KEY_CONVERT; break; case VK_SPACE: evt->key_code = GF_KEY_SPACE; break; case VK_PRIOR: evt->key_code = GF_KEY_PAGEUP; break; case VK_NEXT: evt->key_code = GF_KEY_PAGEDOWN; break; case VK_END: evt->key_code = GF_KEY_END; break; case VK_HOME: evt->key_code = GF_KEY_HOME; break; case VK_LEFT: evt->key_code = GF_KEY_LEFT; break; case VK_UP: evt->key_code = GF_KEY_UP; break; case VK_RIGHT: evt->key_code = GF_KEY_RIGHT; break; case VK_DOWN: evt->key_code = GF_KEY_DOWN; break; case VK_SELECT: evt->key_code = GF_KEY_SELECT; break; case VK_PRINT: case VK_SNAPSHOT: evt->key_code = GF_KEY_PRINTSCREEN; break; case VK_EXECUTE: evt->key_code = GF_KEY_EXECUTE; break; case VK_INSERT: evt->key_code = GF_KEY_INSERT; break; case VK_DELETE: evt->key_code = GF_KEY_DEL; break; case VK_HELP: evt->key_code = GF_KEY_HELP; break;/* case VK_LWIN: return ; case VK_RWIN: return ; case VK_APPS: return ;*/ case VK_NUMPAD0: evt->key_code = GF_KEY_0; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD1: evt->key_code = GF_KEY_1; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD2: evt->key_code = GF_KEY_2; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD3: evt->key_code = GF_KEY_3; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD4: evt->key_code = GF_KEY_4; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD5: evt->key_code = GF_KEY_5; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD6: evt->key_code = GF_KEY_6; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD7: evt->key_code = GF_KEY_7; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD8: evt->key_code = GF_KEY_8; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_NUMPAD9: evt->key_code = GF_KEY_9; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_MULTIPLY: evt->key_code = GF_KEY_STAR; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_ADD: evt->key_code = GF_KEY_PLUS; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_SEPARATOR: evt->key_code = GF_KEY_FULLSTOP; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_SUBTRACT: evt->key_code = GF_KEY_HYPHEN; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_DECIMAL: evt->key_code = GF_KEY_COMMA; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_DIVIDE: evt->key_code = GF_KEY_SLASH; evt->flags = GF_KEY_EXT_NUMPAD; break; case VK_F1: evt->key_code = GF_KEY_F1; break; case VK_F2: evt->key_code = GF_KEY_F2; break; case VK_F3: evt->key_code = GF_KEY_F3; break; case VK_F4: evt->key_code = GF_KEY_F4; break; case VK_F5: evt->key_code = GF_KEY_F5; break; case VK_F6: evt->key_code = GF_KEY_F6; break; case VK_F7: evt->key_code = GF_KEY_F7; break; case VK_F8: evt->key_code = GF_KEY_F8; break; case VK_F9: evt->key_code = GF_KEY_F9; break; case VK_F10: evt->key_code = GF_KEY_F10; break; case VK_F11: evt->key_code = GF_KEY_F11; break; case VK_F12: evt->key_code = GF_KEY_F12; break; case VK_F13: evt->key_code = GF_KEY_F13; break; case VK_F14: evt->key_code = GF_KEY_F14; break; case VK_F15: evt->key_code = GF_KEY_F15; break; case VK_F16: evt->key_code = GF_KEY_F16; break; case VK_F17: evt->key_code = GF_KEY_F17; break; case VK_F18: evt->key_code = GF_KEY_F18; break; case VK_F19: evt->key_code = GF_KEY_F19; break; case VK_F20: evt->key_code = GF_KEY_F20; break; case VK_F21: evt->key_code = GF_KEY_F21; break; case VK_F22: evt->key_code = GF_KEY_F22; break; case VK_F23: evt->key_code = GF_KEY_F23; break; case VK_F24: evt->key_code = GF_KEY_F24; break; case VK_NUMLOCK: evt->key_code = GF_KEY_NUMLOCK; break; case VK_SCROLL: evt->key_code = GF_KEY_SCROLL; break;/* * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. * Used only as parameters to GetAsyncKeyState() and GetKeyState(). * No other API or message will distinguish left and right keys in this way. */ case VK_LSHIFT: evt->key_code = GF_KEY_SHIFT; evt->flags = GF_KEY_EXT_LEFT; break; case VK_RSHIFT: evt->key_code = GF_KEY_SHIFT; evt->flags = GF_KEY_EXT_RIGHT; break; case VK_LCONTROL: evt->key_code = GF_KEY_CONTROL; evt->flags = GF_KEY_EXT_LEFT; break; case VK_RCONTROL: evt->key_code = GF_KEY_CONTROL; evt->flags = GF_KEY_EXT_RIGHT; break; case VK_LMENU: evt->key_code = GF_KEY_ALT; evt->flags = GF_KEY_EXT_LEFT; break; case VK_RMENU: evt->key_code = GF_KEY_ALT; evt->flags = GF_KEY_EXT_RIGHT; break;#if(WINVER >= 0x0400) case VK_PROCESSKEY: evt->key_code = GF_KEY_PROCESS; break;#endif /* WINVER >= 0x0400 */ case VK_ATTN: evt->key_code = GF_KEY_ATTN; break; case VK_CRSEL: evt->key_code = GF_KEY_CRSEL; break; case VK_EXSEL: evt->key_code = GF_KEY_EXSEL; break; case VK_EREOF: evt->key_code = GF_KEY_ERASEEOF; break; case VK_PLAY: evt->key_code = GF_KEY_PLAY; break; case VK_ZOOM: evt->key_code = GF_KEY_ZOOM; break; //case VK_NONAME: evt->key_code = GF_KEY_NONAME; break; //case VK_PA1: evt->key_code = GF_KEY_PA1; break; case VK_OEM_CLEAR: evt->key_code = GF_KEY_CLEAR; break; /*thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ default: if ((wParam>=0x30) && (wParam<=0x39)) evt->key_code = GF_KEY_0 + wParam-0x30; else if ((wParam>=0x41) && (wParam<=0x5A)) evt->key_code = GF_KEY_A + wParam-0x51; else { GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; short res = (LOWORD(wParam) != 0x5b) ? LOWORD(wParam) : wParam; if (res==ctx->keys.vkLeft) evt->key_code = is_landscape ? GF_KEY_UP : GF_KEY_LEFT; else if (res==ctx->keys.vkRight) evt->key_code = is_landscape ? GF_KEY_DOWN : GF_KEY_RIGHT; else if (res==ctx->keys.vkDown) evt->key_code = is_landscape ? GF_KEY_LEFT : GF_KEY_DOWN; else if (res==ctx->keys.vkUp) evt->key_code = is_landscape ? GF_KEY_RIGHT : GF_KEY_UP; else if (res==ctx->keys.vkStart) evt->key_code = GF_KEY_ENTER; else if (res==ctx->keys.vkA) evt->key_code = GF_KEY_CONTROL; else if (res==ctx->keys.vkB) evt->key_code = GF_KEY_SHIFT; else if (res==ctx->keys.vkC) evt->key_code = GF_KEY_ALT; else evt->key_code = GF_KEY_UNIDENTIFIED; } break; }}LRESULT APIENTRY GAPI_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam){ GF_Event evt; switch (msg) { case WM_SIZE: { GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; evt.type = GF_EVENT_SIZE; evt.size.width = LOWORD(lParam); evt.size.height = HIWORD(lParam); the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); } break; case WM_CLOSE: evt.type = GF_EVENT_QUIT; the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); return 1; case WM_DESTROY: { GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; if (ctx->owns_hwnd ) { PostQuitMessage (0); } else if (ctx->orig_wnd_proc) { /*restore window proc*/ SetWindowLong(ctx->hWnd, GWL_WNDPROC, ctx->orig_wnd_proc); ctx->orig_wnd_proc = 0L; } } break; case WM_ERASEBKGND:// evt.type = GF_EVENT_REFRESH;// the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; case WM_PAINT: { PAINTSTRUCT ps; HDC dc, hdcBitmap, old; GAPIPriv *gctx = (GAPIPriv *)the_video_driver->opaque; if (gctx->gx_mode) break; dc = BeginPaint(gctx->hWnd, &ps); hdcBitmap = CreateCompatibleDC((HDC)dc); old = (HDC) SelectObject(hdcBitmap, gctx->bitmap); BitBlt((HDC)dc, gctx->dst_blt.x, gctx->dst_blt.y, gctx->bb_width, gctx->bb_height, hdcBitmap, 0, 0, SRCCOPY); SelectObject(hdcBitmap, old); EndPaint(gctx->hWnd, &ps); } break; case WM_MOUSEMOVE: GAPI_GetCoordinates(lParam, &evt); evt.type = GF_EVENT_MOUSEMOVE; the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: GAPI_GetCoordinates(lParam, &evt); evt.type = GF_EVENT_MOUSEDOWN; evt.mouse.button = GF_MOUSE_LEFT; the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; case WM_LBUTTONUP: GAPI_GetCoordinates(lParam, &evt); evt.type = GF_EVENT_MOUSEUP; evt.mouse.button = GF_MOUSE_LEFT; the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; /*FIXME - there's a bug on alt state (we miss one event)*/ case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: w32_translate_key(wParam, lParam, &evt.key); evt.type = ((msg==WM_SYSKEYDOWN) || (msg==WM_KEYDOWN)) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; case WM_CHAR: evt.type = GF_EVENT_TEXTINPUT; evt.character.unicode_char = wParam; break; } return DefWindowProc (hWnd, msg, wParam, lParam);}void GAPI_WindowThread(void *par){ MSG msg; WNDCLASS wc; GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; memset(&wc, 0, sizeof(WNDCLASS)); wc.hInstance = GetModuleHandle(_T("gapi.dll")); wc.lpfnWndProc = GAPI_WindowProc; wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH); wc.lpszClassName = _T("GPAC GAPI Output"); RegisterClass (&wc); ctx->hWnd = CreateWindow(_T("GPAC GAPI Output"), NULL, WS_POPUP, 0, 0, 120, 100, NULL, NULL, wc.hInstance, NULL); if (ctx->hWnd == NULL) { ctx->ThreadID = 0; ExitThread(1); } ShowWindow(ctx->hWnd, SW_SHOWNORMAL); while (GetMessage (&(msg), NULL, 0, 0)) { TranslateMessage (&(msg)); DispatchMessage (&(msg)); } ctx->ThreadID = 0; ExitThread (0);}void GAPI_SetupWindow(GF_VideoOutput *dr){ GAPIPriv *ctx = (GAPIPriv *)dr->opaque; if (the_video_driver) return; the_video_driver = dr; if (!ctx->hWnd) { ctx->hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) GAPI_WindowThread, (LPVOID) dr, 0, &(ctx->ThreadID) ); while (!ctx->hWnd && ctx->hThread) gf_sleep(10); if (!ctx->hThread) return; ctx->owns_hwnd = 1; } else { ctx->orig_wnd_proc = GetWindowLong(ctx->hWnd, GWL_WNDPROC); /*override window proc*/ SetWindowLong(ctx->hWnd, GWL_WNDPROC, (DWORD) GAPI_WindowProc); }}void GAPI_ShutdownWindow(GF_VideoOutput *dr){ GAPIPriv *ctx = (GAPIPriv *)dr->opaque; if (ctx->owns_hwnd) { PostMessage(ctx->hWnd, WM_DESTROY, 0, 0); while (ctx->ThreadID) gf_sleep(10); UnregisterClass(_T("GPAC GAPI Output"), GetModuleHandle(_T("gapi.dll"))); CloseHandle(ctx->hThread); ctx->hThread = NULL; } else if (ctx->orig_wnd_proc) { /*restore window proc*/ SetWindowLong(ctx->hWnd, GWL_WNDPROC, ctx->orig_wnd_proc); ctx->orig_wnd_proc = 0L; } ctx->hWnd = NULL; the_video_driver = NULL;}GF_Err GAPI_Clear(GF_VideoOutput *dr, u32 color){ GAPICTX(dr); gctx->erase_dest = 1; return GF_OK;}static void createPixmap(GAPIPriv *ctx, HDC dc, Bool for_gl){ const size_t bmiSize = sizeof(BITMAPINFO) + 256U*sizeof(RGBQUAD); BITMAPINFO* bmi; DWORD* p; bmi = (BITMAPINFO*)malloc(bmiSize); memset(bmi, 0, bmiSize); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = ctx->bb_width; bmi->bmiHeader.biHeight = -1 * (s32) ctx->bb_height; /*top-down image*/ bmi->bmiHeader.biPlanes = (short)1; bmi->bmiHeader.biBitCount = (unsigned int) ctx->bits_per_pixel; bmi->bmiHeader.biCompression = BI_BITFIELDS; bmi->bmiHeader.biClrUsed = 3; p = (DWORD*)bmi->bmiColors; switch (ctx->pixel_format) { case GF_PIXEL_RGB_555: p[0] = 0x00007c00; p[1] = 0x000003e0; p[2] = 0x0000001f; break; case GF_PIXEL_RGB_565: p[0] = 0x0000f800; p[1] = 0x000007e0; p[2] = 0x0000001f; break; case GF_PIXEL_RGB_24: p[0] = 0x00ff0000; p[1] = 0x0000ff00; p[2] = 0x000000ff; break; } if (for_gl) { ctx->bitmap = CreateDIBSection(dc, bmi, DIB_RGB_COLORS, (void **) &ctx->bits, NULL, 0); } else { ctx->bitmap = CreateDIBSection(dc, bmi, DIB_RGB_COLORS, (void **) &ctx->backbuffer, NULL, 0); /*watchout - win32 always create DWORD align memory, so align our pitch*/ while ((ctx->bb_pitch % 4) != 0) ctx->bb_pitch ++; } free(bmi);}#ifdef GPAC_USE_OGL_ESvoid GAPI_ReleaseOGL_ES(GAPIPriv *ctx){ if (ctx->egldpy) { if (ctx->eglctx) eglDestroyContext(ctx->egldpy, ctx->eglctx); if (ctx->surface ) eglDestroySurface(ctx->egldpy, ctx->surface); if (ctx->egldpy) eglTerminate(ctx->egldpy); ctx->egldpy = 0; } if (ctx->bitmap) DeleteObject(ctx->bitmap); ctx->bitmap = NULL;}GF_Err GAPI_SetupOGL_ES(GF_VideoOutput *dr) { EGLint n, maj, min; GF_Event evt; HDC dc; GAPICTX(dr) static int atts[15]; atts[0] = EGL_RED_SIZE; atts[1] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : 5; atts[2] = EGL_GREEN_SIZE; atts[3] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : (gctx->pixel_format==GF_PIXEL_RGB_565) ? 6 : 5; atts[4] = EGL_BLUE_SIZE; atts[5] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : 5; /*no supported...*/ atts[6] = EGL_ALPHA_SIZE; atts[7] = EGL_DONT_CARE; atts[8] = EGL_DEPTH_SIZE; atts[9] = 32; atts[10] = EGL_STENCIL_SIZE; atts[11] = EGL_DONT_CARE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -