1 /*****************************************************************************
2 * utils.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
29 ** conversion facilities
34 char *CStrFromWSTR(UINT codePage
, LPCWSTR wstr
, UINT len
)
38 size_t mblen
= WideCharToMultiByte(codePage
,
39 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
42 char *buffer
= (char *)CoTaskMemAlloc(mblen
+1);
43 ZeroMemory(buffer
, mblen
+1);
44 if( WideCharToMultiByte(codePage
, 0, wstr
, len
, buffer
, mblen
, NULL
, NULL
) )
54 char *CStrFromBSTR(UINT codePage
, BSTR bstr
)
56 return CStrFromWSTR(codePage
, bstr
, SysStringLen(bstr
));
59 BSTR
BSTRFromCStr(UINT codePage
, LPCSTR s
)
61 int wideLen
= MultiByteToWideChar(codePage
, 0, s
, -1, NULL
, 0);
64 WCHAR
* wideStr
= (WCHAR
*)CoTaskMemAlloc(wideLen
*sizeof(WCHAR
));
69 ZeroMemory(wideStr
, wideLen
*sizeof(WCHAR
));
70 MultiByteToWideChar(codePage
, 0, s
, -1, wideStr
, wideLen
);
71 bstr
= SysAllocStringLen(wideStr
, wideLen
-1);
72 CoTaskMemFree(wideStr
);
84 HRESULT
GetObjectProperty(LPUNKNOWN object
, DISPID dispID
, VARIANT
& v
)
87 HRESULT hr
= object
->QueryInterface(IID_IDispatch
, (LPVOID
*)&pDisp
);
90 DISPPARAMS dispparamsNoArgs
= {NULL
, NULL
, 0, 0};
93 hr
= pDisp
->Invoke(dispID
, IID_NULL
, LOCALE_USER_DEFAULT
,
94 DISPATCH_PROPERTYGET
, &dispparamsNoArgs
, &vres
, NULL
, NULL
);
97 if( V_VT(&v
) != V_VT(&vres
) )
99 hr
= VariantChangeType(&v
, &vres
, 0, V_VT(&v
));
112 HDC
CreateDevDC(DVTARGETDEVICE
*ptd
)
117 hdc
= CreateDC(TEXT("DISPLAY"), NULL
, NULL
, NULL
);
121 LPDEVNAMES lpDevNames
= (LPDEVNAMES
) ptd
; // offset for size field
122 LPDEVMODE lpDevMode
= NULL
;
124 if (ptd
->tdExtDevmodeOffset
!= 0)
125 lpDevMode
= (LPDEVMODE
) ((LPTSTR
)ptd
+ ptd
->tdExtDevmodeOffset
);
127 hdc
= CreateDC( (LPTSTR
) lpDevNames
+ ptd
->tdDriverNameOffset
,
128 (LPTSTR
) lpDevNames
+ ptd
->tdDeviceNameOffset
,
129 (LPTSTR
) lpDevNames
+ ptd
->tdPortNameOffset
,
135 #define HIMETRIC_PER_INCH 2540
137 void DPFromHimetric(HDC hdc
, LPPOINT pt
, int count
)
139 LONG lpX
= GetDeviceCaps(hdc
, LOGPIXELSX
);
140 LONG lpY
= GetDeviceCaps(hdc
, LOGPIXELSY
);
143 pt
->x
= pt
->x
*lpX
/HIMETRIC_PER_INCH
;
144 pt
->y
= pt
->y
*lpY
/HIMETRIC_PER_INCH
;
149 void HimetricFromDP(HDC hdc
, LPPOINT pt
, int count
)
151 LONG lpX
= GetDeviceCaps(hdc
, LOGPIXELSX
);
152 LONG lpY
= GetDeviceCaps(hdc
, LOGPIXELSY
);
155 pt
->x
= pt
->x
*HIMETRIC_PER_INCH
/lpX
;
156 pt
->y
= pt
->y
*HIMETRIC_PER_INCH
/lpY
;
162 LPWSTR
CombineURL(LPCWSTR baseUrl
, LPCWSTR url
)
166 // check whether URL is already absolute
167 const wchar_t *end
=wcschr(url
, L
':');
168 if( (NULL
!= end
) && (end
!= url
) )
170 // validate protocol header
171 const wchar_t *start
= url
;
176 while( start
!= end
)
183 || (L
'/' == c
)) ) /* VLC uses / to allow user to specify a demuxer */
184 // not valid protocol header, assume relative URL
188 /* we have a protocol header, therefore URL is absolute */
189 UINT len
= wcslen(url
);
190 wchar_t *href
= (LPWSTR
)CoTaskMemAlloc((len
+1)*sizeof(wchar_t));
193 memcpy(href
, url
, len
*sizeof(wchar_t));
204 size_t baseLen
= wcslen(baseUrl
);
205 wchar_t *href
= (LPWSTR
)CoTaskMemAlloc((baseLen
+wcslen(url
)+1)*sizeof(wchar_t));
208 /* prepend base URL */
209 wcscpy(href
, baseUrl
);
212 ** relative url could be empty,
213 ** in which case return base URL
219 ** locate pathname part of base URL
222 /* skip over protocol part */
223 wchar_t *pathstart
= wcschr(href
, L
':');
227 if( L
'/' == *(++pathstart
) )
229 if( L
'/' == *(++pathstart
) )
234 /* skip over host part */
235 pathstart
= wcschr(pathstart
, L
'/');
236 pathend
= href
+baseLen
;
239 // no path, add a / past end of url (over '\0')
246 /* baseURL is just a UNIX file path */
249 /* baseURL is not an absolute path */
253 pathend
= href
+baseLen
;
256 /* relative URL made of an absolute path ? */
259 /* replace path completely */
260 wcscpy(pathstart
, url
);
264 /* find last path component and replace it */
265 while( L
'/' != *pathend
)
269 ** if relative url path starts with one or more './' or '../',
270 ** factor them out of href so that we return a
273 while( pathend
> pathstart
)
275 const wchar_t *p
= url
;
281 /* relative url is just '.' */
287 /* relative url starts with './' */
296 /* relative url is '..' */
302 /* relative url starts with '../' */
310 while( L
'/' != *pathend
);
312 /* skip over '/' separator */
314 /* concatenate remaining base URL and relative URL */
315 wcscpy(pathend
, url
);