xref: /AOO41X/main/dtrans/source/win32/misc/ImplHelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir //------------------------------------------------------------------------
33*cdf0e10cSrcweir // includes
34*cdf0e10cSrcweir //------------------------------------------------------------------------
35*cdf0e10cSrcweir #include <osl/diagnose.h>
36*cdf0e10cSrcweir #include "ImplHelper.hxx"
37*cdf0e10cSrcweir #include <rtl/tencinfo.h>
38*cdf0e10cSrcweir #include <rtl/memory.h>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #include <memory>
41*cdf0e10cSrcweir #if defined _MSC_VER
42*cdf0e10cSrcweir #pragma warning(push,1)
43*cdf0e10cSrcweir #endif
44*cdf0e10cSrcweir #include <windows.h>
45*cdf0e10cSrcweir #if defined _MSC_VER
46*cdf0e10cSrcweir #pragma warning(pop)
47*cdf0e10cSrcweir #endif
48*cdf0e10cSrcweir #ifdef __MINGW32__
49*cdf0e10cSrcweir #include <excpt.h>
50*cdf0e10cSrcweir #endif
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir //------------------------------------------------------------------------
53*cdf0e10cSrcweir // defines
54*cdf0e10cSrcweir //------------------------------------------------------------------------
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir #define FORMATETC_EXACT_MATCH    1
57*cdf0e10cSrcweir #define FORMATETC_PARTIAL_MATCH -1
58*cdf0e10cSrcweir #define FORMATETC_NO_MATCH       0
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir //------------------------------------------------------------------------
61*cdf0e10cSrcweir // namespace directives
62*cdf0e10cSrcweir //------------------------------------------------------------------------
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir using ::rtl::OUString;
65*cdf0e10cSrcweir using ::rtl::OString;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir //------------------------------------------------------------------------
68*cdf0e10cSrcweir // returns a windows codepage appropriate to the
69*cdf0e10cSrcweir // given mime charset parameter value
70*cdf0e10cSrcweir //------------------------------------------------------------------------
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset )
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir 	sal_uInt32 winCP = GetACP( );
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir 	if ( charset.getLength( ) )
77*cdf0e10cSrcweir 	{
78*cdf0e10cSrcweir 		OString osCharset(
79*cdf0e10cSrcweir 			charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US );
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 		rtl_TextEncoding txtEnc =
82*cdf0e10cSrcweir 			rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) );
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 		sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc );
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 		CHARSETINFO chrsInf;
87*cdf0e10cSrcweir 		sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ?
88*cdf0e10cSrcweir                         sal_True : sal_False;
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir 		// if one of the above functions fails
91*cdf0e10cSrcweir 		// we will return the current ANSI codepage
92*cdf0e10cSrcweir 		// of this thread
93*cdf0e10cSrcweir 		if ( bRet )
94*cdf0e10cSrcweir 			winCP = chrsInf.ciACP;
95*cdf0e10cSrcweir 	}
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	return winCP;
98*cdf0e10cSrcweir }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir //--------------------------------------------------
101*cdf0e10cSrcweir // returns a windows codepage appropriate to the
102*cdf0e10cSrcweir // given locale and locale type
103*cdf0e10cSrcweir //--------------------------------------------------
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype )
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir 	OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) );
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 	// we set an default value
110*cdf0e10cSrcweir 	OUString winCP;
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir 	// set an default value
113*cdf0e10cSrcweir 	if ( LOCALE_IDEFAULTCODEPAGE == lctype )
114*cdf0e10cSrcweir 	{
115*cdf0e10cSrcweir 		winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 );
116*cdf0e10cSrcweir 	}
117*cdf0e10cSrcweir 	else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype )
118*cdf0e10cSrcweir 	{
119*cdf0e10cSrcweir 		winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 );
120*cdf0e10cSrcweir 	}
121*cdf0e10cSrcweir 	else
122*cdf0e10cSrcweir 		OSL_ASSERT( sal_False );
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 	// we use the GetLocaleInfoA because don't want to provide
125*cdf0e10cSrcweir 	// a unicode wrapper function for Win9x in sal/systools
126*cdf0e10cSrcweir 	char buff[6];
127*cdf0e10cSrcweir 	sal_Int32 nResult = GetLocaleInfoA(
128*cdf0e10cSrcweir 		lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) );
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 	OSL_ASSERT( nResult );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 	if ( nResult )
133*cdf0e10cSrcweir 	{
134*cdf0e10cSrcweir 		sal_Int32 len = MultiByteToWideChar(
135*cdf0e10cSrcweir 			CP_ACP, 0, buff, -1, NULL, 0 );
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 		OSL_ASSERT( len > 0 );
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 		std::auto_ptr< sal_Unicode > lpwchBuff( new sal_Unicode[len] );
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 		if ( NULL != lpwchBuff.get( ) )
142*cdf0e10cSrcweir 		{
143*cdf0e10cSrcweir 			len = MultiByteToWideChar(
144*cdf0e10cSrcweir 				CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(lpwchBuff.get( )), len );
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 			winCP = OUString( lpwchBuff.get( ), (len - 1) );
147*cdf0e10cSrcweir 		}
148*cdf0e10cSrcweir 	}
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 	return winCP;
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir //--------------------------------------------------
154*cdf0e10cSrcweir // returns a mime charset parameter value appropriate
155*cdf0e10cSrcweir // to the given codepage, optional a prefix can be
156*cdf0e10cSrcweir // given, e.g. "windows-" or "cp"
157*cdf0e10cSrcweir //--------------------------------------------------
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix )
160*cdf0e10cSrcweir {
161*cdf0e10cSrcweir 	return aPrefix + cptostr( cp );
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir //--------------------------------------------------
165*cdf0e10cSrcweir // returns a mime charset parameter value appropriate
166*cdf0e10cSrcweir // to the given locale id and locale type, optional a
167*cdf0e10cSrcweir // prefix can be given, e.g. "windows-" or "cp"
168*cdf0e10cSrcweir //--------------------------------------------------
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix  )
171*cdf0e10cSrcweir {
172*cdf0e10cSrcweir 	OUString charset = getWinCPFromLocaleId( lcid, lctype );
173*cdf0e10cSrcweir 	return aPrefix + charset;
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir //------------------------------------------------------------------------
177*cdf0e10cSrcweir // IsOEMCP
178*cdf0e10cSrcweir //------------------------------------------------------------------------
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage )
181*cdf0e10cSrcweir {
182*cdf0e10cSrcweir 	OSL_ASSERT( IsValidCodePage( codepage ) );
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir 	sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737,
185*cdf0e10cSrcweir 							  775, 850, 852, 855, 857, 860,
186*cdf0e10cSrcweir 						      861, 862, 863, 864, 865, 866,
187*cdf0e10cSrcweir 						      869, 874, 932, 936, 949, 950, 1361 };
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 	for ( sal_Int8 i = 0; i < ( sizeof( arrOEMCP )/sizeof( sal_uInt32 ) ); ++i )
190*cdf0e10cSrcweir 		if ( arrOEMCP[i] == codepage )
191*cdf0e10cSrcweir 			return sal_True;
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 	return sal_False;
194*cdf0e10cSrcweir }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir //------------------------------------------------------------------------
197*cdf0e10cSrcweir // converts a codepage into its string representation
198*cdf0e10cSrcweir //------------------------------------------------------------------------
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir OUString SAL_CALL cptostr( sal_uInt32 codepage )
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 	OSL_ASSERT( IsValidCodePage( codepage ) );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 	return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 );
205*cdf0e10cSrcweir }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir //-------------------------------------------------------------------------
208*cdf0e10cSrcweir // OleStdDeleteTargetDevice()
209*cdf0e10cSrcweir //
210*cdf0e10cSrcweir // Purpose:
211*cdf0e10cSrcweir //
212*cdf0e10cSrcweir // Parameters:
213*cdf0e10cSrcweir //
214*cdf0e10cSrcweir // Return Value:
215*cdf0e10cSrcweir //    SCODE  -  S_OK if successful
216*cdf0e10cSrcweir //-------------------------------------------------------------------------
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir #ifdef __MINGW32__
221*cdf0e10cSrcweir 	jmp_buf jmpbuf;
222*cdf0e10cSrcweir 	__SEHandler han;
223*cdf0e10cSrcweir 	if (__builtin_setjmp(jmpbuf) == 0)
224*cdf0e10cSrcweir 	{
225*cdf0e10cSrcweir 		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
226*cdf0e10cSrcweir #else
227*cdf0e10cSrcweir 	__try
228*cdf0e10cSrcweir 	{
229*cdf0e10cSrcweir #endif
230*cdf0e10cSrcweir 		CoTaskMemFree( ptd );
231*cdf0e10cSrcweir 	}
232*cdf0e10cSrcweir #ifdef __MINGW32__
233*cdf0e10cSrcweir 	else
234*cdf0e10cSrcweir #else
235*cdf0e10cSrcweir 	__except( EXCEPTION_EXECUTE_HANDLER )
236*cdf0e10cSrcweir #endif
237*cdf0e10cSrcweir 	{
238*cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Error DeleteTargetDevice" );
239*cdf0e10cSrcweir 	}
240*cdf0e10cSrcweir #ifdef __MINGW32__
241*cdf0e10cSrcweir 	han.Reset();
242*cdf0e10cSrcweir #endif
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir //-------------------------------------------------------------------------
248*cdf0e10cSrcweir // OleStdCopyTargetDevice()
249*cdf0e10cSrcweir //
250*cdf0e10cSrcweir // Purpose:
251*cdf0e10cSrcweir //  duplicate a TARGETDEVICE struct. this function allocates memory for
252*cdf0e10cSrcweir //  the copy. the caller MUST free the allocated copy when done with it
253*cdf0e10cSrcweir //  using the standard allocator returned from CoGetMalloc.
254*cdf0e10cSrcweir //  (OleStdFree can be used to free the copy).
255*cdf0e10cSrcweir //
256*cdf0e10cSrcweir // Parameters:
257*cdf0e10cSrcweir //  ptdSrc      pointer to source TARGETDEVICE
258*cdf0e10cSrcweir //
259*cdf0e10cSrcweir // Return Value:
260*cdf0e10cSrcweir //    pointer to allocated copy of ptdSrc
261*cdf0e10cSrcweir //    if ptdSrc==NULL then retuns NULL is returned.
262*cdf0e10cSrcweir //    if ptdSrc!=NULL and memory allocation fails, then NULL is returned
263*cdf0e10cSrcweir //-------------------------------------------------------------------------
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc )
266*cdf0e10cSrcweir {
267*cdf0e10cSrcweir 	DVTARGETDEVICE* ptdDest = NULL;
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir #ifdef __MINGW32__
270*cdf0e10cSrcweir 	jmp_buf jmpbuf;
271*cdf0e10cSrcweir 	__SEHandler han;
272*cdf0e10cSrcweir 	if (__builtin_setjmp(jmpbuf) == 0)
273*cdf0e10cSrcweir 	{
274*cdf0e10cSrcweir 		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
275*cdf0e10cSrcweir #else
276*cdf0e10cSrcweir 	__try
277*cdf0e10cSrcweir 	{
278*cdf0e10cSrcweir #endif
279*cdf0e10cSrcweir 		if ( NULL != ptdSrc )
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 			ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) );
282*cdf0e10cSrcweir 			rtl_copyMemory( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) );
283*cdf0e10cSrcweir 		}
284*cdf0e10cSrcweir 	}
285*cdf0e10cSrcweir #ifdef __MINGW32__
286*cdf0e10cSrcweir 	han.Reset();
287*cdf0e10cSrcweir #else
288*cdf0e10cSrcweir 	__except( EXCEPTION_EXECUTE_HANDLER )
289*cdf0e10cSrcweir 	{
290*cdf0e10cSrcweir 	}
291*cdf0e10cSrcweir #endif
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 	return ptdDest;
294*cdf0e10cSrcweir }
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir //-------------------------------------------------------------------------
298*cdf0e10cSrcweir // OleStdCopyFormatEtc()
299*cdf0e10cSrcweir //
300*cdf0e10cSrcweir // Purpose:
301*cdf0e10cSrcweir //  Copies the contents of a FORMATETC structure. this function takes
302*cdf0e10cSrcweir //  special care to copy correctly copying the pointer to the TARGETDEVICE
303*cdf0e10cSrcweir //  contained within the source FORMATETC structure.
304*cdf0e10cSrcweir //  if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
305*cdf0e10cSrcweir //  of the TARGETDEVICE will be allocated for the destination of the
306*cdf0e10cSrcweir //  FORMATETC (petcDest).
307*cdf0e10cSrcweir //
308*cdf0e10cSrcweir //  NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
309*cdf0e10cSrcweir //  within the destination FORMATETC when done with it
310*cdf0e10cSrcweir //  using the standard allocator returned from CoGetMalloc.
311*cdf0e10cSrcweir //  (OleStdFree can be used to free the copy).
312*cdf0e10cSrcweir //
313*cdf0e10cSrcweir // Parameters:
314*cdf0e10cSrcweir //  petcDest      pointer to destination FORMATETC
315*cdf0e10cSrcweir //  petcSrc       pointer to source FORMATETC
316*cdf0e10cSrcweir //
317*cdf0e10cSrcweir // Return Value:
318*cdf0e10cSrcweir //  returns TRUE if copy was successful;
319*cdf0e10cSrcweir //	retuns FALSE if not successful, e.g. one or both of the pointers
320*cdf0e10cSrcweir //	were invalid or the pointers were equal
321*cdf0e10cSrcweir //-------------------------------------------------------------------------
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc )
324*cdf0e10cSrcweir {
325*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir #ifdef __MINGW32__
328*cdf0e10cSrcweir 	jmp_buf jmpbuf;
329*cdf0e10cSrcweir 	__SEHandler han;
330*cdf0e10cSrcweir 	if (__builtin_setjmp(jmpbuf) == 0)
331*cdf0e10cSrcweir 	{
332*cdf0e10cSrcweir 		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
333*cdf0e10cSrcweir #else
334*cdf0e10cSrcweir 	__try
335*cdf0e10cSrcweir 	{
336*cdf0e10cSrcweir #endif
337*cdf0e10cSrcweir 		if ( petcDest != petcSrc )
338*cdf0e10cSrcweir 		{
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 		petcDest->cfFormat = petcSrc->cfFormat;
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir 		petcDest->ptd      = NULL;
343*cdf0e10cSrcweir 		if ( NULL != petcSrc->ptd )
344*cdf0e10cSrcweir 			petcDest->ptd  = CopyTargetDevice(petcSrc->ptd);
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir 		petcDest->dwAspect = petcSrc->dwAspect;
347*cdf0e10cSrcweir 		petcDest->lindex   = petcSrc->lindex;
348*cdf0e10cSrcweir 		petcDest->tymed    = petcSrc->tymed;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 		bRet = sal_True;
351*cdf0e10cSrcweir 		}
352*cdf0e10cSrcweir 	}
353*cdf0e10cSrcweir #ifdef __MINGW32__
354*cdf0e10cSrcweir 	else
355*cdf0e10cSrcweir #else
356*cdf0e10cSrcweir 	__except( EXCEPTION_EXECUTE_HANDLER )
357*cdf0e10cSrcweir #endif
358*cdf0e10cSrcweir 	{
359*cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Error CopyFormatEtc" );
360*cdf0e10cSrcweir 	}
361*cdf0e10cSrcweir #ifdef __MINGW32__
362*cdf0e10cSrcweir 	han.Reset();
363*cdf0e10cSrcweir #endif
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 	return bRet;
366*cdf0e10cSrcweir }
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir //-------------------------------------------------------------------------
369*cdf0e10cSrcweir // returns:
370*cdf0e10cSrcweir //  1 for exact match,
371*cdf0e10cSrcweir //  0 for no match,
372*cdf0e10cSrcweir // -1 for partial match (which is defined to mean the left is a subset
373*cdf0e10cSrcweir //    of the right: fewer aspects, null target device, fewer medium).
374*cdf0e10cSrcweir //-------------------------------------------------------------------------
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs )
377*cdf0e10cSrcweir {
378*cdf0e10cSrcweir 	sal_Int32 nMatch = FORMATETC_EXACT_MATCH;
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir #ifdef __MINGW32__
381*cdf0e10cSrcweir 	jmp_buf jmpbuf;
382*cdf0e10cSrcweir 	__SEHandler han;
383*cdf0e10cSrcweir 	if (__builtin_setjmp(jmpbuf) == 0)
384*cdf0e10cSrcweir 	{
385*cdf0e10cSrcweir 		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
386*cdf0e10cSrcweir #else
387*cdf0e10cSrcweir 	__try
388*cdf0e10cSrcweir 	{
389*cdf0e10cSrcweir #endif
390*cdf0e10cSrcweir 		if ( pFetcLhs != pFetcRhs )
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir 		if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) ||
393*cdf0e10cSrcweir 			 ( pFetcLhs->lindex   != pFetcRhs->lindex ) ||
394*cdf0e10cSrcweir 			 !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) )
395*cdf0e10cSrcweir 		{
396*cdf0e10cSrcweir 			nMatch = FORMATETC_NO_MATCH;
397*cdf0e10cSrcweir 		}
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir 		else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect )
400*cdf0e10cSrcweir 			// same aspects; equal
401*cdf0e10cSrcweir 			;
402*cdf0e10cSrcweir 		else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 )
403*cdf0e10cSrcweir 		{
404*cdf0e10cSrcweir 			// left not subset of aspects of right; not equal
405*cdf0e10cSrcweir 			nMatch = FORMATETC_NO_MATCH;
406*cdf0e10cSrcweir 		}
407*cdf0e10cSrcweir 		else
408*cdf0e10cSrcweir 			// left subset of right
409*cdf0e10cSrcweir 			nMatch = FORMATETC_PARTIAL_MATCH;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 		if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH )
412*cdf0e10cSrcweir 		{
413*cdf0e10cSrcweir 		if ( pFetcLhs->tymed == pFetcRhs->tymed )
414*cdf0e10cSrcweir 			// same medium flags; equal
415*cdf0e10cSrcweir 			;
416*cdf0e10cSrcweir 		else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 )
417*cdf0e10cSrcweir 		{
418*cdf0e10cSrcweir 			// left not subset of medium flags of right; not equal
419*cdf0e10cSrcweir 			nMatch = FORMATETC_NO_MATCH;
420*cdf0e10cSrcweir 		}
421*cdf0e10cSrcweir 		else
422*cdf0e10cSrcweir 			// left subset of right
423*cdf0e10cSrcweir 			nMatch = FORMATETC_PARTIAL_MATCH;
424*cdf0e10cSrcweir 		}
425*cdf0e10cSrcweir 	}
426*cdf0e10cSrcweir #ifdef __MINGW32__
427*cdf0e10cSrcweir 	else
428*cdf0e10cSrcweir #else
429*cdf0e10cSrcweir 	__except( EXCEPTION_EXECUTE_HANDLER )
430*cdf0e10cSrcweir #endif
431*cdf0e10cSrcweir 	{
432*cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Error CompareFormatEtc" );
433*cdf0e10cSrcweir 		nMatch = FORMATETC_NO_MATCH;
434*cdf0e10cSrcweir 	}
435*cdf0e10cSrcweir #ifdef __MINGW32__
436*cdf0e10cSrcweir 	han.Reset();
437*cdf0e10cSrcweir #endif
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir     return nMatch;
440*cdf0e10cSrcweir }
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir //-------------------------------------------------------------------------
444*cdf0e10cSrcweir //
445*cdf0e10cSrcweir //-------------------------------------------------------------------------
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight )
448*cdf0e10cSrcweir {
449*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir #ifdef __MINGW32__
452*cdf0e10cSrcweir 	jmp_buf jmpbuf;
453*cdf0e10cSrcweir 	__SEHandler han;
454*cdf0e10cSrcweir 	if (__builtin_setjmp(jmpbuf) == 0)
455*cdf0e10cSrcweir 	{
456*cdf0e10cSrcweir 		han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
457*cdf0e10cSrcweir #else
458*cdf0e10cSrcweir 	__try
459*cdf0e10cSrcweir 	{
460*cdf0e10cSrcweir #endif
461*cdf0e10cSrcweir 		if ( ptdLeft == ptdRight )
462*cdf0e10cSrcweir 		{
463*cdf0e10cSrcweir 			// same address of td; must be same (handles NULL case)
464*cdf0e10cSrcweir 			bRet = sal_True;
465*cdf0e10cSrcweir 		}
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir 		// one ot the two is NULL
468*cdf0e10cSrcweir 		else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) )
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir 		if ( ptdLeft->tdSize == ptdRight->tdSize )
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir 		if ( rtl_compareMemory( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 )
473*cdf0e10cSrcweir 			bRet = sal_True;
474*cdf0e10cSrcweir 	}
475*cdf0e10cSrcweir #ifdef __MINGW32__
476*cdf0e10cSrcweir 	else
477*cdf0e10cSrcweir #else
478*cdf0e10cSrcweir 	__except( EXCEPTION_EXECUTE_HANDLER )
479*cdf0e10cSrcweir #endif
480*cdf0e10cSrcweir 	{
481*cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Error CompareTargetDevice" );
482*cdf0e10cSrcweir 		bRet = sal_False;
483*cdf0e10cSrcweir 	}
484*cdf0e10cSrcweir #ifdef __MINGW32__
485*cdf0e10cSrcweir 	han.Reset();
486*cdf0e10cSrcweir #endif
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir     return bRet;
489*cdf0e10cSrcweir }
490