📄 dx_window.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / DirectX audio and 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 "dx_hw.h"#include <gpac/user.h>#include "resource.h"/*crude redef of winuser.h due to windows/winsock2 conflicts*/#ifndef WM_MOUSEWHEEL#define WM_MOUSEWHEEL 0x020A#define WHEEL_DELTA 120#endif/*mouse hiding timeout in fullscreen, in milliseconds*/#define MOUSE_HIDE_TIMEOUT 1000static const GF_VideoOutput *the_video_output = NULL;void DD_SetCursor(GF_VideoOutput *dr, u32 cursor_type);static void DD_GetCoordinates(DWORD lParam, GF_Event *evt){ POINTS pt = MAKEPOINTS(lParam); 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_NONCONVERT: evt->key_code = GF_KEY_NONCONVERT; break; case VK_ACCEPT: evt->key_code = GF_KEY_ACCEPT; break; case VK_MODECHANGE: evt->key_code = GF_KEY_MODECHANGE; 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 '!': evt->key_code = GF_KEY_EXCLAMATION; break; case '"': evt->key_code = GF_KEY_QUOTATION; break; case '#': evt->key_code = GF_KEY_NUMBER; break; case '$': evt->key_code = GF_KEY_DOLLAR; break; case '&': evt->key_code = GF_KEY_AMPERSAND; break; case '\'': evt->key_code = GF_KEY_APOSTROPHE; break; case '(': evt->key_code = GF_KEY_LEFTPARENTHESIS; break; case ')': evt->key_code = GF_KEY_RIGHTPARENTHESIS; break; case ',': evt->key_code = GF_KEY_COMMA; break; case ':': evt->key_code = GF_KEY_COLON; break; case ';': evt->key_code = GF_KEY_SEMICOLON; break; case '<': evt->key_code = GF_KEY_LESSTHAN; break; case '>': evt->key_code = GF_KEY_GREATERTHAN; break; case '?': evt->key_code = GF_KEY_QUESTION; break; case '@': evt->key_code = GF_KEY_AT; break; case '[': evt->key_code = GF_KEY_LEFTSQUAREBRACKET; break; case ']': evt->key_code = GF_KEY_RIGHTSQUAREBRACKET; break; case '\\': evt->key_code = GF_KEY_BACKSLASH; break; case '_': evt->key_code = GF_KEY_UNDERSCORE; break; case '`': evt->key_code = GF_KEY_GRAVEACCENT; break; case ' ': evt->key_code = GF_KEY_SPACE; break; case '/': evt->key_code = GF_KEY_SLASH; break; case '*': evt->key_code = GF_KEY_STAR; break; case '-': evt->key_code = GF_KEY_HIPHEN; break; case '+': evt->key_code = GF_KEY_PLUS; break; case '=': evt->key_code = GF_KEY_EQUALS; break; case '^': evt->key_code = GF_KEY_CIRCUM; break; case '{': evt->key_code = GF_KEY_LEFTCURLYBRACKET; break; case '}': evt->key_code = GF_KEY_RIGHTCURLYBRACKET; break; case '|': evt->key_code = GF_KEY_PIPE; 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-0x41; /*DOM 3 Events: Implementations that are unable to identify a key must use the key identifier "Unidentified".*/ else evt->key_code = GF_KEY_UNIDENTIFIED; break; }}static void mouse_move(DDContext *ctx, GF_VideoOutput *vout){ if (ctx->fullscreen) { ctx->last_mouse_move = gf_sys_clock(); if (ctx->cursor_type==GF_CURSOR_HIDE) DD_SetCursor(vout, ctx->cursor_type_backup); }}static void mouse_start_timer(DDContext *ctx, HWND hWnd, GF_VideoOutput *vout){ if (ctx->fullscreen) { if (!ctx->timer) ctx->timer = SetTimer(hWnd, 10, 1000, NULL); mouse_move(ctx, vout); }}void grab_mouse(DDContext *ctx, GF_VideoOutput *vout){ if (ctx->fullscreen) DD_SetCursor(vout, GF_CURSOR_NORMAL); SetCapture(ctx->cur_hwnd); mouse_move(ctx, vout);}void release_mouse(DDContext *ctx, HWND hWnd, GF_VideoOutput *vout){ ReleaseCapture(); mouse_start_timer(ctx, hWnd, vout);}LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam){ GF_Event evt; DDContext *ctx; GF_VideoOutput *vout = (GF_VideoOutput *) GetWindowLong(hWnd, GWL_USERDATA); if (!vout) return DefWindowProc (hWnd, msg, wParam, lParam); ctx = (DDContext *)vout->opaque; switch (msg) { case WM_SIZE: /*always notify GPAC since we're not sure the owner of the window is listening to these events*/ evt.type = GF_EVENT_SIZE; evt.size.width = LOWORD(lParam); evt.size.height = HIWORD(lParam); vout->on_event(vout->evt_cbk_hdl, &evt); break; case WM_CLOSE: if (hWnd==ctx->os_hwnd) { evt.type = GF_EVENT_QUIT; vout->on_event(vout->evt_cbk_hdl, &evt); } return 1; case WM_DESTROY: if (ctx->owns_hwnd || (hWnd==ctx->fs_hwnd)) { PostQuitMessage (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; } break; case WM_ACTIVATE:#if 1 if (ctx->fullscreen && (LOWORD(wParam)==WA_INACTIVE) && (hWnd==ctx->fs_hwnd)) { evt.type = GF_EVENT_SHOWHIDE; vout->on_event(vout->evt_cbk_hdl, &evt); }#endif break; case WM_SETCURSOR: if (ctx->cur_hwnd==hWnd) DD_SetCursor(vout, ctx->cursor_type); return 1; case WM_ERASEBKGND: //InvalidateRect(ctx->cur_hwnd, NULL, TRUE); //break; case WM_PAINT: if (ctx->cur_hwnd==hWnd) { evt.type = GF_EVENT_REFRESH; vout->on_event(vout->evt_cbk_hdl, &evt); } break; case WM_KILLFOCUS: if (hWnd==ctx->os_hwnd) ctx->has_focus = 0; break; case WM_MOUSEMOVE: if (ctx->cur_hwnd!=hWnd) break; if (ctx->last_mouse_pos != lParam) { ctx->last_mouse_pos = lParam; DD_SetCursor(vout, (ctx->cursor_type==GF_CURSOR_HIDE) ? ctx->cursor_type_backup : ctx->cursor_type); evt.type = GF_EVENT_MOUSEMOVE; DD_GetCoordinates(lParam, &evt); vout->on_event(vout->evt_cbk_hdl, &evt); mouse_start_timer(ctx, hWnd, vout); } break; case WM_TIMER: if (wParam==10) { if (ctx->fullscreen && (ctx->cursor_type!=GF_CURSOR_HIDE)) { if (gf_sys_clock() > MOUSE_HIDE_TIMEOUT + ctx->last_mouse_move) { ctx->cursor_type_backup = ctx->cursor_type; DD_SetCursor(vout, GF_CURSOR_HIDE); KillTimer(hWnd, ctx->timer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -