| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_dtrans.hxx" |
| |
| |
| //------------------------------------------------------------------------ |
| // includes |
| //------------------------------------------------------------------------ |
| #include <osl/diagnose.h> |
| #include "ImplHelper.hxx" |
| #include <rtl/tencinfo.h> |
| #include <rtl/memory.h> |
| |
| #include <memory> |
| #if defined _MSC_VER |
| #pragma warning(push,1) |
| #endif |
| #include <windows.h> |
| #if defined _MSC_VER |
| #pragma warning(pop) |
| #endif |
| #ifdef __MINGW32__ |
| #include <excpt.h> |
| #endif |
| |
| //------------------------------------------------------------------------ |
| // defines |
| //------------------------------------------------------------------------ |
| |
| #define FORMATETC_EXACT_MATCH 1 |
| #define FORMATETC_PARTIAL_MATCH -1 |
| #define FORMATETC_NO_MATCH 0 |
| |
| //------------------------------------------------------------------------ |
| // namespace directives |
| //------------------------------------------------------------------------ |
| |
| using ::rtl::OUString; |
| using ::rtl::OString; |
| |
| //------------------------------------------------------------------------ |
| // returns a windows codepage appropriate to the |
| // given mime charset parameter value |
| //------------------------------------------------------------------------ |
| |
| sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset ) |
| { |
| sal_uInt32 winCP = GetACP( ); |
| |
| if ( charset.getLength( ) ) |
| { |
| OString osCharset( |
| charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US ); |
| |
| rtl_TextEncoding txtEnc = |
| rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) ); |
| |
| sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc ); |
| |
| CHARSETINFO chrsInf; |
| sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ? |
| sal_True : sal_False; |
| |
| // if one of the above functions fails |
| // we will return the current ANSI codepage |
| // of this thread |
| if ( bRet ) |
| winCP = chrsInf.ciACP; |
| } |
| |
| return winCP; |
| } |
| |
| //-------------------------------------------------- |
| // returns a windows codepage appropriate to the |
| // given locale and locale type |
| //-------------------------------------------------- |
| |
| OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype ) |
| { |
| OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) ); |
| |
| // we set an default value |
| OUString winCP; |
| |
| // set an default value |
| if ( LOCALE_IDEFAULTCODEPAGE == lctype ) |
| { |
| winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 ); |
| } |
| else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype ) |
| { |
| winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 ); |
| } |
| else |
| OSL_ASSERT( sal_False ); |
| |
| // we use the GetLocaleInfoA because don't want to provide |
| // a unicode wrapper function for Win9x in sal/systools |
| char buff[6]; |
| sal_Int32 nResult = GetLocaleInfoA( |
| lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) ); |
| |
| OSL_ASSERT( nResult ); |
| |
| if ( nResult ) |
| { |
| sal_Int32 len = MultiByteToWideChar( |
| CP_ACP, 0, buff, -1, NULL, 0 ); |
| |
| OSL_ASSERT( len > 0 ); |
| |
| std::auto_ptr< sal_Unicode > lpwchBuff( new sal_Unicode[len] ); |
| |
| if ( NULL != lpwchBuff.get( ) ) |
| { |
| len = MultiByteToWideChar( |
| CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(lpwchBuff.get( )), len ); |
| |
| winCP = OUString( lpwchBuff.get( ), (len - 1) ); |
| } |
| } |
| |
| return winCP; |
| } |
| |
| //-------------------------------------------------- |
| // returns a mime charset parameter value appropriate |
| // to the given codepage, optional a prefix can be |
| // given, e.g. "windows-" or "cp" |
| //-------------------------------------------------- |
| |
| OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix ) |
| { |
| return aPrefix + cptostr( cp ); |
| } |
| |
| //-------------------------------------------------- |
| // returns a mime charset parameter value appropriate |
| // to the given locale id and locale type, optional a |
| // prefix can be given, e.g. "windows-" or "cp" |
| //-------------------------------------------------- |
| |
| OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix ) |
| { |
| OUString charset = getWinCPFromLocaleId( lcid, lctype ); |
| return aPrefix + charset; |
| } |
| |
| //------------------------------------------------------------------------ |
| // IsOEMCP |
| //------------------------------------------------------------------------ |
| |
| sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage ) |
| { |
| OSL_ASSERT( IsValidCodePage( codepage ) ); |
| |
| sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737, |
| 775, 850, 852, 855, 857, 860, |
| 861, 862, 863, 864, 865, 866, |
| 869, 874, 932, 936, 949, 950, 1361 }; |
| |
| for ( sal_Int8 i = 0; i < ( sizeof( arrOEMCP )/sizeof( sal_uInt32 ) ); ++i ) |
| if ( arrOEMCP[i] == codepage ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| //------------------------------------------------------------------------ |
| // converts a codepage into its string representation |
| //------------------------------------------------------------------------ |
| |
| OUString SAL_CALL cptostr( sal_uInt32 codepage ) |
| { |
| OSL_ASSERT( IsValidCodePage( codepage ) ); |
| |
| return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 ); |
| } |
| |
| //------------------------------------------------------------------------- |
| // OleStdDeleteTargetDevice() |
| // |
| // Purpose: |
| // |
| // Parameters: |
| // |
| // Return Value: |
| // SCODE - S_OK if successful |
| //------------------------------------------------------------------------- |
| |
| void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd ) |
| { |
| #ifdef __MINGW32__ |
| jmp_buf jmpbuf; |
| __SEHandler han; |
| if (__builtin_setjmp(jmpbuf) == 0) |
| { |
| han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); |
| #else |
| __try |
| { |
| #endif |
| CoTaskMemFree( ptd ); |
| } |
| #ifdef __MINGW32__ |
| else |
| #else |
| __except( EXCEPTION_EXECUTE_HANDLER ) |
| #endif |
| { |
| OSL_ENSURE( sal_False, "Error DeleteTargetDevice" ); |
| } |
| #ifdef __MINGW32__ |
| han.Reset(); |
| #endif |
| } |
| |
| |
| |
| //------------------------------------------------------------------------- |
| // OleStdCopyTargetDevice() |
| // |
| // Purpose: |
| // duplicate a TARGETDEVICE struct. this function allocates memory for |
| // the copy. the caller MUST free the allocated copy when done with it |
| // using the standard allocator returned from CoGetMalloc. |
| // (OleStdFree can be used to free the copy). |
| // |
| // Parameters: |
| // ptdSrc pointer to source TARGETDEVICE |
| // |
| // Return Value: |
| // pointer to allocated copy of ptdSrc |
| // if ptdSrc==NULL then retuns NULL is returned. |
| // if ptdSrc!=NULL and memory allocation fails, then NULL is returned |
| //------------------------------------------------------------------------- |
| |
| DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc ) |
| { |
| DVTARGETDEVICE* ptdDest = NULL; |
| |
| #ifdef __MINGW32__ |
| jmp_buf jmpbuf; |
| __SEHandler han; |
| if (__builtin_setjmp(jmpbuf) == 0) |
| { |
| han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); |
| #else |
| __try |
| { |
| #endif |
| if ( NULL != ptdSrc ) |
| { |
| ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) ); |
| rtl_copyMemory( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) ); |
| } |
| } |
| #ifdef __MINGW32__ |
| han.Reset(); |
| #else |
| __except( EXCEPTION_EXECUTE_HANDLER ) |
| { |
| } |
| #endif |
| |
| return ptdDest; |
| } |
| |
| |
| //------------------------------------------------------------------------- |
| // OleStdCopyFormatEtc() |
| // |
| // Purpose: |
| // Copies the contents of a FORMATETC structure. this function takes |
| // special care to copy correctly copying the pointer to the TARGETDEVICE |
| // contained within the source FORMATETC structure. |
| // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy |
| // of the TARGETDEVICE will be allocated for the destination of the |
| // FORMATETC (petcDest). |
| // |
| // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE |
| // within the destination FORMATETC when done with it |
| // using the standard allocator returned from CoGetMalloc. |
| // (OleStdFree can be used to free the copy). |
| // |
| // Parameters: |
| // petcDest pointer to destination FORMATETC |
| // petcSrc pointer to source FORMATETC |
| // |
| // Return Value: |
| // returns TRUE if copy was successful; |
| // retuns FALSE if not successful, e.g. one or both of the pointers |
| // were invalid or the pointers were equal |
| //------------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc ) |
| { |
| sal_Bool bRet = sal_False; |
| |
| #ifdef __MINGW32__ |
| jmp_buf jmpbuf; |
| __SEHandler han; |
| if (__builtin_setjmp(jmpbuf) == 0) |
| { |
| han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); |
| #else |
| __try |
| { |
| #endif |
| if ( petcDest != petcSrc ) |
| { |
| |
| petcDest->cfFormat = petcSrc->cfFormat; |
| |
| petcDest->ptd = NULL; |
| if ( NULL != petcSrc->ptd ) |
| petcDest->ptd = CopyTargetDevice(petcSrc->ptd); |
| |
| petcDest->dwAspect = petcSrc->dwAspect; |
| petcDest->lindex = petcSrc->lindex; |
| petcDest->tymed = petcSrc->tymed; |
| |
| bRet = sal_True; |
| } |
| } |
| #ifdef __MINGW32__ |
| else |
| #else |
| __except( EXCEPTION_EXECUTE_HANDLER ) |
| #endif |
| { |
| OSL_ENSURE( sal_False, "Error CopyFormatEtc" ); |
| } |
| #ifdef __MINGW32__ |
| han.Reset(); |
| #endif |
| |
| return bRet; |
| } |
| |
| //------------------------------------------------------------------------- |
| // returns: |
| // 1 for exact match, |
| // 0 for no match, |
| // -1 for partial match (which is defined to mean the left is a subset |
| // of the right: fewer aspects, null target device, fewer medium). |
| //------------------------------------------------------------------------- |
| |
| sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs ) |
| { |
| sal_Int32 nMatch = FORMATETC_EXACT_MATCH; |
| |
| #ifdef __MINGW32__ |
| jmp_buf jmpbuf; |
| __SEHandler han; |
| if (__builtin_setjmp(jmpbuf) == 0) |
| { |
| han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); |
| #else |
| __try |
| { |
| #endif |
| if ( pFetcLhs != pFetcRhs ) |
| |
| if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) || |
| ( pFetcLhs->lindex != pFetcRhs->lindex ) || |
| !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) ) |
| { |
| nMatch = FORMATETC_NO_MATCH; |
| } |
| |
| else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect ) |
| // same aspects; equal |
| ; |
| else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 ) |
| { |
| // left not subset of aspects of right; not equal |
| nMatch = FORMATETC_NO_MATCH; |
| } |
| else |
| // left subset of right |
| nMatch = FORMATETC_PARTIAL_MATCH; |
| |
| if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH ) |
| { |
| if ( pFetcLhs->tymed == pFetcRhs->tymed ) |
| // same medium flags; equal |
| ; |
| else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 ) |
| { |
| // left not subset of medium flags of right; not equal |
| nMatch = FORMATETC_NO_MATCH; |
| } |
| else |
| // left subset of right |
| nMatch = FORMATETC_PARTIAL_MATCH; |
| } |
| } |
| #ifdef __MINGW32__ |
| else |
| #else |
| __except( EXCEPTION_EXECUTE_HANDLER ) |
| #endif |
| { |
| OSL_ENSURE( sal_False, "Error CompareFormatEtc" ); |
| nMatch = FORMATETC_NO_MATCH; |
| } |
| #ifdef __MINGW32__ |
| han.Reset(); |
| #endif |
| |
| return nMatch; |
| } |
| |
| |
| //------------------------------------------------------------------------- |
| // |
| //------------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight ) |
| { |
| sal_Bool bRet = sal_False; |
| |
| #ifdef __MINGW32__ |
| jmp_buf jmpbuf; |
| __SEHandler han; |
| if (__builtin_setjmp(jmpbuf) == 0) |
| { |
| han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); |
| #else |
| __try |
| { |
| #endif |
| if ( ptdLeft == ptdRight ) |
| { |
| // same address of td; must be same (handles NULL case) |
| bRet = sal_True; |
| } |
| |
| // one ot the two is NULL |
| else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) ) |
| |
| if ( ptdLeft->tdSize == ptdRight->tdSize ) |
| |
| if ( rtl_compareMemory( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 ) |
| bRet = sal_True; |
| } |
| #ifdef __MINGW32__ |
| else |
| #else |
| __except( EXCEPTION_EXECUTE_HANDLER ) |
| #endif |
| { |
| OSL_ENSURE( sal_False, "Error CompareTargetDevice" ); |
| bRet = sal_False; |
| } |
| #ifdef __MINGW32__ |
| han.Reset(); |
| #endif |
| |
| return bRet; |
| } |