1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/diagnose.h>
21 #include "ImplHelper.hxx"
22 #include <rtl/tencinfo.h>
27 #pragma warning(push,1)
36 #if defined ( __MINGW32__ )
37 #include <sehandler.hxx>
40 #define FORMATETC_EXACT_MATCH 1
41 #define FORMATETC_PARTIAL_MATCH -1
42 #define FORMATETC_NO_MATCH 0
44 // namespace directives
46 // returns a windows codepage appropriate to the
47 // given mime charset parameter value
49 sal_uInt32 SAL_CALL
getWinCPFromMimeCharset( const OUString
& charset
)
51 sal_uInt32 winCP
= GetACP( );
53 if ( charset
.getLength( ) )
56 charset
.getStr( ), charset
.getLength( ), RTL_TEXTENCODING_ASCII_US
);
58 rtl_TextEncoding txtEnc
=
59 rtl_getTextEncodingFromMimeCharset( osCharset
.getStr( ) );
61 sal_uIntPtr winChrs
= rtl_getBestWindowsCharsetFromTextEncoding( txtEnc
);
64 sal_Bool bRet
= TranslateCharsetInfo( (DWORD
*)winChrs
, &chrsInf
, TCI_SRCCHARSET
) ?
67 // if one of the above functions fails
68 // we will return the current ANSI codepage
71 winCP
= chrsInf
.ciACP
;
77 // returns a windows codepage appropriate to the
78 // given locale and locale type
80 OUString SAL_CALL
getWinCPFromLocaleId( LCID lcid
, LCTYPE lctype
)
82 OSL_ASSERT( IsValidLocale( lcid
, LCID_SUPPORTED
) );
84 // we set an default value
87 // set an default value
88 if ( LOCALE_IDEFAULTCODEPAGE
== lctype
)
90 winCP
= OUString::number( static_cast<sal_Int32
>(GetOEMCP( )) );
92 else if ( LOCALE_IDEFAULTANSICODEPAGE
== lctype
)
94 winCP
= OUString::number( static_cast<sal_Int32
>(GetACP( )) );
97 OSL_ASSERT( sal_False
);
99 // we use the GetLocaleInfoA because don't want to provide
100 // a unicode wrapper function for Win9x in sal/systools
102 sal_Int32 nResult
= GetLocaleInfoA(
103 lcid
, lctype
| LOCALE_USE_CP_ACP
, buff
, sizeof( buff
) );
105 OSL_ASSERT( nResult
);
109 sal_Int32 len
= MultiByteToWideChar(
110 CP_ACP
, 0, buff
, -1, NULL
, 0 );
112 OSL_ASSERT( len
> 0 );
114 std::vector
< sal_Unicode
> lpwchBuff(len
);
116 len
= MultiByteToWideChar(
117 CP_ACP
, 0, buff
, -1, reinterpret_cast<LPWSTR
>(&lpwchBuff
[0]), len
);
119 winCP
= OUString( &lpwchBuff
[0], (len
- 1) );
125 // returns a mime charset parameter value appropriate
126 // to the given codepage, optional a prefix can be
127 // given, e.g. "windows-" or "cp"
129 OUString SAL_CALL
getMimeCharsetFromWinCP( sal_uInt32 cp
, const OUString
& aPrefix
)
131 return aPrefix
+ cptostr( cp
);
134 // returns a mime charset parameter value appropriate
135 // to the given locale id and locale type, optional a
136 // prefix can be given, e.g. "windows-" or "cp"
138 OUString SAL_CALL
getMimeCharsetFromLocaleId( LCID lcid
, LCTYPE lctype
, const OUString
& aPrefix
)
140 OUString charset
= getWinCPFromLocaleId( lcid
, lctype
);
141 return aPrefix
+ charset
;
146 sal_Bool SAL_CALL
IsOEMCP( sal_uInt32 codepage
)
148 OSL_ASSERT( IsValidCodePage( codepage
) );
150 sal_uInt32 arrOEMCP
[] = { 437, 708, 709, 710, 720, 737,
151 775, 850, 852, 855, 857, 860,
152 861, 862, 863, 864, 865, 866,
153 869, 874, 932, 936, 949, 950, 1361 };
155 for ( size_t i
= 0; i
< SAL_N_ELEMENTS( arrOEMCP
); ++i
)
156 if ( arrOEMCP
[i
] == codepage
)
162 // converts a codepage into its string representation
164 OUString SAL_CALL
cptostr( sal_uInt32 codepage
)
166 OSL_ASSERT( IsValidCodePage( codepage
) );
168 return OUString::number( static_cast<sal_Int64
>( codepage
) );
171 // OleStdDeleteTargetDevice()
178 // SCODE - S_OK if successful
179 void SAL_CALL
DeleteTargetDevice( DVTARGETDEVICE
* ptd
)
181 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
184 if (__builtin_setjmp(jmpbuf
) == 0)
186 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
191 CoTaskMemFree( ptd
);
193 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
196 __except( EXCEPTION_EXECUTE_HANDLER
)
199 OSL_FAIL( "Error DeleteTargetDevice" );
201 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
206 // OleStdCopyTargetDevice()
209 // duplicate a TARGETDEVICE struct. this function allocates memory for
210 // the copy. the caller MUST free the allocated copy when done with it
211 // using the standard allocator returned from CoGetMalloc.
212 // (OleStdFree can be used to free the copy).
215 // ptdSrc pointer to source TARGETDEVICE
218 // pointer to allocated copy of ptdSrc
219 // if ptdSrc==NULL then retuns NULL is returned.
220 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
221 DVTARGETDEVICE
* SAL_CALL
CopyTargetDevice( DVTARGETDEVICE
* ptdSrc
)
223 DVTARGETDEVICE
* ptdDest
= NULL
;
225 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
228 if (__builtin_setjmp(jmpbuf
) == 0)
230 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
235 if ( NULL
!= ptdSrc
)
237 ptdDest
= static_cast< DVTARGETDEVICE
* >( CoTaskMemAlloc( ptdSrc
->tdSize
) );
238 memcpy( ptdDest
, ptdSrc
, static_cast< size_t >( ptdSrc
->tdSize
) );
241 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
244 __except( EXCEPTION_EXECUTE_HANDLER
)
252 // OleStdCopyFormatEtc()
255 // Copies the contents of a FORMATETC structure. this function takes
256 // special care to copy correctly copying the pointer to the TARGETDEVICE
257 // contained within the source FORMATETC structure.
258 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
259 // of the TARGETDEVICE will be allocated for the destination of the
260 // FORMATETC (petcDest).
262 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
263 // within the destination FORMATETC when done with it
264 // using the standard allocator returned from CoGetMalloc.
265 // (OleStdFree can be used to free the copy).
268 // petcDest pointer to destination FORMATETC
269 // petcSrc pointer to source FORMATETC
272 // returns TRUE if copy was successful;
273 // retuns FALSE if not successful, e.g. one or both of the pointers
274 // were invalid or the pointers were equal
275 sal_Bool SAL_CALL
CopyFormatEtc( LPFORMATETC petcDest
, LPFORMATETC petcSrc
)
277 sal_Bool bRet
= sal_False
;
279 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
282 if (__builtin_setjmp(jmpbuf
) == 0)
284 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
289 if ( petcDest
!= petcSrc
)
292 petcDest
->cfFormat
= petcSrc
->cfFormat
;
294 petcDest
->ptd
= NULL
;
295 if ( NULL
!= petcSrc
->ptd
)
296 petcDest
->ptd
= CopyTargetDevice(petcSrc
->ptd
);
298 petcDest
->dwAspect
= petcSrc
->dwAspect
;
299 petcDest
->lindex
= petcSrc
->lindex
;
300 petcDest
->tymed
= petcSrc
->tymed
;
305 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
308 __except( EXCEPTION_EXECUTE_HANDLER
)
311 OSL_FAIL( "Error CopyFormatEtc" );
313 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
321 // 1 for exact match,
323 // -1 for partial match (which is defined to mean the left is a subset
324 // of the right: fewer aspects, null target device, fewer medium).
326 sal_Int32 SAL_CALL
CompareFormatEtc( const FORMATETC
* pFetcLhs
, const FORMATETC
* pFetcRhs
)
328 sal_Int32 nMatch
= FORMATETC_EXACT_MATCH
;
330 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
333 if (__builtin_setjmp(jmpbuf
) == 0)
335 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
340 if ( pFetcLhs
!= pFetcRhs
)
342 if ( ( pFetcLhs
->cfFormat
!= pFetcRhs
->cfFormat
) ||
343 ( pFetcLhs
->lindex
!= pFetcRhs
->lindex
) ||
344 !CompareTargetDevice( pFetcLhs
->ptd
, pFetcRhs
->ptd
) )
346 nMatch
= FORMATETC_NO_MATCH
;
349 else if ( pFetcLhs
->dwAspect
== pFetcRhs
->dwAspect
)
350 // same aspects; equal
352 else if ( ( pFetcLhs
->dwAspect
& ~pFetcRhs
->dwAspect
) != 0 )
354 // left not subset of aspects of right; not equal
355 nMatch
= FORMATETC_NO_MATCH
;
358 // left subset of right
359 nMatch
= FORMATETC_PARTIAL_MATCH
;
361 if ( nMatch
== FORMATETC_EXACT_MATCH
|| nMatch
== FORMATETC_PARTIAL_MATCH
)
363 if ( pFetcLhs
->tymed
== pFetcRhs
->tymed
)
364 // same medium flags; equal
366 else if ( ( pFetcLhs
->tymed
& ~pFetcRhs
->tymed
) != 0 )
368 // left not subset of medium flags of right; not equal
369 nMatch
= FORMATETC_NO_MATCH
;
372 // left subset of right
373 nMatch
= FORMATETC_PARTIAL_MATCH
;
377 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
380 __except( EXCEPTION_EXECUTE_HANDLER
)
383 OSL_FAIL( "Error CompareFormatEtc" );
384 nMatch
= FORMATETC_NO_MATCH
;
386 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
393 sal_Bool SAL_CALL
CompareTargetDevice( DVTARGETDEVICE
* ptdLeft
, DVTARGETDEVICE
* ptdRight
)
395 sal_Bool bRet
= sal_False
;
397 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
400 if (__builtin_setjmp(jmpbuf
) == 0)
402 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
407 if ( ptdLeft
== ptdRight
)
409 // same address of td; must be same (handles NULL case)
413 // one ot the two is NULL
414 else if ( ( NULL
!= ptdRight
) && ( NULL
!= ptdLeft
) )
416 if ( ptdLeft
->tdSize
== ptdRight
->tdSize
)
418 if ( memcmp( ptdLeft
, ptdRight
, ptdLeft
->tdSize
) == 0 )
421 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
424 __except( EXCEPTION_EXECUTE_HANDLER
)
427 OSL_FAIL( "Error CompareTargetDevice" );
430 #if defined ( __MINGW32__ ) && !defined ( _WIN64 )
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */