X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=activex%2Fplugin.cpp;h=eed61162602e6f06af4592db2416c0298afec097;hb=6662b32f51193ab2e8aef48af832178ab085ce15;hp=22914c322450b04cc4cbf6db8a61573c102daefb;hpb=727b4c332e17015432784708514d388f1cbf3b6b;p=vlc diff --git a/activex/plugin.cpp b/activex/plugin.cpp index 22914c3224..eed6116260 100644 --- a/activex/plugin.cpp +++ b/activex/plugin.cpp @@ -36,6 +36,7 @@ #include "vlccontrol2.h" #include "viewobject.h" #include "dataobject.h" +#include "supporterrorinfo.h" #include "utils.h" @@ -52,26 +53,6 @@ using namespace std; //class factory static LRESULT CALLBACK VLCInPlaceClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch( uMsg ) - { - case WM_ERASEBKGND: - return 1L; - - case WM_PAINT: - PAINTSTRUCT ps; - if( GetUpdateRect(hWnd, NULL, FALSE) ) - { - BeginPaint(hWnd, &ps); - EndPaint(hWnd, &ps); - } - return 0L; - - default: - return DefWindowProc(hWnd, uMsg, wParam, lParam); - } -}; - -static LRESULT CALLBACK VLCVideoClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { VLCPlugin *p_instance = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); switch( uMsg ) @@ -117,7 +98,7 @@ VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance, REFCLSID wClass.hbrBackground = NULL; wClass.lpszMenuName = NULL; wClass.lpszClassName = getInPlaceWndClassName(); - + _inplace_wndclass_atom = RegisterClass(&wClass); } else @@ -125,26 +106,6 @@ VLCPluginClass::VLCPluginClass(LONG *p_class_ref, HINSTANCE hInstance, REFCLSID _inplace_wndclass_atom = 0; } - if( ! GetClassInfo(hInstance, getVideoWndClassName(), &wClass) ) - { - wClass.style = CS_NOCLOSE; - wClass.lpfnWndProc = VLCVideoClassWndProc; - wClass.cbClsExtra = 0; - wClass.cbWndExtra = 0; - wClass.hInstance = hInstance; - wClass.hIcon = NULL; - wClass.hCursor = LoadCursor(NULL, IDC_ARROW); - wClass.hbrBackground = NULL; - wClass.lpszMenuName = NULL; - wClass.lpszClassName = getVideoWndClassName(); - - _video_wndclass_atom = RegisterClass(&wClass); - } - else - { - _video_wndclass_atom = 0; - } - HBITMAP hbitmap = (HBITMAP)LoadImage(getHInstance(), TEXT("INPLACE-PICT"), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); if( NULL != hbitmap ) { @@ -166,9 +127,6 @@ VLCPluginClass::~VLCPluginClass() if( 0 != _inplace_wndclass_atom ) UnregisterClass(MAKEINTATOM(_inplace_wndclass_atom), _hinstance); - if( 0 != _video_wndclass_atom ) - UnregisterClass(MAKEINTATOM(_video_wndclass_atom), _hinstance); - if( NULL != _inplace_picture ) _inplace_picture->Release(); }; @@ -223,6 +181,7 @@ STDMETHODIMP VLCPluginClass::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, vo if( NULL != plugin ) { HRESULT hr = plugin->QueryInterface(riid, ppv); + // the following will destroy the object if QueryInterface() failed plugin->Release(); return hr; } @@ -243,7 +202,6 @@ STDMETHODIMP VLCPluginClass::LockServer(BOOL fLock) VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : _inplacewnd(NULL), - _videownd(NULL), _p_class(p_class), _i_ref(1UL), _p_libvlc(NULL), @@ -266,6 +224,7 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : vlcViewObject = new VLCViewObject(this); vlcDataObject = new VLCDataObject(this); vlcOleObject = new VLCOleObject(this); + vlcSupportErrorInfo = new VLCSupportErrorInfo(this); // configure controlling IUnknown interface for implemented interfaces this->pUnkOuter = (NULL != pUnkOuter) ? pUnkOuter : dynamic_cast(this); @@ -279,6 +238,7 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : VLCPlugin::~VLCPlugin() { + delete vlcSupportErrorInfo; delete vlcOleObject; delete vlcDataObject; delete vlcViewObject; @@ -298,6 +258,7 @@ VLCPlugin::~VLCPlugin() _p_pict->Release(); SysFreeString(_bstr_mrl); + SysFreeString(_bstr_baseurl); _p_class->Release(); }; @@ -349,6 +310,8 @@ STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv) *ppv = reinterpret_cast(vlcViewObject); else if( IID_IDataObject == riid ) *ppv = reinterpret_cast(vlcDataObject); + else if( IID_ISupportErrorInfo == riid ) + *ppv = reinterpret_cast(vlcSupportErrorInfo); else { *ppv = NULL; @@ -375,106 +338,15 @@ STDMETHODIMP_(ULONG) VLCPlugin::Release(void) ////////////////////////////////////// -/* -** we use a window to represent plugin viewport, -** whose geometry is limited by the clipping rectangle -** all drawing within this window must follow must -** follow coordinates system described in lprPosRect -*/ - -static void getViewportCoords(LPRECT lprPosRect, LPRECT lprClipRect) -{ - RECT bounds; - bounds.right = lprPosRect->right-lprPosRect->left; - - if( lprClipRect->left <= lprPosRect->left ) - { - // left side is not clipped out - bounds.left = 0; - - if( lprClipRect->right >= lprPosRect->right ) - { - // right side is not clipped out, no change - } - else if( lprClipRect->right >= lprPosRect->left ) - { - // right side is clipped out - lprPosRect->right = lprClipRect->right; - } - else - { - // outside of clipping rectange, not visible - lprPosRect->right = lprPosRect->left; - } - } - else - { - // left side is clipped out - bounds.left = lprPosRect->left-lprClipRect->left; - bounds.right += bounds.left; - - lprPosRect->left = lprClipRect->left; - if( lprClipRect->right >= lprPosRect->right ) - { - // right side is not clipped out - } - else - { - // right side is clipped out - lprPosRect->right = lprClipRect->right; - } - } - - bounds.bottom = lprPosRect->bottom-lprPosRect->top; - - if( lprClipRect->top <= lprPosRect->top ) - { - // top side is not clipped out - bounds.top = 0; - - if( lprClipRect->bottom >= lprPosRect->bottom ) - { - // bottom side is not clipped out, no change - } - else if( lprClipRect->bottom >= lprPosRect->top ) - { - // bottom side is clipped out - lprPosRect->bottom = lprClipRect->bottom; - } - else - { - // outside of clipping rectange, not visible - lprPosRect->right = lprPosRect->left; - } - } - else - { - bounds.top = lprPosRect->top-lprClipRect->top; - bounds.bottom += bounds.top; - - lprPosRect->top = lprClipRect->top; - if( lprClipRect->bottom >= lprPosRect->bottom ) - { - // bottom side is not clipped out - } - else - { - // bottom side is clipped out - lprPosRect->bottom = lprClipRect->bottom; - } - } - *lprClipRect = *lprPosRect; - *lprPosRect = bounds; -}; - HRESULT VLCPlugin::onInit(void) { if( NULL == _p_libvlc ) { // initialize persistable properties - _bstr_mrl = NULL; _b_autoplay = TRUE; _b_autoloop = FALSE; + _bstr_baseurl = NULL; + _bstr_mrl = NULL; _b_visible = TRUE; _b_mute = FALSE; _i_volume = 50; @@ -493,12 +365,11 @@ HRESULT VLCPlugin::onInit(void) HRESULT VLCPlugin::onLoad(void) { - if( SysStringLen(_bstr_mrl) > 0 ) + if( SysStringLen(_bstr_baseurl) == 0 ) { /* - ** try to combine MRL with client site moniker, which for Internet Explorer - ** is the URL of the page the plugin is embedded into. Hence, if the MRL - ** is a relative URL, we should end up with an absolute URL + ** try to retreive the base URL using the client site moniker, which for Internet Explorer + ** is the URL of the page the plugin is embedded into. */ LPOLECLIENTSITE pClientSite; if( SUCCEEDED(vlcOleObject->GetClientSite(&pClientSite)) && (NULL != pClientSite) ) @@ -518,26 +389,13 @@ HRESULT VLCPlugin::onLoad(void) */ if( UrlIsW(base_url, URLIS_URL) ) { - DWORD len = INTERNET_MAX_URL_LENGTH; - LPOLESTR abs_url = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR)*len); - if( NULL != abs_url ) - { - if( SUCCEEDED(UrlCombineW(base_url, _bstr_mrl, abs_url, &len, - URL_ESCAPE_UNSAFE|URL_PLUGGABLE_PROTOCOL)) ) - { - SysFreeString(_bstr_mrl); - _bstr_mrl = SysAllocStringLen(abs_url, len); - } - CoTaskMemFree(abs_url); - } + /* copy base URL */ + _bstr_baseurl = SysAllocString(base_url); } CoTaskMemFree(base_url); } - pContMoniker->Release(); } - pBC->Release(); } - pClientSite->Release(); } } setDirty(FALSE); @@ -561,6 +419,8 @@ HRESULT VLCPlugin::getVLCObject(int* i_vlc) HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc) { + extern HMODULE DllGetModule(); + if( ! isRunning() ) { /* @@ -575,21 +435,26 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc) if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\VideoLAN\\VLC", 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) { - if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type, - (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS ) - { - if( i_type == REG_SZ ) - { - strcat( p_data, "\\vlc" ); - ppsz_argv[0] = p_data; - } - } - RegCloseKey( h_key ); + if( RegQueryValueEx( h_key, "InstallDir", 0, &i_type, + (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS ) + { + if( i_type == REG_SZ ) + { + strcat( p_data, "\\plugins" ); + ppsz_argv[ppsz_argc++] = "--plugin-path"; + ppsz_argv[ppsz_argc++] = p_data; + } + } + RegCloseKey( h_key ); } -#if 0 - ppsz_argv[0] = "C:\\cygwin\\home\\damienf\\vlc-trunk\\vlc"; -#endif + char p_path[MAX_PATH+1]; + DWORD len = GetModuleFileNameA(DllGetModule(), p_path, sizeof(p_path)); + if( len > 0 ) + { + p_path[len] = '\0'; + ppsz_argv[0] = p_path; + } // make sure plugin isn't affected with VLC single instance mode ppsz_argv[ppsz_argc++] = "--no-one-instance"; @@ -605,19 +470,6 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc) if( _b_autoloop ) ppsz_argv[ppsz_argc++] = "--loop"; - // initial volume setting - char volBuffer[16]; - ppsz_argv[ppsz_argc++] = "--volume"; - if( _b_mute ) - { - ppsz_argv[ppsz_argc++] = "0"; - } - else - { - snprintf(volBuffer, sizeof(volBuffer), "%d", _i_volume); - ppsz_argv[ppsz_argc++] = volBuffer; - } - if( IsDebuggerPresent() ) { /* @@ -639,27 +491,69 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc) return E_FAIL; } - char *psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl); - if( NULL != psz_mrl ) + // initial volume setting + libvlc_audio_set_volume(_p_libvlc, _i_volume, NULL); + if( _b_mute ) + { + libvlc_audio_set_mute(_p_libvlc, TRUE, NULL); + } + + // initial playlist item + if( SysStringLen(_bstr_mrl) > 0 ) { - const char *options[1]; - int i_options = 0; + char *psz_mrl = NULL; - char timeBuffer[32]; - if( _i_time ) + if( SysStringLen(_bstr_baseurl) > 0 ) + { + /* + ** if the MRL a relative URL, we should end up with an absolute URL + */ + LPWSTR abs_url = CombineURL(_bstr_baseurl, _bstr_mrl); + if( NULL != abs_url ) + { + psz_mrl = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url)); + CoTaskMemFree(abs_url); + } + else + { + psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl); + } + } + else + { + /* + ** baseURL is empty, assume MRL is absolute + */ + psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl); + } + if( NULL != psz_mrl ) { - snprintf(timeBuffer, sizeof(timeBuffer), ":start-time=%d", _i_time); - options[i_options++] = timeBuffer; + const char *options[1]; + int i_options = 0; + + char timeBuffer[32]; + if( _i_time ) + { + snprintf(timeBuffer, sizeof(timeBuffer), ":start-time=%d", _i_time); + options[i_options++] = timeBuffer; + } + // add default target to playlist + libvlc_playlist_add_extended(_p_libvlc, psz_mrl, NULL, i_options, options, NULL); + CoTaskMemFree(psz_mrl); } - // add default target to playlist - libvlc_playlist_add_extended(_p_libvlc, psz_mrl, NULL, i_options, options, NULL); - CoTaskMemFree(psz_mrl); } } *pp_libvlc = _p_libvlc; return S_OK; }; +void VLCPlugin::setErrorInfo(REFIID riid, const char *description) +{ + vlcSupportErrorInfo->setErrorInfo( getClassID() == CLSID_VLCPlugin2 ? + OLESTR("VideoLAN.VLCPlugin.2") : OLESTR("VideoLAN.VLCPlugin.1"), + riid, description ); +}; + HRESULT VLCPlugin::onAmbientChanged(LPUNKNOWN pContainer, DISPID dispID) { VARIANT v; @@ -750,6 +644,14 @@ HRESULT VLCPlugin::onClose(DWORD dwSaveOption) { libvlc_instance_t* p_libvlc = _p_libvlc; + IVLCLog *p_log; + if( SUCCEEDED(vlcControl2->get_log(&p_log)) ) + { + // make sure the log is disabled + p_log->put_verbosity(-1); + p_log->Release(); + } + _p_libvlc = NULL; vlcDataObject->onClose(); @@ -765,32 +667,26 @@ BOOL VLCPlugin::isInPlaceActive(void) HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprcPosRect, LPCRECT lprcClipRect) { - RECT posRect = *lprcPosRect; RECT clipRect = *lprcClipRect; /* ** record keeping of control geometry within container */ - _posRect = posRect; - - /* - ** convert posRect & clipRect to match control viewport coordinates - */ - getViewportCoords(&posRect, &clipRect); + _posRect = *lprcPosRect; /* ** Create a window for in place activated control. ** the window geometry matches the control viewport ** within container so that embedded video is always - ** properly clipped. + ** properly displayed. */ _inplacewnd = CreateWindow(_p_class->getInPlaceWndClassName(), "VLC Plugin In-Place Window", WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, - clipRect.left, - clipRect.top, - clipRect.right-clipRect.left, - clipRect.bottom-clipRect.top, + lprcPosRect->left, + lprcPosRect->top, + lprcPosRect->right-lprcPosRect->left, + lprcPosRect->bottom-lprcPosRect->top, hwndParent, 0, _p_class->getHInstance(), @@ -802,32 +698,11 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc SetWindowLongPtr(_inplacewnd, GWLP_USERDATA, reinterpret_cast(this)); - /* - ** VLC embedded video automatically grows to cover client - ** area of parent window. - ** hence create a such a 'parent' window whose geometry - ** is always correct relative to the viewport bounds - */ - _videownd = CreateWindow(_p_class->getVideoWndClassName(), - "VLC Plugin Video Window", - WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE, - posRect.left, - posRect.top, - posRect.right-posRect.left, - posRect.bottom-posRect.top, - _inplacewnd, - 0, - _p_class->getHInstance(), - NULL - ); - - if( NULL == _videownd ) - { - DestroyWindow(_inplacewnd); - return E_FAIL; - } + /* change cliprect coordinates system relative to window bounding rect */ + OffsetRect(&clipRect, -lprcPosRect->left, -lprcPosRect->top); - SetWindowLongPtr(_videownd, GWLP_USERDATA, reinterpret_cast(this)); + HRGN clipRgn = CreateRectRgnIndirect(&clipRect); + SetWindowRgn(_inplacewnd, clipRgn, TRUE); if( _b_usermode ) { @@ -839,13 +714,13 @@ HRESULT VLCPlugin::onActivateInPlace(LPMSG lpMesg, HWND hwndParent, LPCRECT lprc /* set internal video width and height */ libvlc_video_set_size(p_libvlc, - posRect.right-posRect.left, - posRect.bottom-posRect.top, + lprcPosRect->right-lprcPosRect->left, + lprcPosRect->bottom-lprcPosRect->top, NULL ); /* set internal video parent window */ libvlc_video_set_parent(p_libvlc, - reinterpret_cast(_videownd), NULL); + reinterpret_cast(_inplacewnd), NULL); if( _b_autoplay & (libvlc_playlist_items_count(p_libvlc, NULL) > 0) ) { @@ -868,11 +743,9 @@ HRESULT VLCPlugin::onInPlaceDeactivate(void) fireOnStopEvent(); } - DestroyWindow(_videownd); - _videownd = NULL; DestroyWindow(_inplacewnd); _inplacewnd = NULL; - + return S_OK; }; @@ -885,7 +758,7 @@ void VLCPlugin::setVisible(BOOL fVisible) { ShowWindow(_inplacewnd, fVisible ? SW_SHOW : SW_HIDE); if( fVisible ) - InvalidateRect(_videownd, NULL, TRUE); + InvalidateRect(_inplacewnd, NULL, TRUE); } setDirty(TRUE); firePropChangedEvent(DISPID_Visible); @@ -917,7 +790,7 @@ void VLCPlugin::setTime(int seconds) if( seconds != _i_time ) { - _i_time = seconds; + setStartTime(_i_time); if( isRunning() ) { libvlc_input_t *p_input = libvlc_playlist_get_input(_p_libvlc, NULL); @@ -927,7 +800,6 @@ void VLCPlugin::setTime(int seconds) libvlc_input_free(p_input); } } - setDirty(TRUE); } }; @@ -1053,52 +925,38 @@ void VLCPlugin::onPaint(HDC hdc, const RECT &bounds, const RECT &clipRect) void VLCPlugin::onPositionChange(LPCRECT lprcPosRect, LPCRECT lprcClipRect) { RECT clipRect = *lprcClipRect; - RECT posRect = *lprcPosRect; //RedrawWindow(GetParent(_inplacewnd), &_posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); /* ** record keeping of control geometry within container */ - _posRect = posRect; - - /* - ** convert posRect & clipRect to match control viewport coordinates - */ - getViewportCoords(&posRect, &clipRect); + _posRect = *lprcPosRect; /* ** change in-place window geometry to match clipping region */ SetWindowPos(_inplacewnd, NULL, - clipRect.left, - clipRect.top, - clipRect.right-clipRect.left, - clipRect.bottom-clipRect.top, + lprcPosRect->left, + lprcPosRect->top, + lprcPosRect->right-lprcPosRect->left, + lprcPosRect->bottom-lprcPosRect->top, SWP_NOACTIVATE| SWP_NOCOPYBITS| SWP_NOZORDER| SWP_NOOWNERZORDER ); - /* - ** change video window geometry to match object bounds within clipping region - */ - SetWindowPos(_videownd, NULL, - posRect.left, - posRect.top, - posRect.right-posRect.left, - posRect.bottom-posRect.top, - SWP_NOACTIVATE| - SWP_NOCOPYBITS| - SWP_NOZORDER| - SWP_NOOWNERZORDER ); + /* change cliprect coordinates system relative to window bounding rect */ + OffsetRect(&clipRect, -lprcPosRect->left, -lprcPosRect->top); + HRGN clipRgn = CreateRectRgnIndirect(&clipRect); + SetWindowRgn(_inplacewnd, clipRgn, FALSE); //RedrawWindow(_videownd, &posRect, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); if( isRunning() ) { libvlc_video_set_size(_p_libvlc, - posRect.right-posRect.left, - posRect.bottom-posRect.top, + lprcPosRect->right-lprcPosRect->left, + lprcPosRect->bottom-lprcPosRect->top, NULL ); } }; @@ -1130,4 +988,3 @@ void VLCPlugin::fireOnStopEvent(void) DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; vlcConnectionPointContainer->fireEvent(DISPID_StopEvent, &dispparamsNoArgs); }; -