📄 dx_window.c
字号:
ctx->timer = 0; } } } break; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: grab_mouse(ctx, vout); evt.type = GF_EVENT_MOUSEDOWN; DD_GetCoordinates(lParam, &evt); evt.mouse.button = GF_MOUSE_LEFT; vout->on_event(vout->evt_cbk_hdl, &evt); if (!ctx->has_focus && (hWnd==ctx->os_hwnd)) { ctx->has_focus = 1; SetFocus(ctx->os_hwnd); } break; case WM_LBUTTONUP: release_mouse(ctx, hWnd, vout); evt.type = GF_EVENT_MOUSEUP; DD_GetCoordinates(lParam, &evt); evt.mouse.button = GF_MOUSE_LEFT; vout->on_event(vout->evt_cbk_hdl, &evt); break; case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: grab_mouse(ctx, vout); evt.type = GF_EVENT_MOUSEDOWN; DD_GetCoordinates(lParam, &evt); evt.mouse.button = GF_MOUSE_RIGHT; vout->on_event(vout->evt_cbk_hdl, &evt); if (!ctx->has_focus && (hWnd==ctx->os_hwnd)) { ctx->has_focus = 1; SetFocus(ctx->os_hwnd); } break; case WM_RBUTTONUP: release_mouse(ctx, hWnd, vout); evt.type = GF_EVENT_MOUSEUP; DD_GetCoordinates(lParam, &evt); evt.mouse.button = GF_MOUSE_RIGHT; vout->on_event(vout->evt_cbk_hdl, &evt); mouse_start_timer(ctx, hWnd, vout); break; case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: grab_mouse(ctx, vout); evt.type = GF_EVENT_MOUSEDOWN; evt.mouse.button = GF_MOUSE_MIDDLE; DD_GetCoordinates(lParam, &evt); vout->on_event(vout->evt_cbk_hdl, &evt); if (!ctx->has_focus && (hWnd==ctx->os_hwnd)) { ctx->has_focus = 1; SetFocus(ctx->os_hwnd); } break; case WM_MBUTTONUP: release_mouse(ctx, hWnd, vout); evt.type = GF_EVENT_MOUSEUP; DD_GetCoordinates(lParam, &evt); evt.mouse.button = GF_MOUSE_MIDDLE; vout->on_event(vout->evt_cbk_hdl, &evt); mouse_start_timer(ctx, hWnd, vout); break; case WM_MOUSEWHEEL: if (ctx->cur_hwnd==hWnd) { DD_SetCursor(vout, (ctx->cursor_type==GF_CURSOR_HIDE) ? ctx->cursor_type_backup : ctx->cursor_type); evt.type = GF_EVENT_MOUSEWHEEL; DD_GetCoordinates(lParam, &evt); evt.mouse.wheel_pos = FLT2FIX( ((Float) (s16) HIWORD(wParam)) / WHEEL_DELTA ); vout->on_event(vout->evt_cbk_hdl, &evt); mouse_start_timer(ctx, hWnd, vout); } return 1; /*there's a bug on alt state (we miss one event)*/ case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYUP: case WM_KEYDOWN: w32_translate_key(wParam, lParam, &evt.key); evt.type = ((msg==WM_SYSKEYDOWN) || (msg==WM_KEYDOWN)) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; vout->on_event(vout->evt_cbk_hdl, &evt); break; case WM_CHAR: evt.type = GF_EVENT_TEXTINPUT; evt.character.unicode_char = wParam; vout->on_event(vout->evt_cbk_hdl, &evt); break; } return DefWindowProc (hWnd, msg, wParam, lParam);}#ifndef WS_EX_LAYERED#define WS_EX_LAYERED 0x80000 #endif#ifndef LWA_COLORKEY#define LWA_COLORKEY 0x00000001#endif#ifndef LWA_ALPHA#define LWA_ALPHA 0x00000002#endiftypedef BOOL (WINAPI* typSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);static void SetWindowless(GF_VideoOutput *vout, HWND hWnd){ const char *opt; u32 a, r, g, b; COLORREF ckey; typSetLayeredWindowAttributes _SetLayeredWindowAttributes; HMODULE hUser32; u32 isWin2K; OSVERSIONINFO Version = {sizeof(OSVERSIONINFO)}; GetVersionEx(&Version); isWin2K = (Version.dwPlatformId == VER_PLATFORM_WIN32_NT && Version.dwMajorVersion >= 5); if (!isWin2K) return; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX Out] Enabling windowless mode\n")); hUser32 = GetModuleHandle("USER32.DLL"); if (hUser32 == NULL) return; _SetLayeredWindowAttributes = (typSetLayeredWindowAttributes) GetProcAddress(hUser32,"SetLayeredWindowAttributes"); if (_SetLayeredWindowAttributes == NULL) { GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[DX Out] Win32 layered windows not supported\n")); return; } SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); /*get background ckey*/ opt = gf_modules_get_option((GF_BaseInterface *)vout, "Rendering", "ColorKey"); if (!opt) { gf_modules_set_option((GF_BaseInterface *)vout, "Rendering", "ColorKey", "FFFEFEFE"); opt = "FFFEFEFE"; } sscanf(opt, "%02X%02X%02X%02X", &a, &r, &g, &b); ckey = RGB(r, g, b); if (a<255) _SetLayeredWindowAttributes(hWnd, ckey, (u8) a, LWA_COLORKEY|LWA_ALPHA); else _SetLayeredWindowAttributes(hWnd, ckey, 0, LWA_COLORKEY); GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX Out] Using color key %s\n", opt));} u32 DD_WindowThread(void *par){ u32 flags; RECT rc; MSG msg; WNDCLASS wc; HINSTANCE hInst; GF_VideoOutput *vout = par; DDContext *ctx = (DDContext *)vout->opaque; GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[DirectXOutput] Entering thread ID %d\n", gf_th_id() )); hInst = GetModuleHandle("gm_dx_hw.dll"); memset(&wc, 0, sizeof(WNDCLASS)); wc.style = CS_BYTEALIGNWINDOW; wc.hInstance = hInst; wc.lpfnWndProc = DD_WindowProc; wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH); wc.lpszClassName = "GPAC DirectDraw Output"; RegisterClass (&wc); flags = ctx->switch_res; ctx->switch_res = 0; if (!ctx->os_hwnd) { if (flags & GF_TERM_WINDOWLESS) ctx->windowless = 1; ctx->os_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC DirectDraw Output", ctx->windowless ? WS_POPUP : WS_OVERLAPPEDWINDOW, 0, 0, 120, 100, NULL, NULL, hInst, NULL); if (ctx->os_hwnd == NULL) { ctx->th_state = 2; return 1; } if (flags & GF_TERM_INIT_HIDE) { ShowWindow(ctx->os_hwnd, SW_HIDE); } else { SetForegroundWindow(ctx->os_hwnd); ShowWindow(ctx->os_hwnd, SW_SHOWNORMAL); } /*get border & title bar sizes*/ rc.left = rc.top = 0; rc.right = rc.bottom = 100; AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, 0); ctx->off_w = rc.right - rc.left - 100; ctx->off_h = rc.bottom - rc.top - 100; ctx->owns_hwnd = 1; if (ctx->windowless) SetWindowless(vout, ctx->os_hwnd); } ctx->fs_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC DirectDraw FS Output", WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); if (!ctx->fs_hwnd) { ctx->th_state = 2; return 1; } ShowWindow(ctx->fs_hwnd, SW_HIDE); ctx->th_state = 1; /*if visible set focus*/ if (!ctx->switch_res) SetFocus(ctx->os_hwnd); ctx->switch_res = 0; SetWindowLong(ctx->os_hwnd, GWL_USERDATA, (LONG) vout); SetWindowLong(ctx->fs_hwnd, GWL_USERDATA, (LONG) vout); /*load cursors*/ ctx->curs_normal = LoadCursor(NULL, IDC_ARROW); assert(ctx->curs_normal); ctx->curs_hand = LoadCursor(hInst, MAKEINTRESOURCE(IDC_HAND_PTR)); ctx->curs_collide = LoadCursor(hInst, MAKEINTRESOURCE(IDC_COLLIDE)); ctx->cursor_type = GF_CURSOR_NORMAL; while (GetMessage (&(msg), NULL, 0, 0)) { TranslateMessage (&(msg)); DispatchMessage (&(msg)); } ctx->th_state = 2; return 0;}void DD_SetupWindow(GF_VideoOutput *dr, u32 flags){ DDContext *ctx = (DDContext *)dr->opaque; if (ctx->os_hwnd) { /*override window proc*/ if (!(flags & GF_TERM_NO_WINDOWPROC_OVERRIDE) ) { ctx->orig_wnd_proc = GetWindowLong(ctx->os_hwnd, GWL_WNDPROC); SetWindowLong(ctx->os_hwnd, GWL_WNDPROC, (DWORD) DD_WindowProc); } } ctx->switch_res = flags; /*create our event thread - since we always have a dedicated window for fullscreen, we need that even when a window is passed to us*/ ctx->th = gf_th_new(); gf_th_run(ctx->th, DD_WindowThread, dr); while (!ctx->th_state) gf_sleep(2); if (!the_video_output) the_video_output = dr;}void DD_ShutdownWindow(GF_VideoOutput *dr){ DDContext *ctx = (DDContext *)dr->opaque; if (ctx->owns_hwnd) { PostMessage(ctx->os_hwnd, WM_DESTROY, 0, 0); } else if (ctx->orig_wnd_proc) { /*restore window proc*/ //SetWindowLong(ctx->os_hwnd, GWL_WNDPROC, ctx->orig_wnd_proc); ctx->orig_wnd_proc = 0L; } PostMessage(ctx->fs_hwnd, WM_DESTROY, 0, 0); while (ctx->th_state!=2) gf_sleep(10); UnregisterClass("GPAC DirectDraw Output", GetModuleHandle("gm_dx_hw.dll")); gf_th_del(ctx->th); ctx->th = NULL; ctx->os_hwnd = NULL; ctx->fs_hwnd = NULL; the_video_output = NULL;}void DD_SetCursor(GF_VideoOutput *dr, u32 cursor_type){ DDContext *ctx = (DDContext *)dr->opaque; if (cursor_type==GF_CURSOR_HIDE) { if (ctx->cursor_type!=GF_CURSOR_HIDE) { ShowCursor(FALSE); ctx->cursor_type = cursor_type; } return; } if (ctx->cursor_type==GF_CURSOR_HIDE) ShowCursor(TRUE); ctx->cursor_type = cursor_type; switch (cursor_type) { case GF_CURSOR_ANCHOR: case GF_CURSOR_TOUCH: case GF_CURSOR_ROTATE: case GF_CURSOR_PROXIMITY: case GF_CURSOR_PLANE: SetCursor(ctx->curs_hand); break; case GF_CURSOR_COLLIDE: SetCursor(ctx->curs_collide); break; default: SetCursor(ctx->curs_normal); break; }}HWND DD_GetGlobalHWND(){ if (!the_video_output) return NULL; return ((DDContext*)the_video_output->opaque)->os_hwnd;}GF_Err DD_ProcessEvent(GF_VideoOutput*dr, GF_Event *evt){ DDContext *ctx = (DDContext *)dr->opaque; if (!evt) return GF_OK; switch (evt->type) { case GF_EVENT_SET_CURSOR: DD_SetCursor(dr, evt->cursor.cursor_type); break; case GF_EVENT_SET_CAPTION: if (evt->caption.caption) SetWindowText(ctx->os_hwnd, evt->caption.caption); break; case GF_EVENT_MOVE: if (evt->move.relative == 2) { u32 x, y, fsw, fsh; x = y = 0; fsw = GetSystemMetrics(SM_CXSCREEN); fsh = GetSystemMetrics(SM_CYSCREEN); if (evt->move.align_x==1) x = (fsw - ctx->width) / 2; else if (evt->move.align_x==2) x = fsw - ctx->width; if (evt->move.align_y==1) y = (fsh - ctx->height) / 2; else if (evt->move.align_y==2) y = fsh - ctx->height; SetWindowPos(ctx->os_hwnd, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } else if (evt->move.relative) { POINT pt; pt.x = pt.y = 0; MapWindowPoints(ctx->os_hwnd, NULL, &pt, 1); SetWindowPos(ctx->os_hwnd, NULL, evt->move.x + pt.x, evt->move.y + pt.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } else { SetWindowPos(ctx->os_hwnd, NULL, evt->move.x, evt->move.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } break; case GF_EVENT_SHOWHIDE: ShowWindow(ctx->os_hwnd, evt->show.show_type ? SW_SHOW : SW_HIDE); break; /*if scene resize resize window*/ case GF_EVENT_SIZE: if (ctx->owns_hwnd) { if (ctx->windowless) SetWindowPos(ctx->os_hwnd, NULL, 0, 0, evt->size.width, evt->size.height, SWP_NOZORDER | SWP_NOMOVE); else SetWindowPos(ctx->os_hwnd, NULL, 0, 0, evt->size.width + ctx->off_w, evt->size.height + ctx->off_h, SWP_NOZORDER | SWP_NOMOVE); if (ctx->fullscreen) { ctx->store_width = evt->size.width; ctx->store_height = evt->size.height; } } break; /*HW setup*/ case GF_EVENT_VIDEO_SETUP: if (ctx->is_3D_out) { ctx->width = evt->size.width; ctx->height = evt->size.height; return DD_SetupOpenGL(dr); } return DD_SetBackBufferSize(dr, evt->size.width, evt->size.height); } return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -