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
;
123 LPTSTR lpszDriverName
;
124 LPTSTR lpszDeviceName
;
127 lpDevNames
= (LPDEVNAMES
) ptd
; // offset for size field
129 if (ptd
->tdExtDevmodeOffset
== 0)
135 lpDevMode
= (LPDEVMODE
) ((LPTSTR
)ptd
+ ptd
->tdExtDevmodeOffset
);
138 lpszDriverName
= (LPTSTR
) lpDevNames
+ ptd
->tdDriverNameOffset
;
139 lpszDeviceName
= (LPTSTR
) lpDevNames
+ ptd
->tdDeviceNameOffset
;
140 lpszPortName
= (LPTSTR
) lpDevNames
+ ptd
->tdPortNameOffset
;
142 hdc
= CreateDC(lpszDriverName
, lpszDeviceName
, lpszPortName
, lpDevMode
);
147 #define HIMETRIC_PER_INCH 2540
149 void DPFromHimetric(HDC hdc
, LPPOINT pt
, int count
)
151 LONG lpX
= GetDeviceCaps(hdc
, LOGPIXELSX
);
152 LONG lpY
= GetDeviceCaps(hdc
, LOGPIXELSY
);
155 pt
->x
= pt
->x
*lpX
/HIMETRIC_PER_INCH
;
156 pt
->y
= pt
->y
*lpY
/HIMETRIC_PER_INCH
;
161 void HimetricFromDP(HDC hdc
, LPPOINT pt
, int count
)
163 LONG lpX
= GetDeviceCaps(hdc
, LOGPIXELSX
);
164 LONG lpY
= GetDeviceCaps(hdc
, LOGPIXELSY
);
167 pt
->x
= pt
->x
*HIMETRIC_PER_INCH
/lpX
;
168 pt
->y
= pt
->y
*HIMETRIC_PER_INCH
/lpY
;
174 LPWSTR
CombineURL(LPCWSTR baseUrl
, LPCWSTR url
)
178 // check whether URL is already absolute
179 const wchar_t *end
=wcschr(url
, L
':');
180 if( (NULL
!= end
) && (end
!= url
) )
182 // validate protocol header
183 const wchar_t *start
= url
;
188 while( start
!= end
)
195 || (L
'/' == c
)) ) /* VLC uses / to allow user to specify a demuxer */
196 // not valid protocol header, assume relative URL
200 /* we have a protocol header, therefore URL is absolute */
201 UINT len
= wcslen(url
);
202 wchar_t *href
= (LPWSTR
)CoTaskMemAlloc((len
+1)*sizeof(wchar_t));
205 memcpy(href
, url
, len
*sizeof(wchar_t));
216 size_t baseLen
= wcslen(baseUrl
);
217 wchar_t *href
= (LPWSTR
)CoTaskMemAlloc((baseLen
+wcslen(url
)+1)*sizeof(wchar_t));
220 /* prepend base URL */
221 wcscpy(href
, baseUrl
);
224 ** relative url could be empty,
225 ** in which case return base URL
231 ** locate pathname part of base URL
234 /* skip over protocol part */
235 wchar_t *pathstart
= wcschr(href
, L
':');
239 if( L
'/' == *(++pathstart
) )
241 if( L
'/' == *(++pathstart
) )
246 /* skip over host part */
247 pathstart
= wcschr(pathstart
, L
'/');
248 pathend
= href
+baseLen
;
251 // no path, add a / past end of url (over '\0')
258 /* baseURL is just a UNIX file path */
261 /* baseURL is not an absolute path */
265 pathend
= href
+baseLen
;
268 /* relative URL made of an absolute path ? */
271 /* replace path completely */
272 wcscpy(pathstart
, url
);
276 /* find last path component and replace it */
277 while( L
'/' != *pathend
)
281 ** if relative url path starts with one or more './' or '../',
282 ** factor them out of href so that we return a
285 while( pathend
> pathstart
)
287 const wchar_t *p
= url
;
293 /* relative url is just '.' */
299 /* relative url starts with './' */
308 /* relative url is '..' */
314 /* relative url starts with '../' */
322 while( L
'/' != *pathend
);
324 /* skip over '/' separator */
326 /* concatenate remaining base URL and relative URL */
327 wcscpy(pathend
, url
);