/** * Move or resize overlay surface on video display. * * This function is used to move or resize an overlay surface on the screen. * Ususally the overlay is moved by the user and thus, by a move or resize * event. */ static int DirectXUpdateOverlay(vout_display_t *vd, LPDIRECTDRAWSURFACE2 surface) { vout_display_sys_t *sys = vd->sys; RECT src = sys->rect_src_clipped; RECT dst = sys->rect_dest_clipped; if (sys->use_wallpaper) { src.left = vd->source.i_x_offset; src.top = vd->source.i_y_offset; src.right = vd->source.i_x_offset + vd->source.i_visible_width; src.bottom = vd->source.i_y_offset + vd->source.i_visible_height; AlignRect(&src, sys->i_align_src_boundary, sys->i_align_src_size); vout_display_cfg_t cfg = *vd->cfg; cfg.display.width = sys->rect_display.right; cfg.display.height = sys->rect_display.bottom; vout_display_place_t place; vout_display_PlacePicture(&place, &vd->source, &cfg, true); dst.left = sys->rect_display.left + place.x; dst.top = sys->rect_display.top + place.y; dst.right = dst.left + place.width; dst.bottom = dst.top + place.height; AlignRect(&dst, sys->i_align_dest_boundary, sys->i_align_dest_size); } if (!surface) { if (!sys->pool) return VLC_EGENERIC; surface = sys->resource.p_sys->front_surface; } /* The new window dimensions should already have been computed by the * caller of this function */ /* Position and show the overlay */ DDOVERLAYFX ddofx; ZeroMemory(&ddofx, sizeof(ddofx)); ddofx.dwSize = sizeof(ddofx); ddofx.dckDestColorkey.dwColorSpaceLowValue = sys->i_colorkey; ddofx.dckDestColorkey.dwColorSpaceHighValue = sys->i_colorkey; HRESULT hr = IDirectDrawSurface2_UpdateOverlay(surface, &src, sys->display, &dst, DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE, &ddofx); sys->restore_overlay = hr != DD_OK; if (hr != DD_OK) { msg_Warn(vd, "DirectDrawUpdateOverlay cannot move/resize overlay"); return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * UpdateRects: update clipping rectangles ***************************************************************************** * This function is called when the window position or size are changed, and * its job is to update the source and destination RECTs used to display the * picture. *****************************************************************************/ void UpdateRects(vout_display_t *vd, const vout_display_cfg_t *cfg, const video_format_t *source, bool is_forced) { vout_display_sys_t *sys = vd->sys; #define rect_src sys->rect_src #define rect_src_clipped sys->rect_src_clipped #define rect_dest sys->rect_dest #define rect_dest_clipped sys->rect_dest_clipped RECT rect; POINT point; /* */ if (!cfg) cfg = vd->cfg; if (!source) source = &vd->source; /* Retrieve the window size */ GetClientRect(sys->hwnd, &rect); /* Retrieve the window position */ point.x = point.y = 0; ClientToScreen(sys->hwnd, &point); /* If nothing changed, we can return */ bool has_moved; bool is_resized; EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized, point.x, point.y, rect.right, rect.bottom); if (is_resized) vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom, cfg->is_fullscreen); if (!is_forced && !has_moved && !is_resized ) return; /* Update the window position and size */ vout_display_cfg_t place_cfg = *cfg; place_cfg.display.width = rect.right; place_cfg.display.height = rect.bottom; vout_display_place_t place; vout_display_PlacePicture(&place, source, &place_cfg, false); EventThreadUpdateSourceAndPlace(sys->event, source, &place); if (sys->hvideownd) SetWindowPos(sys->hvideownd, 0, place.x, place.y, place.width, place.height, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS); /* Destination image position and dimensions */ #if defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d) rect_dest.left = 0; rect_dest.right = place.width; rect_dest.top = 0; rect_dest.bottom = place.height; #else rect_dest.left = point.x + place.x; rect_dest.right = rect_dest.left + place.width; rect_dest.top = point.y + place.y; rect_dest.bottom = rect_dest.top + place.height; #ifdef MODULE_NAME_IS_directdraw /* Apply overlay hardware constraints */ if (sys->use_overlay) AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size); #endif #endif #if defined(MODULE_NAME_IS_directdraw) /* UpdateOverlay directdraw function doesn't automatically clip to the * display size so we need to do it otherwise it will fail */ /* Clip the destination window */ if (!IntersectRect(&rect_dest_clipped, &rect_dest, &sys->rect_display)) { SetRectEmpty(&rect_src_clipped); goto exit; } #ifndef NDEBUG msg_Dbg(vd, "DirectXUpdateRects image_dst_clipped coords:" " %li,%li,%li,%li", rect_dest_clipped.left, rect_dest_clipped.top, rect_dest_clipped.right, rect_dest_clipped.bottom); #endif #else /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */ rect_dest_clipped = rect_dest; #endif /* the 2 following lines are to fix a bug when clicking on the desktop */ if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 || (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) { SetRectEmpty(&rect_src_clipped); goto exit; } /* src image dimensions */ rect_src.left = 0; rect_src.top = 0; rect_src.right = source->i_width; rect_src.bottom = source->i_height; /* Clip the source image */ rect_src_clipped.left = source->i_x_offset + (rect_dest_clipped.left - rect_dest.left) * source->i_visible_width / (rect_dest.right - rect_dest.left); rect_src_clipped.right = source->i_x_offset + source->i_visible_width - (rect_dest.right - rect_dest_clipped.right) * source->i_visible_width / (rect_dest.right - rect_dest.left); rect_src_clipped.top = source->i_y_offset + (rect_dest_clipped.top - rect_dest.top) * source->i_visible_height / (rect_dest.bottom - rect_dest.top); rect_src_clipped.bottom = source->i_y_offset + source->i_visible_height - (rect_dest.bottom - rect_dest_clipped.bottom) * source->i_visible_height / (rect_dest.bottom - rect_dest.top); #ifdef MODULE_NAME_IS_directdraw /* Apply overlay hardware constraints */ if (sys->use_overlay) AlignRect(&rect_src_clipped, sys->i_align_src_boundary, sys->i_align_src_size); #elif defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d) /* Needed at least with YUV content */ rect_src_clipped.left &= ~1; rect_src_clipped.right &= ~1; rect_src_clipped.top &= ~1; rect_src_clipped.bottom &= ~1; #endif #ifndef NDEBUG msg_Dbg(vd, "DirectXUpdateRects image_src_clipped" " coords: %li,%li,%li,%li", rect_src_clipped.left, rect_src_clipped.top, rect_src_clipped.right, rect_src_clipped.bottom); #endif #ifdef MODULE_NAME_IS_directdraw /* The destination coordinates need to be relative to the current * directdraw primary surface (display) */ rect_dest_clipped.left -= sys->rect_display.left; rect_dest_clipped.right -= sys->rect_display.left; rect_dest_clipped.top -= sys->rect_display.top; rect_dest_clipped.bottom -= sys->rect_display.top; #endif CommonChangeThumbnailClip(vd, true); exit: /* Signal the change in size/position */ sys->changes |= DX_POSITION_CHANGE; #undef rect_src #undef rect_src_clipped #undef rect_dest #undef rect_dest_clipped }
void iDialog::Center() { iRect rect = AlignRect(GetDlgMetrics(), m_pMgr->Metrics(), AlignCenter); OnPlace(rect); SetRect(rect); }