/** * \brief Dispatch incoming window events and handle them. * * This function should be placed inside libvo's function "check_events". * * \return int with these flags possibly set, take care to handle in the right order * if it matters in your driver: * * VO_EVENT_RESIZE = The window was resized. If necessary reinit your * driver render context accordingly. * VO_EVENT_EXPOSE = The window was exposed. Call e.g. flip_frame() to redraw * the window if the movie is paused. */ int vo_w32_check_events(struct vo *vo) { struct vo_w32_state *w32 = vo->w32; MSG msg; w32->event_flags = 0; while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessageW(&msg); } if (vo->opts->WinID >= 0) { BOOL res; RECT r; POINT p; res = GetClientRect(w32->window, &r); if (res && (r.right != vo->dwidth || r.bottom != vo->dheight)) { vo->dwidth = r.right; vo->dheight = r.bottom; w32->event_flags |= VO_EVENT_RESIZE; } p.x = 0; p.y = 0; ClientToScreen(w32->window, &p); if (p.x != w32->window_x || p.y != w32->window_y) { w32->window_x = p.x; w32->window_y = p.y; } res = GetClientRect(WIN_ID_TO_HWND(vo->opts->WinID), &r); if (res && (r.right != vo->dwidth || r.bottom != vo->dheight)) MoveWindow(w32->window, 0, 0, r.right, r.bottom, FALSE); if (!IsWindow(WIN_ID_TO_HWND(vo->opts->WinID))) // Window has probably been closed, e.g. due to program crash mplayer_put_key(vo->key_fifo, MP_KEY_CLOSE_WIN); } return w32->event_flags; }
/** * \brief Initialize w32_common framework. * * The first function that should be called from the w32_common framework. * It handles window creation on the screen with proper title and attributes. * It also initializes the framework's internal variables. The function should * be called after your own preinit initialization and you shouldn't do any * window management on your own. * * Global libvo variables changed: * vo_w32_window * vo_screenwidth * vo_screenheight * * \return 1 = Success, 0 = Failure */ int vo_w32_init(struct vo *vo) { struct vo_w32_state *w32 = vo->w32; if (w32 && w32->window) return 1; if (!w32) w32 = vo->w32 = talloc_zero(vo, struct vo_w32_state); HINSTANCE hInstance = GetModuleHandleW(NULL); HICON mplayerIcon = LoadIconW(hInstance, L"IDI_ICON1"); WNDCLASSEXW wcex = { .cbSize = sizeof wcex, .style = CS_OWNDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, .lpfnWndProc = WndProc, .hInstance = hInstance, .hIcon = mplayerIcon, .hCursor = LoadCursor(0, IDC_ARROW), .lpszClassName = classname, .hIconSm = mplayerIcon, }; if (!RegisterClassExW(&wcex)) { mp_msg(MSGT_VO, MSGL_ERR, "vo: win32: unable to register window class!\n"); return 0; } if (vo->opts->WinID >= 0) { RECT r; GetClientRect(WIN_ID_TO_HWND(vo->opts->WinID), &r); vo->dwidth = r.right; vo->dheight = r.bottom; w32->window = CreateWindowExW(WS_EX_NOPARENTNOTIFY, classname, classname, WS_CHILD | WS_VISIBLE, 0, 0, vo->dwidth, vo->dheight, WIN_ID_TO_HWND(vo->opts->WinID), 0, hInstance, vo); } else { w32->window = CreateWindowExW(0, classname, classname, update_style(vo, 0), CW_USEDEFAULT, 0, 100, 100, 0, 0, hInstance, vo); } if (!w32->window) { mp_msg(MSGT_VO, MSGL_ERR, "vo: win32: unable to create window!\n"); return 0; } if (vo->opts->WinID >= 0) EnableWindow(w32->window, 0); // we don't have proper event handling vo->wakeup_period = 0.02; updateScreenProperties(vo); mp_msg(MSGT_VO, MSGL_V, "vo: win32: running at %dx%d\n", vo->opts->screenwidth, vo->opts->screenheight); return 1; } /** * \brief Toogle fullscreen / windowed mode. * * Should be called on VOCTRL_FULLSCREEN event. The window is * always resized during this call, so the rendering context * should be reinitialized with the new dimensions. * It is unspecified if vo_check_events will create a resize * event in addition or not. */ void vo_w32_fullscreen(struct vo *vo) { vo->opts->fs = !vo->opts->fs; reinit_window_state(vo); }
/** * \brief Initialize w32_common framework. * * The first function that should be called from the w32_common framework. * It handles window creation on the screen with proper title and attributes. * It also initializes the framework's internal variables. The function should * be called after your own preinit initialization and you shouldn't do any * window management on your own. * * Global libvo variables changed: * vo_w32_window * vo_screenwidth * vo_screenheight * * \return 1 = Success, 0 = Failure */ int vo_w32_init(struct vo *vo) { assert(!vo->w32); struct vo_w32_state *w32 = talloc_zero(vo, struct vo_w32_state); vo->w32 = w32; HINSTANCE hInstance = GetModuleHandleW(NULL); HICON mplayerIcon = LoadIconW(hInstance, L"IDI_ICON1"); WNDCLASSEXW wcex = { .cbSize = sizeof wcex, .style = CS_OWNDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, .lpfnWndProc = WndProc, .hInstance = hInstance, .hIcon = mplayerIcon, .hCursor = LoadCursor(NULL, IDC_ARROW), .lpszClassName = classname, .hIconSm = mplayerIcon, }; if (!RegisterClassExW(&wcex)) { MP_ERR(vo, "win32: unable to register window class!\n"); return 0; } if (vo->opts->WinID >= 0) { RECT r; GetClientRect(WIN_ID_TO_HWND(vo->opts->WinID), &r); vo->dwidth = r.right; vo->dheight = r.bottom; w32->window = CreateWindowExW(WS_EX_NOPARENTNOTIFY, classname, classname, WS_CHILD | WS_VISIBLE, 0, 0, vo->dwidth, vo->dheight, WIN_ID_TO_HWND(vo->opts->WinID), 0, hInstance, vo); } else { w32->window = CreateWindowExW(0, classname, classname, update_style(vo, 0), CW_USEDEFAULT, 0, 100, 100, 0, 0, hInstance, vo); } if (!w32->window) { MP_ERR(vo, "win32: unable to create window!\n"); return 0; } w32->tracking = FALSE; w32->trackEvent = (TRACKMOUSEEVENT){ .cbSize = sizeof(TRACKMOUSEEVENT), .dwFlags = TME_LEAVE, .hwndTrack = w32->window, }; if (vo->opts->WinID >= 0) EnableWindow(w32->window, 0); w32->cursor_visible = true; // we don't have proper event handling vo->wakeup_period = 0.02; updateScreenProperties(vo); MP_VERBOSE(vo, "win32: running at %dx%d\n", vo->opts->screenwidth, vo->opts->screenheight); return 1; } /** * \brief Toogle fullscreen / windowed mode. * * Should be called on VOCTRL_FULLSCREEN event. The window is * always resized during this call, so the rendering context * should be reinitialized with the new dimensions. * It is unspecified if vo_check_events will create a resize * event in addition or not. */ static void vo_w32_fullscreen(struct vo *vo) { if (vo->opts->fullscreen != vo->w32->current_fs) reinit_window_state(vo); } /** * \brief Toogle window border attribute. * * Should be called on VOCTRL_BORDER event. */ static void vo_w32_border(struct vo *vo) { vo->opts->border = !vo->opts->border; reinit_window_state(vo); } /** * \brief Toogle window ontop attribute. * * Should be called on VOCTRL_ONTOP event. */ static void vo_w32_ontop(struct vo *vo) { vo->opts->ontop = !vo->opts->ontop; reinit_window_state(vo); }