X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=activex%2Futils.cpp;h=8750aa1ce2e6749e3e3b9492829a4d2dd58b975f;hb=d248d3f2f9a3ca4b8b9508c84ee96d07c362c82b;hp=ec37b05410fef3b9fa589254e22c15c9c3e5affb;hpb=1b75d79ed2680352f5ed1f67d57e9c205dd73162;p=vlc diff --git a/activex/utils.cpp b/activex/utils.cpp index ec37b05410..8750aa1ce2 100644 --- a/activex/utils.cpp +++ b/activex/utils.cpp @@ -1,7 +1,7 @@ /***************************************************************************** * utils.cpp: ActiveX control for VLC ***************************************************************************** - * Copyright (C) 2005 VideoLAN + * Copyright (C) 2005 the VideoLAN team * * Authors: Damien Fouilleul * @@ -17,49 +17,59 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #include "utils.h" +#include +#include + /* ** conversion facilities */ using namespace std; -char *CStrFromBSTR(int codePage, BSTR bstr) +char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len) { - UINT len = SysStringLen(bstr); if( len > 0 ) { size_t mblen = WideCharToMultiByte(codePage, - 0, bstr, len, NULL, 0, NULL, NULL); + 0, wstr, len, NULL, 0, NULL, NULL); if( mblen > 0 ) { - char *buffer = (char *)malloc(mblen+1); + char *buffer = (char *)CoTaskMemAlloc(mblen+1); ZeroMemory(buffer, mblen+1); - if( WideCharToMultiByte(codePage, 0, bstr, len, buffer, mblen, NULL, NULL) ) + if( WideCharToMultiByte(codePage, 0, wstr, len, buffer, mblen, NULL, NULL) ) + { + buffer[mblen] = '\0'; return buffer; + } } } return NULL; }; -BSTR BSTRFromCStr(int codePage, const char *s) +char *CStrFromBSTR(UINT codePage, BSTR bstr) +{ + return CStrFromWSTR(codePage, bstr, SysStringLen(bstr)); +}; + +BSTR BSTRFromCStr(UINT codePage, LPCSTR s) { int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0); - if( wideLen ) + if( wideLen > 0 ) { - WCHAR* wideStr = (WCHAR*)malloc(wideLen*sizeof(WCHAR)); + WCHAR* wideStr = (WCHAR*)CoTaskMemAlloc(wideLen*sizeof(WCHAR)); if( NULL != wideStr ) { BSTR bstr; ZeroMemory(wideStr, wideLen*sizeof(WCHAR)); MultiByteToWideChar(codePage, 0, s, -1, wideStr, wideLen); - bstr = SysAllocString(wideStr); - free(wideStr); + bstr = SysAllocStringLen(wideStr, wideLen-1); + CoTaskMemFree(wideStr); return bstr; } @@ -79,6 +89,7 @@ HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v) { DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; VARIANT vres; + VariantInit(&vres); hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &vres, NULL, NULL); if( SUCCEEDED(hr) ) @@ -100,34 +111,214 @@ HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v) HDC CreateDevDC(DVTARGETDEVICE *ptd) { - HDC hdc=NULL; - LPDEVNAMES lpDevNames; - LPDEVMODE lpDevMode; - LPTSTR lpszDriverName; - LPTSTR lpszDeviceName; - LPTSTR lpszPortName; - - if (ptd == NULL) { - hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); - goto errReturn; - } - - lpDevNames = (LPDEVNAMES) ptd; // offset for size field - - if (ptd->tdExtDevmodeOffset == 0) { - lpDevMode = NULL; - }else{ - lpDevMode = (LPDEVMODE) ((LPTSTR)ptd + ptd->tdExtDevmodeOffset); - } - - lpszDriverName = (LPTSTR) lpDevNames + ptd->tdDriverNameOffset; - lpszDeviceName = (LPTSTR) lpDevNames + ptd->tdDeviceNameOffset; - lpszPortName = (LPTSTR) lpDevNames + ptd->tdPortNameOffset; - - hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode); - -errReturn: - return hdc; + HDC hdc=NULL; + if( NULL == ptd ) + { + hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + } + else + { + LPDEVNAMES lpDevNames; + LPDEVMODE lpDevMode; + LPTSTR lpszDriverName; + LPTSTR lpszDeviceName; + LPTSTR lpszPortName; + + lpDevNames = (LPDEVNAMES) ptd; // offset for size field + + if (ptd->tdExtDevmodeOffset == 0) + { + lpDevMode = NULL; + } + else + { + lpDevMode = (LPDEVMODE) ((LPTSTR)ptd + ptd->tdExtDevmodeOffset); + } + + lpszDriverName = (LPTSTR) lpDevNames + ptd->tdDriverNameOffset; + lpszDeviceName = (LPTSTR) lpDevNames + ptd->tdDeviceNameOffset; + lpszPortName = (LPTSTR) lpDevNames + ptd->tdPortNameOffset; + + hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode); + } + return hdc; +}; + +#define HIMETRIC_PER_INCH 2540 + +void DPFromHimetric(HDC hdc, LPPOINT pt, int count) +{ + LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX); + LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY); + while( count-- ) + { + pt->x = pt->x*lpX/HIMETRIC_PER_INCH; + pt->y = pt->y*lpY/HIMETRIC_PER_INCH; + ++pt; + } }; +void HimetricFromDP(HDC hdc, LPPOINT pt, int count) +{ + LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX); + LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY); + while( count-- ) + { + pt->x = pt->x*HIMETRIC_PER_INCH/lpX; + pt->y = pt->y*HIMETRIC_PER_INCH/lpY; + ++pt; + } +}; + + +LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url) +{ + if( NULL != url ) + { + // check whether URL is already absolute + const wchar_t *end=wcschr(url, L':'); + if( (NULL != end) && (end != url) ) + { + // validate protocol header + const wchar_t *start = url; + while( start != end ) { + wchar_t c = towlower(*start); + if( (c < L'a') || (c > L'z') ) + // not a valid protocol header, assume relative URL + goto relativeurl; + ++start; + } + /* we have a protocol header, therefore URL is absolute */ + UINT len = wcslen(url); + wchar_t *href = (LPWSTR)CoTaskMemAlloc((len+1)*sizeof(wchar_t)); + if( href ) + { + memcpy(href, url, len*sizeof(wchar_t)); + href[len] = L'\0'; + } + return href; + } + +relativeurl: + + if( baseUrl ) + { + size_t baseLen = wcslen(baseUrl); + wchar_t *href = (LPWSTR)CoTaskMemAlloc((baseLen+wcslen(url)+1)*sizeof(wchar_t)); + if( href ) + { + /* prepend base URL */ + wcscpy(href, baseUrl); + + /* + ** relative url could be empty, + ** in which case return base URL + */ + if( L'\0' == *url ) + return href; + + /* + ** locate pathname part of base URL + */ + + /* skip over protocol part */ + wchar_t *pathstart = wcschr(href, L':'); + wchar_t *pathend; + if( pathstart ) + { + if( L'/' == *(++pathstart) ) + { + if( L'/' == *(++pathstart) ) + { + ++pathstart; + } + } + /* skip over host part */ + pathstart = wcschr(pathstart, L'/'); + pathend = href+baseLen; + if( ! pathstart ) + { + // no path, add a / past end of url (over '\0') + pathstart = pathend; + *pathstart = L'/'; + } + } + else + { + /* baseURL is just a UNIX file path */ + if( L'/' != *href ) + { + /* baseURL is not an absolute path */ + return NULL; + } + pathstart = href; + pathend = href+baseLen; + } + + /* relative URL made of an absolute path ? */ + if( L'/' == *url ) + { + /* replace path completely */ + wcscpy(pathstart, url); + return href; + } + + /* find last path component and replace it */ + while( L'/' != *pathend ) + --pathend; + + /* + ** if relative url path starts with one or more './' or '../', + ** factor them out of href so that we return a + ** normalized URL + */ + while( pathend > pathstart ) + { + const wchar_t *p = url; + if( L'.' != *p ) + break; + ++p; + if( L'\0' == *p ) + { + /* relative url is just '.' */ + url = p; + break; + } + if( L'/' == *p ) + { + /* relative url starts with './' */ + url = ++p; + continue; + } + if( L'.' != *p ) + break; + ++p; + if( L'\0' == *p ) + { + /* relative url is '..' */ + } + else + { + if( L'/' != *p ) + break; + /* relative url starts with '../' */ + ++p; + } + url = p; + do + { + --pathend; + } + while( L'/' != *pathend ); + } + /* skip over '/' separator */ + ++pathend; + /* concatenate remaining base URL and relative URL */ + wcscpy(pathend, url); + } + return href; + } + } + return NULL; +}