diff options
author | RĂ¼diger Timm <rt@openoffice.org> | 2007-07-24 09:28:49 +0000 |
---|---|---|
committer | RĂ¼diger Timm <rt@openoffice.org> | 2007-07-24 09:28:49 +0000 |
commit | b6801926b515be4cfb10ca7e3322939f0f97426b (patch) | |
tree | 7971cdac09b3e2fc4055be2aa8408782d114b950 /vcl/unx | |
parent | cbb5b49ce60a793220a68e29150cf98a3e3a0f85 (diff) |
INTEGRATION: CWS mergesvp (1.1.2); FILE ADDED
2007/06/27 11:10:52 pl 1.1.2.1: #i78931# contribute svp sources
Diffstat (limited to 'vcl/unx')
-rw-r--r-- | vcl/unx/headless/svpelement.cxx | 299 | ||||
-rw-r--r-- | vcl/unx/headless/svpelement.hxx | 56 | ||||
-rw-r--r-- | vcl/unx/headless/svpframe.cxx | 436 | ||||
-rw-r--r-- | vcl/unx/headless/svpframe.hxx | 130 | ||||
-rw-r--r-- | vcl/unx/headless/svpgdi.cxx | 537 | ||||
-rw-r--r-- | vcl/unx/headless/svpgdi.hxx | 181 | ||||
-rw-r--r-- | vcl/unx/headless/svpinst.cxx | 535 | ||||
-rw-r--r-- | vcl/unx/headless/svpinst.hxx | 205 | ||||
-rw-r--r-- | vcl/unx/headless/svpprn.cxx | 1109 | ||||
-rw-r--r-- | vcl/unx/headless/svpprn.hxx | 133 | ||||
-rw-r--r-- | vcl/unx/headless/svppspgraphics.hxx | 206 | ||||
-rw-r--r-- | vcl/unx/headless/svptext.cxx | 510 |
12 files changed, 4337 insertions, 0 deletions
diff --git a/vcl/unx/headless/svpelement.cxx b/vcl/unx/headless/svpelement.cxx new file mode 100644 index 000000000000..9f39503e4b2b --- /dev/null +++ b/vcl/unx/headless/svpelement.cxx @@ -0,0 +1,299 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpelement.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:26:44 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "svpelement.hxx" + +#include <basebmp/scanlineformats.hxx> +#include <tools/debug.hxx> + +#if defined WITH_SVP_LISTENING +#include <osl/thread.h> +#include <vcl/svapp.hxx> +#include <rtl/strbuf.hxx> +#include <vcl/bitmap.hxx> +#include <tools/stream.hxx> + +#include "svpvd.hxx" +#include "svpbmp.hxx" +#include "svpframe.hxx" + +#include <list> +#include <hash_map> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/ip.h> +#include <stdio.h> +#include <errno.h> + +using namespace basegfx; + +class SvpElementContainer +{ + std::list< SvpElement* > m_aElements; + int m_nSocket; + oslThread m_aThread; + + SvpElementContainer(); + ~SvpElementContainer(); + public: + void registerElement( SvpElement* pElement ) { m_aElements.push_back(pElement); } + void deregisterElement( SvpElement* pElement ) { m_aElements.remove(pElement); } + + void run(); + DECL_LINK(processRequest,void*); + + static SvpElementContainer& get(); +}; + +extern "C" void SAL_CALL SvpContainerThread( void* ); + +SvpElementContainer& SvpElementContainer::get() +{ + static SvpElementContainer* pInstance = new SvpElementContainer(); + return *pInstance; +} + +SvpElementContainer::SvpElementContainer() +{ + static const char* pEnv = getenv("SVP_LISTENER_PORT"); + int nPort = (pEnv && *pEnv) ? atoi(pEnv) : 8000; + m_nSocket = socket( PF_INET, SOCK_STREAM, 0 ); + if( m_nSocket >= 0) + { + int nOn = 1; + if( setsockopt(m_nSocket, SOL_SOCKET, SO_REUSEADDR, + (char*)&nOn, sizeof(nOn)) ) + { + perror( "SvpElementContainer: changing socket options failed" ); + close( m_nSocket ); + } + else + { + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(nPort); + addr.sin_addr.s_addr = INADDR_ANY; + if( bind(m_nSocket,(struct sockaddr*)&addr,sizeof(addr)) ) + { + perror( "SvpElementContainer: bind() failed" ); + close( m_nSocket ); + } + else + { + if( listen( m_nSocket, 0 ) ) + { + perror( "SvpElementContainer: listen() failed" ); + close(m_nSocket); + } + else + { + m_aThread = osl_createThread( SvpContainerThread, this ); + } + } + } + } + else + perror( "SvpElementContainer: socket() failed\n" ); +} + +SvpElementContainer::~SvpElementContainer() +{ +} + +void SAL_CALL SvpContainerThread(void* pSvpContainer) +{ + ((SvpElementContainer*)pSvpContainer)->run(); +} + +void SvpElementContainer::run() +{ + bool bRun = m_nSocket != 0; + while( bRun ) + { + int nLocalSocket = accept( m_nSocket, NULL, NULL ); + if( nLocalSocket < 0 ) + { + bRun = false; + perror( "accept() failed" ); + } + else + { + Application::PostUserEvent( LINK( this, SvpElementContainer, processRequest ), (void*)nLocalSocket ); + } + } + if( m_nSocket ) + close( m_nSocket ); +} + +static const char* matchType( SvpElement* pEle ) +{ + if( dynamic_cast<SvpSalBitmap*>(pEle) ) + return "Bitmap"; + else if( dynamic_cast<SvpSalFrame*>(pEle) ) + return "Frame"; + else if( dynamic_cast<SvpSalVirtualDevice*>(pEle) ) + return "VirtualDevice"; + return typeid(*pEle).name(); +} + +IMPL_LINK( SvpElementContainer, processRequest, void*, pSocket ) +{ + int nFile = (int)pSocket; + + rtl::OStringBuffer aBuf( 256 ), aAnswer( 256 ); + char c; + while( read( nFile, &c, 1 ) && c != '\n' ) + aBuf.append( sal_Char(c) ); + rtl::OString aCommand( aBuf.makeStringAndClear() ); + if( aCommand.compareTo( "list", 4 ) == 0 ) + { + std::hash_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash > aMap; + for( std::list< SvpElement* >::const_iterator it = m_aElements.begin(); + it != m_aElements.end(); ++it ) + { + std::list<SvpElement*>& rList = aMap[matchType(*it)]; + rList.push_back( *it ); + } + for( std::hash_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash>::const_iterator hash_it = aMap.begin(); + hash_it != aMap.end(); ++hash_it ) + { + aAnswer.append( "ElementType: " ); + aAnswer.append( hash_it->first ); + aAnswer.append( '\n' ); + for( std::list<SvpElement*>::const_iterator it = hash_it->second.begin(); + it != hash_it->second.end(); ++it ) + { + aAnswer.append( sal_Int64(reinterpret_cast<sal_uInt32>(*it)), 16 ); + aAnswer.append( '\n' ); + } + } + } + else if( aCommand.compareTo( "get", 3 ) == 0 ) + { + sal_IntPtr aId = aCommand.copy( 3 ).toInt64( 16 ); + SvpElement* pElement = reinterpret_cast<SvpElement*>(aId); + for( std::list< SvpElement* >::const_iterator it = m_aElements.begin(); + it != m_aElements.end(); ++it ) + { + if( *it == pElement ) + { + const basebmp::BitmapDeviceSharedPtr& rDevice = pElement->getDevice(); + if( rDevice.get() ) + { + SvpSalBitmap* pSalBitmap = new SvpSalBitmap(); + pSalBitmap->setBitmap( rDevice ); + Bitmap aBitmap( pSalBitmap ); + SvMemoryStream aStream( 256, 256 ); + aStream << aBitmap; + aStream.Seek( STREAM_SEEK_TO_END ); + int nBytes = aStream.Tell(); + aStream.Seek( STREAM_SEEK_TO_BEGIN ); + aAnswer.append( (const sal_Char*)aStream.GetData(), nBytes ); + } + break; + } + } + } + else if( aCommand.compareTo( "quit", 4 ) == 0 ) + { + Application::Quit(); + close( m_nSocket ); + m_nSocket = 0; + } + write( nFile, aAnswer.getStr(), aAnswer.getLength() ); + close( nFile ); + + return 0; +} + +#endif + +using namespace basebmp; + +SvpElement::SvpElement() +{ + #if defined WITH_SVP_LISTENING + SvpElementContainer::get().registerElement( this ); + #endif +} + +SvpElement::~SvpElement() +{ + #if defined WITH_SVP_LISTENING + SvpElementContainer::get().deregisterElement( this ); + #endif +} + +sal_uInt32 SvpElement::getBitCountFromScanlineFormat( sal_Int32 nFormat ) +{ + sal_uInt32 nBitCount = 1; + switch( nFormat ) + { + case Format::ONE_BIT_MSB_GREY: + case Format::ONE_BIT_LSB_GREY: + case Format::ONE_BIT_MSB_PAL: + case Format::ONE_BIT_LSB_PAL: + nBitCount = 1; + break; + case Format::FOUR_BIT_MSB_GREY: + case Format::FOUR_BIT_LSB_GREY: + case Format::FOUR_BIT_MSB_PAL: + case Format::FOUR_BIT_LSB_PAL: + nBitCount = 4; + break; + case Format::EIGHT_BIT_PAL: + case Format::EIGHT_BIT_GREY: + nBitCount = 8; + break; + case Format::SIXTEEN_BIT_LSB_TC_MASK: + case Format::SIXTEEN_BIT_MSB_TC_MASK: + nBitCount = 16; + break; + case Format::TWENTYFOUR_BIT_TC_MASK: + nBitCount = 24; + break; + case Format::THIRTYTWO_BIT_TC_MASK: + nBitCount = 32; + break; + default: + DBG_ERROR( "unsupported basebmp format" ); + break; + } + return nBitCount; +} + + diff --git a/vcl/unx/headless/svpelement.hxx b/vcl/unx/headless/svpelement.hxx new file mode 100644 index 000000000000..0c37e6c62f03 --- /dev/null +++ b/vcl/unx/headless/svpelement.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpelement.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:26:55 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_SVPELEMENT_HXX +#define _SVP_SVPELEMENT_HXX + +#ifndef INCLUDED_BASEBMP_BITMAPDEVICE_HXX +#include <basebmp/bitmapdevice.hxx> +#endif + +#define SVP_DEFAULT_BITMAP_FORMAT basebmp::Format::TWENTYFOUR_BIT_TC_MASK + +class SvpElement +{ + protected: + SvpElement(); + virtual ~SvpElement(); + public: + virtual const basebmp::BitmapDeviceSharedPtr& getDevice() const = 0; + + static sal_uInt32 getBitCountFromScanlineFormat( sal_Int32 nFormat ); +}; + +#endif diff --git a/vcl/unx/headless/svpframe.cxx b/vcl/unx/headless/svpframe.cxx new file mode 100644 index 000000000000..0a3e743946c4 --- /dev/null +++ b/vcl/unx/headless/svpframe.cxx @@ -0,0 +1,436 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpframe.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:06 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "svpframe.hxx" +#include "svpinst.hxx" +#include "svpgdi.hxx" + +#include <basebmp/scanlineformats.hxx> +#include <basegfx/vector/b2ivector.hxx> + +using namespace basebmp; +using namespace basegfx; + +SvpSalFrame* SvpSalFrame::s_pFocusFrame = NULL; + +SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance, + SalFrame* pParent, + ULONG nSalFrameStyle, + SystemParentData* ) : + m_pInstance( pInstance ), + m_pParent( static_cast<SvpSalFrame*>(pParent) ), + m_nStyle( nSalFrameStyle ), + m_bVisible( false ), + m_nMinWidth( 0 ), + m_nMinHeight( 0 ), + m_nMaxWidth( 0 ), + m_nMaxHeight( 0 ) +{ + m_aSystemChildData.nSize = sizeof( SystemChildData ); + m_aSystemChildData.pDisplay = NULL; + m_aSystemChildData.aWindow = 0; + m_aSystemChildData.pSalFrame = this; + m_aSystemChildData.pWidget = NULL; + m_aSystemChildData.pVisual = NULL; + m_aSystemChildData.nDepth = 24; + m_aSystemChildData.aColormap = 0; + m_aSystemChildData.pAppContext = NULL; + m_aSystemChildData.aShellWindow = 0; + m_aSystemChildData.pShellWidget = NULL; + + if( m_pParent ) + m_pParent->m_aChildren.push_back( this ); + + if( m_pInstance ) + m_pInstance->registerFrame( this ); + + SetPosSize( 0, 0, 800, 600, SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); +} + +SvpSalFrame::~SvpSalFrame() +{ + if( m_pInstance ) + m_pInstance->deregisterFrame( this ); + + std::list<SvpSalFrame*> Children = m_aChildren; + for( std::list<SvpSalFrame*>::iterator it = Children.begin(); + it != Children.end(); ++it ) + (*it)->SetParent( m_pParent ); + if( m_pParent ) + m_pParent->m_aChildren.remove( this ); +} + +void SvpSalFrame::GetFocus() +{ + if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_FLOAT)) == 0 ) + { + if( s_pFocusFrame ) + s_pFocusFrame->LoseFocus(); + s_pFocusFrame = this; + m_pInstance->PostEvent( this, NULL, SALEVENT_GETFOCUS ); + } +} + +void SvpSalFrame::LoseFocus() +{ + if( s_pFocusFrame == this ) + { + m_pInstance->PostEvent( this, NULL, SALEVENT_LOSEFOCUS ); + s_pFocusFrame = NULL; + } +} + +SalGraphics* SvpSalFrame::GetGraphics() +{ + SvpSalGraphics* pGraphics = new SvpSalGraphics(); + pGraphics->setDevice( m_aFrame ); + m_aGraphics.push_back( pGraphics ); + return pGraphics; +} + +void SvpSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) +{ + SvpSalGraphics* pSvpGraphics = dynamic_cast<SvpSalGraphics*>(pGraphics); + m_aGraphics.remove( pSvpGraphics ); + delete pSvpGraphics; +} + +BOOL SvpSalFrame::PostEvent( void* pData ) +{ + m_pInstance->PostEvent( this, pData, SALEVENT_USEREVENT ); + return TRUE; +} + +void SvpSalFrame::PostPaint() const +{ + if( m_bVisible ) + { + SalPaintEvent aPEvt; + + aPEvt.mnBoundX = 0; + aPEvt.mnBoundY = 0; + aPEvt.mnBoundWidth = maGeometry.nWidth; + aPEvt.mnBoundHeight = maGeometry.nHeight; + + CallCallback( SALEVENT_PAINT, &aPEvt ); + } +} + +void SvpSalFrame::SetTitle( const XubString& ) +{ +} + +void SvpSalFrame::SetIcon( USHORT ) +{ +} + +void SvpSalFrame::SetMenu( SalMenu* ) +{ +} + +void SvpSalFrame::DrawMenuBar() +{ +} + +void SvpSalFrame::SetExtendedFrameStyle( SalExtStyle ) +{ +} + +void SvpSalFrame::Show( BOOL bVisible, BOOL bNoActivate ) +{ + if( bVisible && ! m_bVisible ) + { + m_bVisible = true; + m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE ); + if( ! bNoActivate ) + GetFocus(); + } + else if( ! bVisible && m_bVisible ) + { + m_bVisible = false; + m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE ); + LoseFocus(); + } +} + +void SvpSalFrame::Enable( BOOL ) +{ +} + +void SvpSalFrame::SetMinClientSize( long nWidth, long nHeight ) +{ + m_nMinWidth = nWidth; + m_nMinHeight = nHeight; +} + +void SvpSalFrame::SetMaxClientSize( long nWidth, long nHeight ) +{ + m_nMaxWidth = nWidth; + m_nMaxHeight = nHeight; +} + +void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, USHORT nFlags ) +{ + if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 ) + maGeometry.nX = nX; + if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0 ) + maGeometry.nY = nY; + if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 ) + { + maGeometry.nWidth = nWidth; + if( m_nMaxWidth > 0 && maGeometry.nWidth > (unsigned int)m_nMaxWidth ) + maGeometry.nWidth = m_nMaxWidth; + if( m_nMinWidth > 0 && maGeometry.nWidth < (unsigned int)m_nMinWidth ) + maGeometry.nWidth = m_nMinWidth; + } + if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0 ) + { + maGeometry.nHeight = nHeight; + if( m_nMaxHeight > 0 && maGeometry.nHeight > (unsigned int)m_nMaxHeight ) + maGeometry.nHeight = m_nMaxHeight; + if( m_nMinHeight > 0 && maGeometry.nHeight < (unsigned int)m_nMinHeight ) + maGeometry.nHeight = m_nMinHeight; + } + B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight ); + if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize ) + { + if( aFrameSize.getX() == 0 ) + aFrameSize.setX( 1 ); + if( aFrameSize.getY() == 0 ) + aFrameSize.setY( 1 ); + m_aFrame = createBitmapDevice( aFrameSize, false, SVP_DEFAULT_BITMAP_FORMAT ); + // update device in existing graphics + for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin(); + it != m_aGraphics.end(); ++it ) + (*it)->setDevice( m_aFrame ); + } + if( m_bVisible ) + m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE ); +} + +void SvpSalFrame::GetClientSize( long& rWidth, long& rHeight ) +{ + if( m_bVisible ) + { + rWidth = maGeometry.nWidth; + rHeight = maGeometry.nHeight; + } + else + rWidth = rHeight = 0; +} + +void SvpSalFrame::GetWorkArea( Rectangle& rRect ) +{ + rRect = Rectangle( Point( 0, 0 ), + Size( VIRTUAL_DESKTOP_WIDTH, VIRTUAL_DESKTOP_HEIGHT ) ); +} + +SalFrame* SvpSalFrame::GetParent() const +{ + return m_pParent; +} + +#define _FRAMESTATE_MASK_GEOMETRY \ + (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | \ + SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT) +#define _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY \ + (SAL_FRAMESTATE_MASK_MAXIMIZED_X | SAL_FRAMESTATE_MASK_MAXIMIZED_Y | \ + SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT) + +void SvpSalFrame::SetWindowState( const SalFrameState *pState ) +{ + if (pState == NULL) + return; + + // Request for position or size change + if (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY) + { + long nX = maGeometry.nX; + long nY = maGeometry.nY; + long nWidth = maGeometry.nWidth; + long nHeight = maGeometry.nHeight; + + // change requested properties + if (pState->mnMask & SAL_FRAMESTATE_MASK_X) + nX = pState->mnX; + if (pState->mnMask & SAL_FRAMESTATE_MASK_Y) + nY = pState->mnY; + if (pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH) + nWidth = pState->mnWidth; + if (pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT) + nHeight = pState->mnHeight; + + SetPosSize( nX, nY, nWidth, nHeight, + SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | + SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); + } +} + +BOOL SvpSalFrame::GetWindowState( SalFrameState* pState ) +{ + pState->mnState = SAL_FRAMESTATE_NORMAL; + pState->mnX = maGeometry.nX; + pState->mnY = maGeometry.nY; + pState->mnWidth = maGeometry.nWidth; + pState->mnHeight = maGeometry.nHeight; + pState->mnMask = _FRAMESTATE_MASK_GEOMETRY | SAL_FRAMESTATE_MASK_STATE; + + return TRUE; +} + +void SvpSalFrame::ShowFullScreen( BOOL, sal_Int32 ) +{ + SetPosSize( 0, 0, VIRTUAL_DESKTOP_WIDTH, VIRTUAL_DESKTOP_HEIGHT, + SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); +} + +void SvpSalFrame::StartPresentation( BOOL ) +{ +} + +void SvpSalFrame::SetAlwaysOnTop( BOOL ) +{ +} + +void SvpSalFrame::ToTop( USHORT ) +{ + GetFocus(); +} + +void SvpSalFrame::SetPointer( PointerStyle ) +{ +} + +void SvpSalFrame::CaptureMouse( BOOL ) +{ +} + +void SvpSalFrame::SetPointerPos( long, long ) +{ +} + +void SvpSalFrame::Flush() +{ +} + +void SvpSalFrame::Sync() +{ +} + +void SvpSalFrame::SetInputContext( SalInputContext* ) +{ +} + +void SvpSalFrame::EndExtTextInput( USHORT ) +{ +} + +String SvpSalFrame::GetKeyName( USHORT ) +{ + return String(); +} + +String SvpSalFrame::GetSymbolKeyName( const XubString&, USHORT ) +{ + return String(); +} + +BOOL SvpSalFrame::MapUnicodeToKeyCode( sal_Unicode, LanguageType, KeyCode& ) +{ + return FALSE; +} + +LanguageType SvpSalFrame::GetInputLanguage() +{ + return LANGUAGE_DONTKNOW; +} + +SalBitmap* SvpSalFrame::SnapShot() +{ + return NULL; +} + +void SvpSalFrame::UpdateSettings( AllSettings& ) +{ +} + +void SvpSalFrame::Beep( SoundType ) +{ +} + +const SystemEnvData* SvpSalFrame::GetSystemData() const +{ + return &m_aSystemChildData; +} + +SalFrame::SalPointerState SvpSalFrame::GetPointerState() +{ + SalPointerState aState; + aState.mnState = 0; + return aState; +} + +void SvpSalFrame::SetParent( SalFrame* pNewParent ) +{ + if( m_pParent ) + m_pParent->m_aChildren.remove( this ); + m_pParent = static_cast<SvpSalFrame*>(pNewParent); +} + +bool SvpSalFrame::SetPluginParent( SystemParentData* ) +{ + return true; +} + +void SvpSalFrame::SetBackgroundBitmap( SalBitmap* ) +{ +} + +void SvpSalFrame::ResetClipRegion() +{ +} + +void SvpSalFrame::BeginSetClipRegion( ULONG ) +{ +} + +void SvpSalFrame::UnionClipRegion( long, long, long, long ) +{ +} + +void SvpSalFrame::EndSetClipRegion() +{ +} + diff --git a/vcl/unx/headless/svpframe.hxx b/vcl/unx/headless/svpframe.hxx new file mode 100644 index 000000000000..d93989ce2960 --- /dev/null +++ b/vcl/unx/headless/svpframe.hxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpframe.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_SVPFRAME_HXX + +#include <vcl/salframe.hxx> +#include <vcl/sysdata.hxx> + +#include "svpelement.hxx" + +#include <list> + +class SvpSalInstance; +class SvpSalGraphics; + +class SvpSalFrame : public SalFrame, public SvpElement +{ + SvpSalInstance* m_pInstance; + SvpSalFrame* m_pParent; // pointer to parent frame + std::list< SvpSalFrame* > m_aChildren; // List of child frames + ULONG m_nStyle; + bool m_bVisible; + long m_nMinWidth; + long m_nMinHeight; + long m_nMaxWidth; + long m_nMaxHeight; + + SystemEnvData m_aSystemChildData; + + basebmp::BitmapDeviceSharedPtr m_aFrame; + std::list< SvpSalGraphics* > m_aGraphics; + + static SvpSalFrame* s_pFocusFrame; +public: + SvpSalFrame( SvpSalInstance* pInstance, + SalFrame* pParent, + ULONG nSalFrameStyle, + SystemParentData* pSystemParent = NULL ); + virtual ~SvpSalFrame(); + + void GetFocus(); + void LoseFocus(); + void PostPaint() const; + + // SvpElement + virtual const basebmp::BitmapDeviceSharedPtr& getDevice() const { return m_aFrame; } + + // SalFrame + virtual SalGraphics* GetGraphics(); + virtual void ReleaseGraphics( SalGraphics* pGraphics ); + + virtual BOOL PostEvent( void* pData ); + + virtual void SetTitle( const XubString& rTitle ); + virtual void SetIcon( USHORT nIcon ); + virtual void SetMenu( SalMenu* pMenu ); + virtual void DrawMenuBar(); + + virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle ); + virtual void Show( BOOL bVisible, BOOL bNoActivate = FALSE ); + virtual void Enable( BOOL bEnable ); + virtual void SetMinClientSize( long nWidth, long nHeight ); + virtual void SetMaxClientSize( long nWidth, long nHeight ); + virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, USHORT nFlags ); + virtual void GetClientSize( long& rWidth, long& rHeight ); + virtual void GetWorkArea( Rectangle& rRect ); + virtual SalFrame* GetParent() const; + virtual void SetWindowState( const SalFrameState* pState ); + virtual BOOL GetWindowState( SalFrameState* pState ); + virtual void ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay ); + virtual void StartPresentation( BOOL bStart ); + virtual void SetAlwaysOnTop( BOOL bOnTop ); + virtual void ToTop( USHORT nFlags ); + virtual void SetPointer( PointerStyle ePointerStyle ); + virtual void CaptureMouse( BOOL bMouse ); + virtual void SetPointerPos( long nX, long nY ); + virtual void Flush(); + virtual void Sync(); + virtual void SetInputContext( SalInputContext* pContext ); + virtual void EndExtTextInput( USHORT nFlags ); + virtual String GetKeyName( USHORT nKeyCode ); + virtual String GetSymbolKeyName( const XubString& rFontName, USHORT nKeyCode ); + virtual BOOL MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode ); + virtual LanguageType GetInputLanguage(); + virtual SalBitmap* SnapShot(); + virtual void UpdateSettings( AllSettings& rSettings ); + virtual void Beep( SoundType eSoundType ); + virtual const SystemEnvData* GetSystemData() const; + virtual SalPointerState GetPointerState(); + virtual void SetParent( SalFrame* pNewParent ); + virtual bool SetPluginParent( SystemParentData* pNewParent ); + virtual void SetBackgroundBitmap( SalBitmap* pBitmap ); + virtual void ResetClipRegion(); + virtual void BeginSetClipRegion( ULONG nRects ); + virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight ); + virtual void EndSetClipRegion(); +}; +#endif // _SVP_SVPFRAME_HXX diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx new file mode 100644 index 000000000000..488ee62ccdca --- /dev/null +++ b/vcl/unx/headless/svpgdi.cxx @@ -0,0 +1,537 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpgdi.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:28 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "svpgdi.hxx" +#include "svpbmp.hxx" + +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2irange.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basebmp/scanlineformats.hxx> + +#include <tools/debug.hxx> + +#if OSL_DEBUG_LEVEL > 2 +#include <basebmp/debug.hxx> +#include <fstream> +#include <rtl/strbuf.hxx> +#include <sys/stat.h> +#endif + +#include <svppspgraphics.hxx> + +using namespace basegfx; +using namespace basebmp; + +inline void dbgOut( const BitmapDeviceSharedPtr& +#if OSL_DEBUG_LEVEL > 2 +rDevice +#endif +) +{ + #if OSL_DEBUG_LEVEL > 2 + static int dbgStreamNum = 0; + rtl::OStringBuffer aBuf( 256 ); + aBuf.append( "debug" ); + mkdir( aBuf.getStr(), 0777 ); + aBuf.append( "/" ); + aBuf.append( sal_Int64(reinterpret_cast<sal_uInt32>(rDevice.get())), 16 ); + mkdir( aBuf.getStr(), 0777 ); + aBuf.append( "/bmp" ); + aBuf.append( sal_Int32(dbgStreamNum++) ); + std::fstream bmpstream( aBuf.getStr(), std::ios::out ); + debugDump( rDevice, bmpstream ); + #endif +} + +// =========================================================================== + +bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ ) +{ + // TODO(P3) implement alpha blending + return false; +} + +bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ ) +{ + // TODO(P3) implement alpha blending + return false; +} + +SvpSalGraphics::SvpSalGraphics() : + m_bUseLineColor( true ), + m_aLineColor( COL_BLACK ), + m_bUseFillColor( false ), + m_aFillColor( COL_WHITE ), + m_aTextColor( COL_BLACK ), + m_aDrawMode( DrawMode_PAINT ), + m_eTextFmt( Format::EIGHT_BIT_GREY ) +{ + for( int i = 0; i < MAX_FALLBACK; ++i ) + m_pServerFont[i] = NULL; +} + +SvpSalGraphics::~SvpSalGraphics() +{ +} + +void SvpSalGraphics::setDevice( BitmapDeviceSharedPtr& rDevice ) +{ + m_aDevice = rDevice; + m_aOrigDevice = rDevice; + m_aClipMap.reset(); + + // determine matching bitmap format for masks + sal_uInt32 nDeviceFmt = m_aDevice->getScanlineFormat(); + DBG_ASSERT( (nDeviceFmt <= (sal_uInt32)Format::MAX), "SVP::setDevice() with invalid bitmap format" ); + switch( nDeviceFmt ) + { + case Format::EIGHT_BIT_GREY: + case Format::SIXTEEN_BIT_LSB_TC_MASK: + case Format::SIXTEEN_BIT_MSB_TC_MASK: + case Format::TWENTYFOUR_BIT_TC_MASK: + case Format::THIRTYTWO_BIT_TC_MASK: + m_eTextFmt = Format::EIGHT_BIT_GREY; + break; + default: + m_eTextFmt = Format::ONE_BIT_LSB_GREY; + break; + } +} + +void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) +{ + rDPIX = rDPIY = 96; +} + +void SvpSalGraphics::GetScreenFontResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) +{ + rDPIX = rDPIY = 96; +} + +USHORT SvpSalGraphics::GetBitCount() +{ + return SvpElement::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() ); +} + +long SvpSalGraphics::GetGraphicsWidth() const +{ + if( m_aDevice.get() ) + { + B2IVector aSize = m_aDevice->getSize(); + return aSize.getX(); + } + return 0; +} + +void SvpSalGraphics::ResetClipRegion() +{ + m_aDevice = m_aOrigDevice; + m_aClipMap.reset(); +} + +void SvpSalGraphics::BeginSetClipRegion( ULONG n ) +{ + if( n <= 1 ) + { + m_aClipMap.reset(); + } + else + { + m_aDevice = m_aOrigDevice; + B2IVector aSize = m_aDevice->getSize(); + m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY ); + m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) ); + } +} + +BOOL SvpSalGraphics::unionClipRegion( long nX, long nY, long nWidth, long nHeight ) +{ + if( m_aClipMap ) + { + B2DPolyPolygon aFull; + aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) ) ); + m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT ); + } + else + { + m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice, + basegfx::B2IRange(nX,nY,nX+nWidth,nY+nHeight) ); + } + + return TRUE; +} + +void SvpSalGraphics::EndSetClipRegion() +{ +} + +void SvpSalGraphics::SetLineColor() +{ + m_bUseLineColor = false; +} + +void SvpSalGraphics::SetLineColor( SalColor nSalColor ) +{ + m_bUseLineColor = true; + m_aLineColor = basebmp::Color( nSalColor ); +} + +void SvpSalGraphics::SetFillColor() +{ + m_bUseFillColor = false; +} + +void SvpSalGraphics::SetFillColor( SalColor nSalColor ) +{ + m_bUseFillColor = true; + m_aFillColor = basebmp::Color( nSalColor ); +} + +void SvpSalGraphics::SetXORMode( BOOL bSet ) +{ + m_aDrawMode = bSet ? DrawMode_XOR : DrawMode_PAINT; +} + +void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor ) +{ + m_bUseLineColor = true; + switch( nROPColor ) + { + case SAL_ROP_0: + m_aLineColor = basebmp::Color( 0 ); + break; + case SAL_ROP_1: + m_aLineColor = basebmp::Color( 0xffffff ); + break; + case SAL_ROP_INVERT: + m_aLineColor = basebmp::Color( 0xffffff ); + break; + } +} + +void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor ) +{ + m_bUseFillColor = true; + switch( nROPColor ) + { + case SAL_ROP_0: + m_aFillColor = basebmp::Color( 0 ); + break; + case SAL_ROP_1: + m_aFillColor = basebmp::Color( 0xffffff ); + break; + case SAL_ROP_INVERT: + m_aFillColor = basebmp::Color( 0xffffff ); + break; + } +} + +void SvpSalGraphics::SetTextColor( SalColor nSalColor ) +{ + m_aTextColor = basebmp::Color( nSalColor ); +} + +void SvpSalGraphics::drawPixel( long nX, long nY ) +{ + if( m_bUseLineColor ) + m_aDevice->setPixel( B2IPoint( nX, nY ), + m_aLineColor, + m_aDrawMode, + m_aClipMap + ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) +{ + basebmp::Color aColor( nSalColor ); + m_aDevice->setPixel( B2IPoint( nX, nY ), + aColor, + m_aDrawMode, + m_aClipMap + ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + if( m_bUseLineColor ) + m_aDevice->drawLine( B2IPoint( nX1, nY1 ), + B2IPoint( nX2, nY2 ), + m_aLineColor, + m_aDrawMode, + m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) +{ + if( m_bUseLineColor || m_bUseFillColor ) + { + B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) ); + if( m_bUseFillColor ) + { + B2DPolyPolygon aPolyPoly( aRect ); + m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap ); + } + if( m_bUseLineColor ) + m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap ); + } + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ) +{ + if( m_bUseLineColor && nPoints ) + { + B2DPolygon aPoly; + aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints ); + for( ULONG i = 1; i < nPoints; i++ ) + aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) ); + aPoly.setClosed( false ); + m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap ); + } + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) +{ + if( ( m_bUseLineColor || m_bUseFillColor ) && nPoints ) + { + B2DPolygon aPoly; + aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints ); + for( ULONG i = 1; i < nPoints; i++ ) + aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) ); + if( m_bUseFillColor ) + { + aPoly.setClosed( true ); + m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap ); + } + if( m_bUseLineColor ) + { + aPoly.setClosed( false ); + m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap ); + } + } + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32* pPointCounts, + PCONSTSALPOINT* pPtAry ) +{ + if( ( m_bUseLineColor || m_bUseFillColor ) && nPoly ) + { + B2DPolyPolygon aPolyPoly; + for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ ) + { + sal_uInt32 nPoints = pPointCounts[nPolygon]; + if( nPoints ) + { + PCONSTSALPOINT pPoints = pPtAry[nPolygon]; + B2DPolygon aPoly; + aPoly.append( B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints ); + for( ULONG i = 1; i < nPoints; i++ ) + aPoly.setB2DPoint( i, B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) ); + + aPolyPoly.append( aPoly ); + } + } + if( m_bUseFillColor ) + { + aPolyPoly.setClosed( true ); + m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap ); + } + if( m_bUseLineColor ) + { + aPolyPoly.setClosed( false ); + nPoly = aPolyPoly.count(); + for( sal_uInt32 i = 0; i < nPoly; i++ ) + m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap ); + } + } + dbgOut( m_aDevice ); +} + +sal_Bool SvpSalGraphics::drawPolyLineBezier( ULONG, + const SalPoint*, + const BYTE* ) +{ + return sal_False; +} + +sal_Bool SvpSalGraphics::drawPolygonBezier( ULONG, + const SalPoint*, + const BYTE* ) +{ + return sal_False; +} + +sal_Bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32, + const sal_uInt32*, + const SalPoint* const*, + const BYTE* const* ) +{ + return sal_False; +} + +void SvpSalGraphics::copyArea( long nDestX, + long nDestY, + long nSrcX, + long nSrcY, + long nSrcWidth, + long nSrcHeight, + USHORT /*nFlags*/ ) +{ + B2IRange aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight ); + B2IRange aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight ); + m_aDevice->drawBitmap( m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, + SalGraphics* pSrcGraphics ) +{ + SvpSalGraphics* pSrc = pSrcGraphics ? + static_cast<SvpSalGraphics*>(pSrcGraphics) : this; + B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, + pPosAry->mnSrcX+pPosAry->mnSrcWidth, + pPosAry->mnSrcY+pPosAry->mnSrcHeight ); + B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, + pPosAry->mnDestX+pPosAry->mnDestWidth, + pPosAry->mnDestY+pPosAry->mnDestHeight ); + m_aDevice->drawBitmap( pSrc->m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap ) +{ + const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); + B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, + pPosAry->mnSrcX+pPosAry->mnSrcWidth, + pPosAry->mnSrcY+pPosAry->mnSrcHeight ); + B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, + pPosAry->mnDestX+pPosAry->mnDestWidth, + pPosAry->mnDestY+pPosAry->mnDestHeight ); + m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawBitmap( const SalTwoRect*, + const SalBitmap&, + SalColor ) +{ + // SNI, as in X11 plugin +} + +void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rTransparentBitmap ) +{ + const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); + const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap); + B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, + pPosAry->mnSrcX+pPosAry->mnSrcWidth, + pPosAry->mnSrcY+pPosAry->mnSrcHeight ); + B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, + pPosAry->mnDestX+pPosAry->mnDestWidth, + pPosAry->mnDestY+pPosAry->mnDestHeight ); + m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ) +{ + const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); + B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, + pPosAry->mnSrcX+pPosAry->mnSrcWidth, + pPosAry->mnSrcY+pPosAry->mnSrcHeight ); + B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY ); + basebmp::Color aColor( nMaskColor ); + m_aDevice->drawMaskedColor( aColor, rSrc.getBitmap(), aSrcRect, aDestPoint, m_aClipMap ); + dbgOut( m_aDevice ); +} + +SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight ) +{ + BitmapDeviceSharedPtr aCopy = + createBitmapDevice( B2IVector( nWidth, nHeight ), + m_aDevice->isTopDown(), + m_aDevice->getScanlineFormat() ); + B2IRange aSrcRect( nX, nY, nX+nWidth, nY+nHeight ); + B2IRange aDestRect( 0, 0, nWidth, nHeight ); + aCopy->drawBitmap( m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT ); + SvpSalBitmap* pBitmap = new SvpSalBitmap(); + pBitmap->setBitmap( aCopy ); + return pBitmap; +} + +SalColor SvpSalGraphics::getPixel( long nX, long nY ) +{ + basebmp::Color aColor( m_aDevice->getPixel( B2IPoint( nX, nY ) ) ); + return aColor.toInt32(); +} + +void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ ) +{ + // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME + B2DPolygon aRect = tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) ); + B2DPolyPolygon aPolyPoly( aRect ); + m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap ); + dbgOut( m_aDevice ); +} + +void SvpSalGraphics::invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ ) +{ + // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME + B2DPolygon aPoly; + aPoly.append( B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints ); + for( ULONG i = 1; i < nPoints; i++ ) + aPoly.setB2DPoint( i, B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) ); + aPoly.setClosed( true ); + m_aDevice->fillPolyPolygon( B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), DrawMode_XOR, m_aClipMap ); + dbgOut( m_aDevice ); +} + +BOOL SvpSalGraphics::drawEPS( long, long, long, long, void*, ULONG ) +{ + return FALSE; +} diff --git a/vcl/unx/headless/svpgdi.hxx b/vcl/unx/headless/svpgdi.hxx new file mode 100644 index 000000000000..b4e0136c528a --- /dev/null +++ b/vcl/unx/headless/svpgdi.hxx @@ -0,0 +1,181 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpgdi.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:38 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_SVPGDI_HXX + +#ifndef _SV_SALGDI_HXX +#include <vcl/salgdi.hxx> +#endif +#ifndef _SV_SALLAYOUT_HXX +#include <vcl/sallayout.hxx> +#endif +#ifndef INCLUDED_BASEBMP_BITMAPDEVICE_HXX +#include <basebmp/bitmapdevice.hxx> +#endif +#ifndef INCLUDED_BASEBMP_COLOR_HXX +#include <basebmp/color.hxx> +#endif + +class ServerFont; + +class SvpSalGraphics : public SalGraphics +{ + basebmp::BitmapDeviceSharedPtr m_aDevice; + basebmp::BitmapDeviceSharedPtr m_aOrigDevice; + basebmp::BitmapDeviceSharedPtr m_aClipMap; + + bool m_bUseLineColor; + basebmp::Color m_aLineColor; + bool m_bUseFillColor; + basebmp::Color m_aFillColor; + basebmp::Color m_aTextColor; + + basebmp::DrawMode m_aDrawMode; + + ServerFont* m_pServerFont[ MAX_FALLBACK ]; + sal_uInt32 m_eTextFmt; + +protected: + virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); + +public: + SvpSalGraphics(); + virtual ~SvpSalGraphics(); + + const basebmp::BitmapDeviceSharedPtr& getDevice() const { return m_aDevice; } + void setDevice( basebmp::BitmapDeviceSharedPtr& rDevice ); + + // overload all pure virtual methods + virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ); + virtual void GetScreenFontResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ); + virtual USHORT GetBitCount(); + virtual long GetGraphicsWidth() const; + + virtual void ResetClipRegion(); + virtual void BeginSetClipRegion( ULONG nCount ); + virtual BOOL unionClipRegion( long nX, long nY, long nWidth, long nHeight ); + virtual void EndSetClipRegion(); + + virtual void SetLineColor(); + virtual void SetLineColor( SalColor nSalColor ); + virtual void SetFillColor(); + + virtual void SetFillColor( SalColor nSalColor ); + + virtual void SetXORMode( BOOL bSet ); + + virtual void SetROPLineColor( SalROPColor nROPColor ); + virtual void SetROPFillColor( SalROPColor nROPColor ); + + virtual void SetTextColor( SalColor nSalColor ); + virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); + virtual void GetFontMetric( ImplFontMetricData* ); + virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); + virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual void GetDevFontList( ImplDevFontList* ); + virtual void GetDevFontSubstList( OutputDevice* ); + virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); + virtual BOOL CreateFontSubset( const rtl::OUString& rToFile, + ImplFontData* pFont, + sal_Int32* pGlyphIDs, + sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphs, + FontSubsetInfo& rInfo + ); + virtual const std::map< sal_Unicode, sal_Int32 >* GetFontEncodingVector( ImplFontData* pFont, const std::map< sal_Unicode, rtl::OString >** ppNonEncoded ); + virtual const void* GetEmbedFontData( ImplFontData* pFont, + const sal_Unicode* pUnicodes, + sal_Int32* pWidths, + FontSubsetInfo& rInfo, + long* pDataLen ); + virtual void FreeEmbedFontData( const void* pData, long nDataLen ); + virtual void GetGlyphWidths( ImplFontData* pFont, + bool bVertical, + std::vector< sal_Int32 >& rWidths, + std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ); + virtual BOOL GetGlyphBoundRect( long nIndex, Rectangle& ); + virtual BOOL GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& ); + virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ); + virtual void DrawServerFontLayout( const ServerFontLayout& ); + virtual void drawPixel( long nX, long nY ); + virtual void drawPixel( long nX, long nY, SalColor nSalColor ); + virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ); + virtual void drawRect( long nX, long nY, long nWidth, long nHeight ); + virtual void drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ); + virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); + virtual void drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32* pPoints, + PCONSTSALPOINT* pPtAry ); + virtual sal_Bool drawPolyLineBezier( ULONG nPoints, + const SalPoint* pPtAry, + const BYTE* pFlgAry ); + virtual sal_Bool drawPolygonBezier( ULONG nPoints, + const SalPoint* pPtAry, + const BYTE* pFlgAry ); + virtual sal_Bool drawPolyPolygonBezier( sal_uInt32 nPoly, + const sal_uInt32* pPoints, + const SalPoint* const* pPtAry, + const BYTE* const* pFlgAry ); + virtual void copyArea( long nDestX, + long nDestY, + long nSrcX, + long nSrcY, + long nSrcWidth, + long nSrcHeight, + USHORT nFlags ); + virtual void copyBits( const SalTwoRect* pPosAry, + SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nTransparentColor ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rTransparentBitmap ); + virtual void drawMask( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ); + virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); + virtual SalColor getPixel( long nX, long nY ); + virtual void invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ); + virtual void invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags ); + + virtual BOOL drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ); +}; + +#endif diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx new file mode 100644 index 000000000000..0cb090a5a0d5 --- /dev/null +++ b/vcl/unx/headless/svpinst.cxx @@ -0,0 +1,535 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpinst.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:49 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <unistd.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/poll.h> + +#include "svpinst.hxx" +#include "svpframe.hxx" +#include "svpdummies.hxx" +#include "svpvd.hxx" +#include "svpbmp.hxx" + +#include <vcl/salframe.hxx> +#include <vcl/svdata.hxx> +#include <vcl/salatype.hxx> +#include <vcl/saldatabasic.hxx> +#include <sal/types.h> + +// plugin factory function +extern "C" +{ + SAL_DLLPUBLIC_EXPORT SalInstance* create_SalInstance() + { + SvpSalInstance* pInstance = new SvpSalInstance(); + SalData* pSalData = new SalData(); + pSalData->m_pInstance = pInstance; + SetSalData( pSalData ); + return pInstance; + } +} + +SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL; + +SvpSalInstance::SvpSalInstance() +{ + m_aTimeout.tv_sec = 0; + m_aTimeout.tv_usec = 0; + m_nTimeoutMS = 0; + + m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1; + if (pipe (m_pTimeoutFDS) != -1) + { + // initialize 'wakeup' pipe. + int flags; + + // set close-on-exec descriptor flag. + if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1) + { + flags |= FD_CLOEXEC; + fcntl (m_pTimeoutFDS[0], F_SETFD, flags); + } + if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1) + { + flags |= FD_CLOEXEC; + fcntl (m_pTimeoutFDS[1], F_SETFD, flags); + } + + // set non-blocking I/O flag. + if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1) + { + flags |= O_NONBLOCK; + fcntl (m_pTimeoutFDS[0], F_SETFL, flags); + } + if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1) + { + flags |= O_NONBLOCK; + fcntl (m_pTimeoutFDS[1], F_SETFL, flags); + } + } + m_aEventGuard = osl_createMutex(); + if( s_pDefaultInstance == NULL ) + s_pDefaultInstance = this; +} + +SvpSalInstance::~SvpSalInstance() +{ + if( s_pDefaultInstance == this ) + s_pDefaultInstance = NULL; + + // close 'wakeup' pipe. + close (m_pTimeoutFDS[0]); + close (m_pTimeoutFDS[1]); + osl_destroyMutex( m_aEventGuard ); +} + +void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, USHORT nEvent ) +{ + if( osl_acquireMutex( m_aEventGuard ) ) + { + m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) ); + osl_releaseMutex( m_aEventGuard ); + } + Wakeup(); +} + +void SvpSalInstance::CancelEvent( const SalFrame* pFrame, void* pData, USHORT nEvent ) +{ + if( osl_acquireMutex( m_aEventGuard ) ) + { + if( ! m_aUserEvents.empty() ) + { + std::list< SalUserEvent >::iterator it = m_aUserEvents.begin(); + do + { + if( it->m_pFrame == pFrame && + it->m_pData == pData && + it->m_nEvent == nEvent ) + { + it = m_aUserEvents.erase( it ); + } + else + ++it; + } while( it != m_aUserEvents.end() ); + } + osl_releaseMutex( m_aEventGuard ); + } +} + +void SvpSalInstance::deregisterFrame( SalFrame* pFrame ) +{ + m_aFrames.remove( pFrame ); + + if( osl_acquireMutex( m_aEventGuard ) ) + { + // cancel outstanding events for this frame + if( ! m_aUserEvents.empty() ) + { + std::list< SalUserEvent >::iterator it = m_aUserEvents.begin(); + do + { + if( it->m_pFrame == pFrame ) + { + it = m_aUserEvents.erase( it ); + } + else + ++it; + } while( it != m_aUserEvents.end() ); + } + osl_releaseMutex( m_aEventGuard ); + } +} + +void SvpSalInstance::Wakeup() +{ + write (m_pTimeoutFDS[1], "", 1); +} + + +// -=-= timeval =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +inline int operator >= ( const timeval &t1, const timeval &t2 ) +{ + if( t1.tv_sec == t2.tv_sec ) + return t1.tv_usec >= t2.tv_usec; + return t1.tv_sec > t2.tv_sec; +} +inline timeval &operator += ( timeval &t1, ULONG t2 ) +{ + t1.tv_sec += t2 / 1000; + t1.tv_usec += t2 ? (t2 % 1000) * 1000 : 500; + if( t1.tv_usec > 1000000 ) + { + t1.tv_sec++; + t1.tv_usec -= 1000000; + } + return t1; +} +inline int operator > ( const timeval &t1, const timeval &t2 ) +{ + if( t1.tv_sec == t2.tv_sec ) + return t1.tv_usec > t2.tv_usec; + return t1.tv_sec > t2.tv_sec; +} + +bool SvpSalInstance::CheckTimeout( bool bExecuteTimers ) +{ + bool bRet = false; + if( m_aTimeout.tv_sec ) // timer is started + { + timeval aTimeOfDay; + gettimeofday( &aTimeOfDay, 0 ); + if( aTimeOfDay >= m_aTimeout ) + { + bRet = true; + if( bExecuteTimers ) + { + // timed out, update timeout + m_aTimeout = aTimeOfDay; + m_aTimeout += m_nTimeoutMS; + // notify + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->mpSalTimer ) + pSVData->mpSalTimer->CallCallback(); + } + } + } + return bRet; +} + +SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, ULONG nStyle ) +{ + return new SvpSalFrame( this, NULL, nStyle, pParent ); +} + +SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, ULONG nStyle ) +{ + return new SvpSalFrame( this, pParent, nStyle ); +} + +void SvpSalInstance::DestroyFrame( SalFrame* pFrame ) +{ + delete pFrame; +} + +SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData* ) +{ + return new SvpSalObject(); +} + +void SvpSalInstance::DestroyObject( SalObject* pObject ) +{ + delete pObject; +} + +SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics*, + long nDX, long nDY, + USHORT nBitCount, const SystemGraphicsData* ) +{ + SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount ); + pNew->SetSize( nDX, nDY ); + return pNew; +} + +void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice ) +{ + delete pDevice; +} + +SalSound* SvpSalInstance::CreateSalSound() +{ + return new SvpSalSound(); +} + +SalTimer* SvpSalInstance::CreateSalTimer() +{ + return new SvpSalTimer( this ); +} + +SalOpenGL* SvpSalInstance::CreateSalOpenGL( SalGraphics* ) +{ + return new SvpSalOpenGL(); +} + +SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus() +{ + return new SvpImeStatus(); +} + +SalSystem* SvpSalInstance::CreateSalSystem() +{ + return new SvpSalSystem(); +} + +SalBitmap* SvpSalInstance::CreateSalBitmap() +{ + return new SvpSalBitmap(); +} + +vos::IMutex* SvpSalInstance::GetYieldMutex() +{ + return &m_aYieldMutex; +} + +ULONG SvpSalInstance::ReleaseYieldMutex() +{ + if ( m_aYieldMutex.GetThreadId() == + NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + { + ULONG nCount = m_aYieldMutex.GetAcquireCount(); + ULONG n = nCount; + while ( n ) + { + m_aYieldMutex.release(); + n--; + } + + return nCount; + } + else + return 0; +} + +void SvpSalInstance::AcquireYieldMutex( ULONG nCount ) +{ + while ( nCount ) + { + m_aYieldMutex.acquire(); + nCount--; + } +} + +void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) +{ + // first, check for already queued events. + + // release yield mutex + std::list< SalUserEvent > aEvents; + ULONG nAcquireCount = ReleaseYieldMutex(); + if( osl_acquireMutex( m_aEventGuard ) ) + { + if( ! m_aUserEvents.empty() ) + { + if( bHandleAllCurrentEvents ) + { + aEvents = m_aUserEvents; + m_aUserEvents.clear(); + } + else + { + aEvents.push_back( m_aUserEvents.front() ); + m_aUserEvents.pop_front(); + } + } + osl_releaseMutex( m_aEventGuard ); + } + // acquire yield mutex again + AcquireYieldMutex( nAcquireCount ); + + bool bEvent = !aEvents.empty(); + if( bEvent ) + { + for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it ) + { + it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData ); + if( it->m_nEvent == SALEVENT_RESIZE ) + { + // this would be a good time to post a paint + const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame); + pSvpFrame->PostPaint(); + } + } + } + + bEvent = CheckTimeout() || bEvent; + + if (bWait && ! bEvent ) + { + int nTimeoutMS = 0; + if (m_aTimeout.tv_sec) // Timer is started. + { + timeval Timeout; + // determine remaining timeout. + gettimeofday (&Timeout, 0); + nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000 + - Timeout.tv_sec*1000 - Timeout.tv_usec/1000; + if( nTimeoutMS < 0 ) + nTimeoutMS = 0; + } + else + nTimeoutMS = -1; // wait until something happens + + // release yield mutex + nAcquireCount = ReleaseYieldMutex(); + // poll + struct pollfd aPoll; + aPoll.fd = m_pTimeoutFDS[0]; + aPoll.events = POLLIN; + aPoll.revents = 0; + poll( &aPoll, 1, nTimeoutMS ); + + // acquire yield mutex again + AcquireYieldMutex( nAcquireCount ); + + // clean up pipe + if( (aPoll.revents & POLLIN) != 0 ) + { + int buffer; + while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0) + continue; + } + } +} + +bool SvpSalInstance::AnyInput( USHORT nType ) +{ + if( (nType & INPUT_TIMER) != 0 ) + return CheckTimeout( false ); + return false; +} + +SalMenu* SvpSalInstance::CreateMenu( BOOL ) +{ + return NULL; +} + +void SvpSalInstance::DestroyMenu( SalMenu* ) +{ +} + +SalMenuItem* SvpSalInstance::CreateMenuItem( const SalItemParams* ) +{ + return NULL; +} + +void SvpSalInstance::DestroyMenuItem( SalMenuItem* ) +{ +} + +SalSession* SvpSalInstance::CreateSalSession() +{ + return NULL; +} + +void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ) +{ + rReturnedBytes = 1; + rReturnedType = AsciiCString; + return const_cast<char*>(""); +} + +// ------------------------------------------------------------------------- +// +// SalYieldMutex +// +// ------------------------------------------------------------------------- + +SvpSalYieldMutex::SvpSalYieldMutex() +{ + mnCount = 0; + mnThreadId = 0; +} + +void SvpSalYieldMutex::acquire() +{ + OMutex::acquire(); + mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnCount++; +} + +void SvpSalYieldMutex::release() +{ + if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + { + if ( mnCount == 1 ) + mnThreadId = 0; + mnCount--; + } + OMutex::release(); +} + +sal_Bool SvpSalYieldMutex::tryToAcquire() +{ + if ( OMutex::tryToAcquire() ) + { + mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnCount++; + return sal_True; + } + else + return sal_False; +} + +// --------------- +// - SalTimer - +// --------------- + +void SvpSalInstance::StopTimer() +{ + m_aTimeout.tv_sec = 0; + m_aTimeout.tv_usec = 0; + m_nTimeoutMS = 0; +} + +void SvpSalInstance::StartTimer( ULONG nMS ) +{ + timeval Timeout (m_aTimeout); // previous timeout. + gettimeofday (&m_aTimeout, 0); + + m_nTimeoutMS = nMS; + m_aTimeout += m_nTimeoutMS; + + if ((Timeout > m_aTimeout) || (Timeout.tv_sec == 0)) + { + // Wakeup from previous timeout (or stopped timer). + Wakeup(); + } +} + +SvpSalTimer::~SvpSalTimer() +{ +} + +void SvpSalTimer::Stop() +{ + m_pInstance->StopTimer(); +} + +void SvpSalTimer::Start( ULONG nMS ) +{ + m_pInstance->StartTimer( nMS ); +} + diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx new file mode 100644 index 000000000000..86f17de00259 --- /dev/null +++ b/vcl/unx/headless/svpinst.hxx @@ -0,0 +1,205 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpinst.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:27:59 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_SALINST_HXX +#define _SVP_SALINST_HXX + +#include <vcl/salinst.hxx> +#include <vcl/salwtype.hxx> +#include <vcl/saltimer.hxx> +#include <vos/mutex.hxx> +#include <vos/thread.hxx> + +#include <list> + +#define VIRTUAL_DESKTOP_WIDTH 1024 +#define VIRTUAL_DESKTOP_HEIGHT 768 +#define VIRTUAL_DESKTOP_DEPTH 24 + +// ------------------------------------------------------------------------- +// SalYieldMutex +// ------------------------------------------------------------------------- + +class SvpSalYieldMutex : public NAMESPACE_VOS(OMutex) +{ +protected: + ULONG mnCount; + NAMESPACE_VOS(OThread)::TThreadIdentifier mnThreadId; + +public: + SvpSalYieldMutex(); + + virtual void acquire(); + virtual void release(); + virtual sal_Bool tryToAcquire(); + + ULONG GetAcquireCount() const { return mnCount; } + NAMESPACE_VOS(OThread)::TThreadIdentifier GetThreadId() const { return mnThreadId; } +}; + +// --------------- +// - SalTimer - +// --------------- +class SvpSalInstance; +class SvpSalTimer : public SalTimer +{ + SvpSalInstance* m_pInstance; +public: + SvpSalTimer( SvpSalInstance* pInstance ) : m_pInstance( pInstance ) {} + virtual ~SvpSalTimer(); + + // overload all pure virtual methods + virtual void Start( ULONG nMS ); + virtual void Stop(); +}; + +// --------------- +// - SalInstance - +// --------------- +class SvpSalFrame; +class SvpSalInstance : public SalInstance +{ + timeval m_aTimeout; + ULONG m_nTimeoutMS; + int m_pTimeoutFDS[2]; + SvpSalYieldMutex m_aYieldMutex; + + // internal event queue + struct SalUserEvent + { + const SalFrame* m_pFrame; + void* m_pData; + USHORT m_nEvent; + + SalUserEvent( const SalFrame* pFrame, void* pData, USHORT nEvent = SALEVENT_USEREVENT ) + : m_pFrame( pFrame ), + m_pData( pData ), + m_nEvent( nEvent ) + {} + }; + + oslMutex m_aEventGuard; + std::list< SalUserEvent > m_aUserEvents; + + std::list< SalFrame* > m_aFrames; +public: + static SvpSalInstance* s_pDefaultInstance; + + SvpSalInstance(); + virtual ~SvpSalInstance(); + + void PostEvent( const SalFrame* pFrame, void* pData, USHORT nEvent ); + void CancelEvent( const SalFrame* pFrame, void* pData, USHORT nEvent ); + + void StartTimer( ULONG nMS ); + void StopTimer(); + void Wakeup(); + + void registerFrame( SalFrame* pFrame ) { m_aFrames.push_back( pFrame ); } + void deregisterFrame( SalFrame* pFrame ); + const std::list< SalFrame* >& getFrames() const { return m_aFrames; } + + bool CheckTimeout( bool bExecuteTimers = true ); + + // Frame + virtual SalFrame* CreateChildFrame( SystemParentData* pParent, ULONG nStyle ); + virtual SalFrame* CreateFrame( SalFrame* pParent, ULONG nStyle ); + virtual void DestroyFrame( SalFrame* pFrame ); + + // Object (System Child Window) + virtual SalObject* CreateObject( SalFrame* pParent, SystemWindowData* pWindowData ); + virtual void DestroyObject( SalObject* pObject ); + + // VirtualDevice + // nDX and nDY in Pixel + // nBitCount: 0 == Default(=as window) / 1 == Mono + // pData allows for using a system dependent graphics or device context + virtual SalVirtualDevice* CreateVirtualDevice( SalGraphics* pGraphics, + long nDX, long nDY, + USHORT nBitCount, const SystemGraphicsData *pData = NULL ); + virtual void DestroyVirtualDevice( SalVirtualDevice* pDevice ); + + // Printer + // pSetupData->mpDriverData can be 0 + // pSetupData must be updatet with the current + // JobSetup + virtual SalInfoPrinter* CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, + ImplJobSetup* pSetupData ); + virtual void DestroyInfoPrinter( SalInfoPrinter* pPrinter ); + virtual SalPrinter* CreatePrinter( SalInfoPrinter* pInfoPrinter ); + virtual void DestroyPrinter( SalPrinter* pPrinter ); + + virtual void GetPrinterQueueInfo( ImplPrnQueueList* pList ); + virtual void GetPrinterQueueState( SalPrinterQueueInfo* pInfo ); + virtual void DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ); + virtual String GetDefaultPrinter(); + + // SalSound + virtual SalSound* CreateSalSound(); + // SalTimer + virtual SalTimer* CreateSalTimer(); + // SalOpenGL + virtual SalOpenGL* CreateSalOpenGL( SalGraphics* pGraphics ); + // SalI18NImeStatus + virtual SalI18NImeStatus* CreateI18NImeStatus(); + // SalSystem + virtual SalSystem* CreateSalSystem(); + // SalBitmap + virtual SalBitmap* CreateSalBitmap(); + + // YieldMutex + virtual vos::IMutex* GetYieldMutex(); + virtual ULONG ReleaseYieldMutex(); + virtual void AcquireYieldMutex( ULONG nCount ); + + // wait next event and dispatch + // must returned by UserEvent (SalFrame::PostEvent) + // and timer + virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); + virtual bool AnyInput( USHORT nType ); + + // Menues + virtual SalMenu* CreateMenu( BOOL bMenuBar ); + virtual void DestroyMenu( SalMenu* pMenu); + virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); + virtual void DestroyMenuItem( SalMenuItem* pItem ); + + // may return NULL to disable session management + virtual SalSession* CreateSalSession(); + + virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); +}; + +#endif // _SV_SALINST_HXX diff --git a/vcl/unx/headless/svpprn.cxx b/vcl/unx/headless/svpprn.cxx new file mode 100644 index 000000000000..ff3dd9447751 --- /dev/null +++ b/vcl/unx/headless/svpprn.cxx @@ -0,0 +1,1109 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpprn.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:28:10 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <vcl/svapp.hxx> +#include <vcl/jobset.h> +#include "svpprn.hxx" +#include <vcl/print.h> +#include <vcl/salptype.hxx> +#include <vcl/timer.hxx> +#include "svppspgraphics.hxx" +#include "svpinst.hxx" + +#include <psprint/printerinfomanager.hxx> + +#include <unistd.h> +#include <sys/stat.h> +#include <sys/wait.h> + +using namespace psp; +using namespace rtl; + +/* + * static helpers + */ + +static String getPdfDir( const PrinterInfo& rInfo ) +{ + String aDir; + sal_Int32 nIndex = 0; + while( nIndex != -1 ) + { + OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) ); + if( ! aToken.compareToAscii( "pdf=", 4 ) ) + { + sal_Int32 nPos = 0; + aDir = aToken.getToken( 1, '=', nPos ); + if( ! aDir.Len() ) + aDir = String( ByteString( getenv( "HOME" ) ), osl_getThreadTextEncoding() ); + break; + } + } + return aDir; +} + +inline int PtTo10Mu( int nPoints ) { return (int)((((double)nPoints)*35.27777778)+0.5); } + +inline int TenMuToPt( int nUnits ) { return (int)((((double)nUnits)/35.27777778)+0.5); } + +static struct +{ + int width; + int height; + const char* name; + int namelength; + Paper paper; +} aPaperTab[] = +{ + { 29700, 42000, "A3", 2, PAPER_A3 }, + { 21000, 29700, "A4", 2, PAPER_A4 }, + { 14800, 21000, "A5", 2, PAPER_A5 }, + { 25000, 35300, "B4", 2, PAPER_B4 }, + { 17600, 25000, "B5", 2, PAPER_B5 }, + { 21600, 27900, "Letter", 6, PAPER_LETTER }, + { 21600, 35600, "Legal", 5, PAPER_LEGAL }, + { 27900, 43100, "Tabloid", 7, PAPER_TABLOID }, + { 0, 0, "USER", 4, PAPER_USER } +}; + +static Paper getPaperType( const String& rPaperName ) +{ + ByteString aPaper( rPaperName, RTL_TEXTENCODING_ISO_8859_1 ); + for( unsigned int i = 0; i < sizeof( aPaperTab )/sizeof( aPaperTab[0] ); i++ ) + { + if( ! strcmp( aPaper.GetBuffer(), aPaperTab[i].name ) ) + return aPaperTab[i].paper; + } + return PAPER_USER; +} + +static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData ) +{ + pJobSetup->meOrientation = (Orientation)(rData.m_eOrientation == orientation::Landscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT); + + // copy page size + String aPaper; + int width, height; + + rData.m_aContext.getPageSize( aPaper, width, height ); + pJobSetup->mePaperFormat = getPaperType( aPaper ); + pJobSetup->mnPaperWidth = 0; + pJobSetup->mnPaperHeight = 0; + if( pJobSetup->mePaperFormat == PAPER_USER ) + { + // transform to 100dth mm + width = PtTo10Mu( width ); + height = PtTo10Mu( height ); + + if( rData.m_eOrientation == psp::orientation::Portrait ) + { + pJobSetup->mnPaperWidth = width; + pJobSetup->mnPaperHeight= height; + } + else + { + pJobSetup->mnPaperWidth = height; + pJobSetup->mnPaperHeight= width; + } + } + + // copy input slot + const PPDKey* pKey = NULL; + const PPDValue* pValue = NULL; + + pJobSetup->mnPaperBin = 0xffff; + if( rData.m_pParser ) + pKey = rData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ); + if( pKey ) + pValue = rData.m_aContext.getValue( pKey ); + if( pKey && pValue ) + { + for( pJobSetup->mnPaperBin = 0; + pValue != pKey->getValue( pJobSetup->mnPaperBin ) && + pJobSetup->mnPaperBin < pKey->countValues(); + pJobSetup->mnPaperBin++ ) + ; + if( pJobSetup->mnPaperBin >= pKey->countValues() || pValue == pKey->getDefaultValue() ) + pJobSetup->mnPaperBin = 0xffff; + } + + + // copy the whole context + if( pJobSetup->mpDriverData ) + rtl_freeMemory( pJobSetup->mpDriverData ); + + int nBytes; + void* pBuffer = NULL; + if( rData.getStreamBuffer( pBuffer, nBytes ) ) + { + pJobSetup->mnDriverDataLen = nBytes; + pJobSetup->mpDriverData = (BYTE*)pBuffer; + } + else + { + pJobSetup->mnDriverDataLen = 0; + pJobSetup->mpDriverData = NULL; + } +} + +static bool passFileToCommandLine( const String& rFilename, const String& rCommandLine, bool bRemoveFile = true ) +{ + bool bSuccess = false; + + rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); + ByteString aCmdLine( rCommandLine, aEncoding ); + ByteString aFilename( rFilename, aEncoding ); + + bool bPipe = aCmdLine.Search( "(TMP)" ) != STRING_NOTFOUND ? false : true; + + // setup command line for exec + if( ! bPipe ) + while( aCmdLine.SearchAndReplace( "(TMP)", aFilename ) != STRING_NOTFOUND ) + ; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "%s commandline: \"%s\"\n", + bPipe ? "piping to" : "executing", + aCmdLine.GetBuffer() ); + struct stat aStat; + if( stat( aFilename.GetBuffer(), &aStat ) ) + fprintf( stderr, "stat( %s ) failed\n", aFilename.GetBuffer() ); + fprintf( stderr, "Tmp file %s has modes: %o\n", aFilename.GetBuffer(), aStat.st_mode ); +#endif + const char* argv[4]; + if( ! ( argv[ 0 ] = getenv( "SHELL" ) ) ) + argv[ 0 ] = "/bin/sh"; + argv[ 1 ] = "-c"; + argv[ 2 ] = aCmdLine.GetBuffer(); + argv[ 3 ] = 0; + + bool bHavePipes = false; + int pid, fd[2]; + + if( bPipe ) + bHavePipes = pipe( fd ) ? false : true; + if( ( pid = fork() ) > 0 ) + { + if( bPipe && bHavePipes ) + { + close( fd[0] ); + char aBuffer[ 2048 ]; + FILE* fp = fopen( aFilename.GetBuffer(), "r" ); + while( fp && ! feof( fp ) ) + { + int nBytes = fread( aBuffer, 1, sizeof( aBuffer ), fp ); + if( nBytes ) + write( fd[ 1 ], aBuffer, nBytes ); + } + fclose( fp ); + close( fd[ 1 ] ); + } + int status = 0; + waitpid( pid, &status, 0 ); + if( ! status ) + bSuccess = true; + } + else if( ! pid ) + { + if( bPipe && bHavePipes ) + { + close( fd[1] ); + if( fd[0] != STDIN_FILENO ) // not probable, but who knows :) + dup2( fd[0], STDIN_FILENO ); + } + execv( argv[0], const_cast<char**>(argv) ); + fprintf( stderr, "failed to execute \"%s\"\n", aCmdLine.GetBuffer() ); + _exit( 1 ); + } + else + fprintf( stderr, "failed to fork\n" ); + + // clean up the mess + if( bRemoveFile ) + unlink( aFilename.GetBuffer() ); + + return bSuccess; +} + +static bool sendAFax( const String& rFaxNumber, const String& rFileName, const String& rCommand ) +{ + std::list< OUString > aFaxNumbers; + + if( ! rFaxNumber.Len() ) + return false; + + sal_Int32 nIndex = 0; + OUString aFaxes( rFaxNumber ); + OUString aBeginToken( RTL_CONSTASCII_USTRINGPARAM("<Fax#>") ); + OUString aEndToken( RTL_CONSTASCII_USTRINGPARAM("</Fax#>") ); + while( nIndex != -1 ) + { + nIndex = aFaxes.indexOf( aBeginToken, nIndex ); + if( nIndex != -1 ) + { + sal_Int32 nBegin = nIndex + aBeginToken.getLength(); + nIndex = aFaxes.indexOf( aEndToken, nIndex ); + if( nIndex != -1 ) + { + aFaxNumbers.push_back( aFaxes.copy( nBegin, nIndex-nBegin ) ); + nIndex += aEndToken.getLength(); + } + } + } + + bool bSuccess = true; + if( aFaxNumbers.begin() != aFaxNumbers.end() ) + { + while( aFaxNumbers.begin() != aFaxNumbers.end() && bSuccess ) + { + String aCmdLine( rCommand ); + String aFaxNumber( aFaxNumbers.front() ); + aFaxNumbers.pop_front(); + while( aCmdLine.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "(PHONE)" ) ), aFaxNumber ) != STRING_NOTFOUND ) + ; +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "sending fax to \"%s\"\n", OUStringToOString( aFaxNumber, osl_getThreadTextEncoding() ).getStr() ); +#endif + bSuccess = passFileToCommandLine( rFileName, aCmdLine, false ); + } + } + else + bSuccess = false; + + // clean up temp file + unlink( ByteString( rFileName, osl_getThreadTextEncoding() ).GetBuffer() ); + + return bSuccess; +} + +static bool createPdf( const String& rToFile, const String& rFromFile, const String& rCommandLine ) +{ + String aCommandLine( rCommandLine ); + while( aCommandLine.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "(OUTFILE)" ) ), rToFile ) != STRING_NOTFOUND ) + ; + return passFileToCommandLine( rFromFile, aCommandLine ); +} + +/* + * SalInstance + */ + +// ----------------------------------------------------------------------- + +SalInfoPrinter* SvpSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, + ImplJobSetup* pJobSetup ) +{ + // create and initialize SalInfoPrinter + PspSalInfoPrinter* pPrinter = new PspSalInfoPrinter; + + if( pJobSetup ) + { + PrinterInfoManager& rManager( PrinterInfoManager::get() ); + PrinterInfo aInfo( rManager.getPrinterInfo( pQueueInfo->maPrinterName ) ); + pPrinter->m_aJobData = aInfo; + pPrinter->m_aPrinterGfx.Init( pPrinter->m_aJobData ); + + if( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo ); + + pJobSetup->mnSystem = JOBSETUP_SYSTEM_UNIX; + pJobSetup->maPrinterName = pQueueInfo->maPrinterName; + pJobSetup->maDriver = aInfo.m_aDriverName; + copyJobDataToJobSetup( pJobSetup, aInfo ); + + // set/clear backwards compatibility flag + bool bStrictSO52Compatibility = false; + std::hash_map<rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator compat_it = + pJobSetup->maValueMap.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StrictSO52Compatibility" ) ) ); + if( compat_it != pJobSetup->maValueMap.end() ) + { + if( compat_it->second.equalsIgnoreAsciiCaseAscii( "true" ) ) + bStrictSO52Compatibility = true; + } + pPrinter->m_aPrinterGfx.setStrictSO52Compatibility( bStrictSO52Compatibility ); + } + + + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SvpSalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ----------------------------------------------------------------------- + +SalPrinter* SvpSalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) +{ + // create and initialize SalPrinter + PspSalPrinter* pPrinter = new PspSalPrinter( pInfoPrinter ); + pPrinter->m_aJobData = static_cast<PspSalInfoPrinter*>(pInfoPrinter)->m_aJobData; + + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SvpSalInstance::DestroyPrinter( SalPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ----------------------------------------------------------------------- + +void SvpSalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList ) +{ + PrinterInfoManager& rManager( PrinterInfoManager::get() ); + static const char* pNoSyncDetection = getenv( "SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION" ); + if( ! pNoSyncDetection || ! *pNoSyncDetection ) + { + // #i62663# synchronize possible asynchronouse printer detection now + rManager.checkPrintersChanged( true ); + } + ::std::list< OUString > aPrinters; + rManager.listPrinters( aPrinters ); + + for( ::std::list< OUString >::iterator it = aPrinters.begin(); it != aPrinters.end(); ++it ) + { + const PrinterInfo& rInfo( rManager.getPrinterInfo( *it ) ); + // Neuen Eintrag anlegen + SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; + pInfo->maPrinterName = *it; + pInfo->maDriver = rInfo.m_aDriverName; + pInfo->maLocation = rInfo.m_aLocation; + pInfo->maComment = rInfo.m_aComment; + pInfo->mpSysData = NULL; + + sal_Int32 nIndex = 0; + while( nIndex != -1 ) + { + String aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) ); + if( aToken.CompareToAscii( "pdf=", 4 ) == COMPARE_EQUAL ) + { + pInfo->maLocation = getPdfDir( rInfo ); + break; + } + } + + pList->Add( pInfo ); + } +} + +// ----------------------------------------------------------------------- + +void SvpSalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) +{ + delete pInfo; +} + +// ----------------------------------------------------------------------- + +void SvpSalInstance::GetPrinterQueueState( SalPrinterQueueInfo* ) +{ +} + +// ----------------------------------------------------------------------- + +String SvpSalInstance::GetDefaultPrinter() +{ + PrinterInfoManager& rManager( PrinterInfoManager::get() ); + return rManager.getDefaultPrinter(); +} + +// ======================================================================= + +PspSalInfoPrinter::PspSalInfoPrinter() +{ + m_pGraphics = NULL; + m_bPapersInit = false; +} + +// ----------------------------------------------------------------------- + +PspSalInfoPrinter::~PspSalInfoPrinter() +{ + if( m_pGraphics ) + { + delete m_pGraphics; + m_pGraphics = NULL; + } +} + +// ----------------------------------------------------------------------- + +void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* ) +{ + m_aPaperFormats.clear(); + m_bPapersInit = true; + + if( m_aJobData.m_pParser ) + { + const PPDKey* pKey = m_aJobData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); + if( pKey ) + { + int nValues = pKey->countValues(); + for( int i = 0; i < nValues; i++ ) + { + const PPDValue* pValue = pKey->getValue( i ); + vcl::PaperInfo aInfo; + aInfo.m_aPaperName = pValue->m_aOptionTranslation; + if( ! aInfo.m_aPaperName.Len() ) + aInfo.m_aPaperName = pValue->m_aOption; + int nWidth = 0, nHeight = 0; + m_aJobData.m_pParser->getPaperDimension( pValue->m_aOption, nWidth, nHeight ); + aInfo.m_nPaperWidth = (unsigned long)((PtTo10Mu( nWidth )+50)/100); + aInfo.m_nPaperHeight = (unsigned long)((PtTo10Mu( nHeight )+50)/100); + m_aPaperFormats.push_back( aInfo ); + } + } + } +} + +// ----------------------------------------------------------------------- + +DuplexMode PspSalInfoPrinter::GetDuplexMode( const ImplJobSetup* pJobSetup ) +{ + DuplexMode aRet = DUPLEX_UNKNOWN; + PrinterInfo aInfo( PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ) ); + if ( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aInfo ); + if( aInfo.m_pParser ) + { + const PPDKey * pKey = aInfo.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) ); + if( pKey ) + { + const PPDValue* pVal = aInfo.m_aContext.getValue( pKey ); + if( pVal && ( + pVal->m_aOption.EqualsIgnoreCaseAscii( "None" ) || + pVal->m_aOption.EqualsIgnoreCaseAscii( "Simplex", 0, 7 ) + ) ) + { + aRet = DUPLEX_OFF; + } + else + aRet = DUPLEX_ON; + } + } + return aRet; +} + +// ----------------------------------------------------------------------- + +int PspSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* ) +{ + return 900; +} + +// ----------------------------------------------------------------------- + +SalGraphics* PspSalInfoPrinter::GetGraphics() +{ + // return a valid pointer only once + // the reasoning behind this is that we could have different + // SalGraphics that can run in multiple threads + // (future plans) + SalGraphics* pRet = NULL; + if( ! m_pGraphics ) + { + m_pGraphics = new PspGraphics( &m_aJobData, &m_aPrinterGfx, NULL, false, this ); + m_pGraphics->SetLayout( 0 ); + pRet = m_pGraphics; + } + return pRet; +} + +// ----------------------------------------------------------------------- + +void PspSalInfoPrinter::ReleaseGraphics( SalGraphics* pGraphics ) +{ + if( pGraphics == m_pGraphics ) + { + delete pGraphics; + m_pGraphics = NULL; + } + return; +} + +// ----------------------------------------------------------------------- + +BOOL PspSalInfoPrinter::Setup( SalFrame*, ImplJobSetup* ) +{ + return FALSE; +} + +// ----------------------------------------------------------------------- + +// This function gets the driver data and puts it into pJobSetup +// If pJobSetup->mpDriverData is NOT NULL, then the independend +// data should be merged into the driver data +// If pJobSetup->mpDriverData IS NULL, then the driver defaults +// should be merged into the independent data +BOOL PspSalInfoPrinter::SetPrinterData( ImplJobSetup* pJobSetup ) +{ + if( pJobSetup->mpDriverData ) + return SetData( ~0, pJobSetup ); + + copyJobDataToJobSetup( pJobSetup, m_aJobData ); + + // set/clear backwards compatibility flag + bool bStrictSO52Compatibility = false; + std::hash_map<rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator compat_it = + pJobSetup->maValueMap.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StrictSO52Compatibility" ) ) ); + if( compat_it != pJobSetup->maValueMap.end() ) + { + if( compat_it->second.equalsIgnoreAsciiCaseAscii( "true" ) ) + bStrictSO52Compatibility = true; + } + m_aPrinterGfx.setStrictSO52Compatibility( bStrictSO52Compatibility ); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +// This function merges the independ driver data +// and sets the new independ data in pJobSetup +// Only the data must be changed, where the bit +// in nGetDataFlags is set +BOOL PspSalInfoPrinter::SetData( + ULONG nSetDataFlags, + ImplJobSetup* pJobSetup ) +{ + JobData aData; + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + + if( aData.m_pParser ) + { + const PPDKey* pKey; + const PPDValue* pValue; + + // merge papersize if necessary + if( nSetDataFlags & SAL_JOBSET_PAPERSIZE ) + { + int nWidth, nHeight; + if( pJobSetup->meOrientation == ORIENTATION_PORTRAIT ) + { + nWidth = pJobSetup->mnPaperWidth; + nHeight = pJobSetup->mnPaperHeight; + } + else + { + nWidth = pJobSetup->mnPaperHeight; + nHeight = pJobSetup->mnPaperWidth; + } + String aPaper; + +#ifdef MACOSX + // For Mac OS X, many printers are directly attached + // USB/Serial printers with a stripped-down PPD that gives us + // problems. We need to do PS->PDF conversion for these printers + // but they are not able to handle multiple page sizes in the same + // document at all, since we must pass -o media=... to them to get + // a good printout. + // So, we must find a match between the paper size from OOo and what + // the PPD of the printer has, and pass that paper size to -o media=... + // If a match cannot be found (ie the paper size from Format->Page is + // nowhere near anything in the PPD), we default to what has been + // chosen in File->Print->Properties. + // + // For printers capable of directly accepting PostScript data, none + // of this occurs and we default to the normal OOo behavior. + const PPDKey *pCupsFilterKey; + const PPDValue *pCupsFilterValue; + BOOL bIsCUPSPrinter = TRUE; + + // Printers that need PS->PDF conversion have a "cupsFilter" key and + // a value of "application/pdf" in that key + pCupsFilterKey = aData.m_pParser->getKey( String(RTL_CONSTASCII_USTRINGPARAM("cupsFilter")) ); + pCupsFilterValue = pCupsFilterKey != NULL ? aData.m_aContext.getValue( pCupsFilterKey ) : NULL; + if ( pCupsFilterValue ) + { + // PPD had a cupsFilter key, check for PS->PDF conversion requirement + ByteString aCupsFilterString( pCupsFilterValue->m_aOption, RTL_TEXTENCODING_ISO_8859_1 ); + if ( aCupsFilterString.Search("application/pdf") == 0 ) + bIsCUPSPrinter = FALSE; + } + else + bIsCUPSPrinter = FALSE; + + if ( TRUE == bIsCUPSPrinter ) + { + // If its a directly attached printer, with a + // stripped down PPD (most OS X printers are) always + // match the paper size. + aPaper = aData.m_pParser->matchPaper( + TenMuToPt( pJobSetup->mnPaperWidth ), + TenMuToPt( pJobSetup->mnPaperHeight ) ); + } + else +#endif + { + if( pJobSetup->mePaperFormat == PAPER_USER ) + aPaper = aData.m_pParser->matchPaper( + TenMuToPt( pJobSetup->mnPaperWidth ), + TenMuToPt( pJobSetup->mnPaperHeight ) ); + else + aPaper = String( ByteString( aPaperTab[ pJobSetup->mePaperFormat ].name ), RTL_TEXTENCODING_ISO_8859_1 ); + } + pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); + pValue = pKey ? pKey->getValue( aPaper ) : NULL; + if( ! ( pKey && pValue && aData.m_aContext.setValue( pKey, pValue, false ) == pValue ) ) + return FALSE; + } + + // merge paperbin if necessary + if( nSetDataFlags & SAL_JOBSET_PAPERBIN ) + { + pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ); + if( pKey ) + { + int nPaperBin = pJobSetup->mnPaperBin; + if( nPaperBin == 0xffff ) + pValue = pKey->getDefaultValue(); + else + pValue = pKey->getValue( pJobSetup->mnPaperBin ); + + // may fail due to constraints; + // real paper bin is copied back to jobsetup in that case + aData.m_aContext.setValue( pKey, pValue ); + } + // if printer has no InputSlot key simply ignore this setting + // (e.g. SGENPRT has no InputSlot) + } + + // merge orientation if necessary + if( nSetDataFlags & SAL_JOBSET_ORIENTATION ) + aData.m_eOrientation = pJobSetup->meOrientation == ORIENTATION_LANDSCAPE ? orientation::Landscape : orientation::Portrait; + + m_aJobData = aData; + copyJobDataToJobSetup( pJobSetup, aData ); + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void PspSalInfoPrinter::GetPageInfo( + const ImplJobSetup* pJobSetup, + long& rOutWidth, long& rOutHeight, + long& rPageOffX, long& rPageOffY, + long& rPageWidth, long& rPageHeight ) +{ + if( ! pJobSetup ) + return; + + JobData aData; + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + + // get the selected page size + if( aData.m_pParser ) + { + + String aPaper; + int width, height; + int left = 0, top = 0, right = 0, bottom = 0; + int nDPI = aData.m_aContext.getRenderResolution(); + + + if( aData.m_eOrientation == psp::orientation::Portrait ) + { + aData.m_aContext.getPageSize( aPaper, width, height ); + aData.m_pParser->getMargins( aPaper, left, right, top, bottom ); + } + else + { + aData.m_aContext.getPageSize( aPaper, height, width ); + aData.m_pParser->getMargins( aPaper, top, bottom, right, left ); + } + + rPageWidth = width * nDPI / 72; + rPageHeight = height * nDPI / 72; + rPageOffX = left * nDPI / 72; + rPageOffY = top * nDPI / 72; + rOutWidth = ( width - left - right ) * nDPI / 72; + rOutHeight = ( height - top - bottom ) * nDPI / 72; + } +} + +// ----------------------------------------------------------------------- + +ULONG PspSalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup ) +{ + if( ! pJobSetup ) + return 0; + + JobData aData; + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + + const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL; + return pKey ? pKey->countValues() : 0; +} + +// ----------------------------------------------------------------------- + +String PspSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, ULONG nPaperBin ) +{ + JobData aData; + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + + String aRet; + if( aData.m_pParser ) + { + const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL; + if( nPaperBin == 0xffff || ! pKey ) + aRet = aData.m_pParser->getDefaultInputSlot(); + else + { + const PPDValue* pValue = pKey->getValue( nPaperBin ); + if( pValue ) + aRet = pValue->m_aOptionTranslation.Len() ? pValue->m_aOptionTranslation : pValue->m_aOption; + } + } + + return aRet; +} + +// ----------------------------------------------------------------------- + +ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT nType ) +{ + switch( nType ) + { + case PRINTER_CAPABILITIES_SUPPORTDIALOG: + return 1; + case PRINTER_CAPABILITIES_COPIES: + return 0xffff; + case PRINTER_CAPABILITIES_COLLATECOPIES: + return 0; + case PRINTER_CAPABILITIES_SETORIENTATION: + return 1; + case PRINTER_CAPABILITIES_SETPAPERBIN: + return 1; + case PRINTER_CAPABILITIES_SETPAPERSIZE: + return 1; + case PRINTER_CAPABILITIES_SETPAPER: + return 0; + case PRINTER_CAPABILITIES_FAX: + { + PrinterInfoManager& rManager = PrinterInfoManager::get(); + PrinterInfo aInfo( rManager.getPrinterInfo( pJobSetup->maPrinterName ) ); + String aFeatures( aInfo.m_aFeatures ); + int nTokenCount = aFeatures.GetTokenCount( ',' ); + for( int i = 0; i < nTokenCount; i++ ) + { + if( aFeatures.GetToken( i ).CompareToAscii( "fax", 3 ) == COMPARE_EQUAL ) + return 1; + } + return 0; + } + case PRINTER_CAPABILITIES_PDF: + { + PrinterInfoManager& rManager = PrinterInfoManager::get(); + PrinterInfo aInfo( rManager.getPrinterInfo( pJobSetup->maPrinterName ) ); + String aFeatures( aInfo.m_aFeatures ); + int nTokenCount = aFeatures.GetTokenCount( ',' ); + for( int i = 0; i < nTokenCount; i++ ) + { + if( aFeatures.GetToken( i ).CompareToAscii( "pdf=", 4 ) == COMPARE_EQUAL ) + return 1; + } + return 0; + } + default: break; + }; + return 0; +} + +// ======================================================================= + +/* + * SalPrinter + */ + +PspSalPrinter::PspSalPrinter( SalInfoPrinter* pInfoPrinter ) + : m_bFax( false ), + m_bPdf( false ), + m_bSwallowFaxNo( false ), + m_pGraphics( NULL ), + m_nCopies( 1 ), + m_pInfoPrinter( pInfoPrinter ) +{ +} + +// ----------------------------------------------------------------------- + +PspSalPrinter::~PspSalPrinter() +{ +} + +// ----------------------------------------------------------------------- + +static String getTmpName() +{ + rtl::OUString aTmp, aSys; + osl_createTempFile( NULL, NULL, &aTmp.pData ); + osl_getSystemPathFromFileURL( aTmp.pData, &aSys.pData ); + + return aSys; +} + +BOOL PspSalPrinter::StartJob( + const XubString* pFileName, + const XubString& rJobName, + const XubString& rAppName, + ULONG nCopies, BOOL /*bCollate*/, + ImplJobSetup* pJobSetup ) +{ + vcl_sal::PrinterUpdate::jobStarted(); + + m_bFax = false; + m_bPdf = false; + m_aFileName = pFileName ? *pFileName : String(); + m_aTmpFile = String(); + m_nCopies = nCopies; + + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData ); + if( m_nCopies > 1 ) + // in case user did not do anything (m_nCopies=1) + // take the default from jobsetup + m_aJobData.m_nCopies = m_nCopies; + + // check wether this printer is configured as fax + int nMode = 0; + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + sal_Int32 nIndex = 0; + while( nIndex != -1 ) + { + OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) ); + if( ! aToken.compareToAscii( "fax", 3 ) ) + { + m_bFax = true; + m_aTmpFile = getTmpName(); + nMode = S_IRUSR | S_IWUSR; + + ::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it; + it = pJobSetup->maValueMap.find( ::rtl::OUString::createFromAscii( "FAX#" ) ); + if( it != pJobSetup->maValueMap.end() ) + m_aFaxNr = it->second; + + sal_Int32 nPos = 0; + m_bSwallowFaxNo = ! aToken.getToken( 1, '=', nPos ).compareToAscii( "swallow", 7 ) ? true : false; + + break; + } + if( ! aToken.compareToAscii( "pdf=", 4 ) ) + { + m_bPdf = true; + m_aTmpFile = getTmpName(); + nMode = S_IRUSR | S_IWUSR; + + if( ! m_aFileName.Len() ) + { + m_aFileName = getPdfDir( rInfo ); + m_aFileName.Append( '/' ); + m_aFileName.Append( rJobName ); + m_aFileName.AppendAscii( ".pdf" ); + } + break; + } + } + m_aPrinterGfx.Init( m_aJobData ); + + // set/clear backwards compatibility flag + bool bStrictSO52Compatibility = false; + std::hash_map<rtl::OUString, rtl::OUString, rtl::OUStringHash >::const_iterator compat_it = + pJobSetup->maValueMap.find( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StrictSO52Compatibility" ) ) ); + if( compat_it != pJobSetup->maValueMap.end() ) + { + if( compat_it->second.equalsIgnoreAsciiCaseAscii( "true" ) ) + bStrictSO52Compatibility = true; + } + m_aPrinterGfx.setStrictSO52Compatibility( bStrictSO52Compatibility ); + + return m_aPrintJob.StartJob( m_aTmpFile.Len() ? m_aTmpFile : m_aFileName, nMode, rJobName, rAppName, m_aJobData, &m_aPrinterGfx ) ? TRUE : FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL PspSalPrinter::EndJob() +{ + BOOL bSuccess = m_aPrintJob.EndJob(); + + if( bSuccess ) + { + // check for fax + if( m_bFax ) + { + + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + // sendAFax removes the file after use + bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand ); + } + else if( m_bPdf ) + { + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand ); + } + } + vcl_sal::PrinterUpdate::jobEnded(); + return bSuccess; +} + +// ----------------------------------------------------------------------- + +BOOL PspSalPrinter::AbortJob() +{ + BOOL bAbort = m_aPrintJob.AbortJob() ? TRUE : FALSE; + vcl_sal::PrinterUpdate::jobEnded(); + return bAbort; +} + +// ----------------------------------------------------------------------- + +SalGraphics* PspSalPrinter::StartPage( ImplJobSetup* pJobSetup, BOOL ) +{ + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData ); + m_pGraphics = new PspGraphics( &m_aJobData, &m_aPrinterGfx, m_bFax ? &m_aFaxNr : NULL, m_bSwallowFaxNo, m_pInfoPrinter ); + m_pGraphics->SetLayout( 0 ); + if( m_nCopies > 1 ) + // in case user did not do anything (m_nCopies=1) + // take the default from jobsetup + m_aJobData.m_nCopies = m_nCopies; + + m_aPrintJob.StartPage( m_aJobData ); + m_aPrinterGfx.Init( m_aPrintJob ); + + return m_pGraphics; +} + +// ----------------------------------------------------------------------- + +BOOL PspSalPrinter::EndPage() +{ + sal_Bool bResult = m_aPrintJob.EndPage(); + m_aPrinterGfx.Clear(); + return bResult ? TRUE : FALSE; +} + +// ----------------------------------------------------------------------- + +ULONG PspSalPrinter::GetErrorCode() +{ + return 0; +} + +/* + * vcl::PrinterUpdate + */ + +Timer* vcl_sal::PrinterUpdate::pPrinterUpdateTimer = NULL; +int vcl_sal::PrinterUpdate::nActiveJobs = 0; + +void vcl_sal::PrinterUpdate::doUpdate() +{ + ::psp::PrinterInfoManager& rManager( ::psp::PrinterInfoManager::get() ); + if( rManager.checkPrintersChanged( false ) && SvpSalInstance::s_pDefaultInstance ) + { + const std::list< SalFrame* >& rList = SvpSalInstance::s_pDefaultInstance->getFrames(); + for( std::list< SalFrame* >::const_iterator it = rList.begin(); + it != rList.end(); ++it ) + SvpSalInstance::s_pDefaultInstance->PostEvent( *it, NULL, SALEVENT_PRINTERCHANGED ); + } +} + +// ----------------------------------------------------------------------- + +IMPL_STATIC_LINK_NOINSTANCE( vcl_sal::PrinterUpdate, UpdateTimerHdl, void*, ) +{ + if( nActiveJobs < 1 ) + { + doUpdate(); + delete pPrinterUpdateTimer; + pPrinterUpdateTimer = NULL; + } + else + pPrinterUpdateTimer->Start(); + + return 0; +} + +// ----------------------------------------------------------------------- + +void vcl_sal::PrinterUpdate::update() +{ + if( Application::GetSettings().GetMiscSettings().GetDisablePrinting() ) + return; + + static bool bOnce = false; + if( ! bOnce ) + { + bOnce = true; + // start background printer detection + psp::PrinterInfoManager::get(); + return; + } + + if( nActiveJobs < 1 ) + doUpdate(); + else if( ! pPrinterUpdateTimer ) + { + pPrinterUpdateTimer = new Timer(); + pPrinterUpdateTimer->SetTimeout( 500 ); + pPrinterUpdateTimer->SetTimeoutHdl( STATIC_LINK( NULL, vcl_sal::PrinterUpdate, UpdateTimerHdl ) ); + pPrinterUpdateTimer->Start(); + } +} + +// ----------------------------------------------------------------------- + +void vcl_sal::PrinterUpdate::jobEnded() +{ + nActiveJobs--; + if( nActiveJobs < 1 ) + { + if( pPrinterUpdateTimer ) + { + pPrinterUpdateTimer->Stop(); + delete pPrinterUpdateTimer; + pPrinterUpdateTimer = NULL; + doUpdate(); + } + } +} diff --git a/vcl/unx/headless/svpprn.hxx b/vcl/unx/headless/svpprn.hxx new file mode 100644 index 000000000000..9b5a7abf99ae --- /dev/null +++ b/vcl/unx/headless/svpprn.hxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svpprn.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:28:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_SVPPRN_HXX +#define _SVP_SVPPRN_HXX + +#ifndef _PSPRINT_JOBDATA_HXX_ +#include <psprint/jobdata.hxx> +#endif +#ifndef _PSPRINT_PRINTERGFX_HXX_ +#include <psprint/printergfx.hxx> +#endif +#ifndef _PSPRINT_PRINTERJOB_HXX_ +#include <psprint/printerjob.hxx> +#endif +#ifndef _SV_SALPRN_HXX +#include <vcl/salprn.hxx> +#endif + +class PspGraphics; + +class PspSalInfoPrinter : public SalInfoPrinter +{ +public: + PspGraphics* m_pGraphics; + psp::JobData m_aJobData; + psp::PrinterGfx m_aPrinterGfx; + + PspSalInfoPrinter(); + virtual ~PspSalInfoPrinter(); + + // overload all pure virtual methods + virtual SalGraphics* GetGraphics(); + virtual void ReleaseGraphics( SalGraphics* pGraphics ); + virtual BOOL Setup( SalFrame* pFrame, ImplJobSetup* pSetupData ); + virtual BOOL SetPrinterData( ImplJobSetup* pSetupData ); + virtual BOOL SetData( ULONG nFlags, ImplJobSetup* pSetupData ); + virtual void GetPageInfo( const ImplJobSetup* pSetupData, + long& rOutWidth, long& rOutHeight, + long& rPageOffX, long& rPageOffY, + long& rPageWidth, long& rPageHeight ); + virtual ULONG GetCapabilities( const ImplJobSetup* pSetupData, USHORT nType ); + virtual ULONG GetPaperBinCount( const ImplJobSetup* pSetupData ); + virtual String GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin ); + virtual void InitPaperFormats( const ImplJobSetup* pSetupData ); + virtual int GetLandscapeAngle( const ImplJobSetup* pSetupData ); + virtual DuplexMode GetDuplexMode( const ImplJobSetup* pSetupData ); +}; + +class PspSalPrinter : public SalPrinter +{ +public: + String m_aFileName; + String m_aTmpFile; + String m_aFaxNr; + bool m_bFax:1; + bool m_bPdf:1; + bool m_bSwallowFaxNo:1; + PspGraphics* m_pGraphics; + psp::PrinterJob m_aPrintJob; + psp::JobData m_aJobData; + psp::PrinterGfx m_aPrinterGfx; + ULONG m_nCopies; + SalInfoPrinter* m_pInfoPrinter; + + PspSalPrinter( SalInfoPrinter* ); + virtual ~PspSalPrinter(); + + // overload all pure virtual methods + virtual BOOL StartJob( const XubString* pFileName, + const XubString& rJobName, + const XubString& rAppName, + ULONG nCopies, BOOL bCollate, + ImplJobSetup* pSetupData ); + virtual BOOL EndJob(); + virtual BOOL AbortJob(); + virtual SalGraphics* StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData ); + virtual BOOL EndPage(); + virtual ULONG GetErrorCode(); +}; + +class Timer; + +namespace vcl_sal { +class VCL_DLLPUBLIC PrinterUpdate +{ + static Timer* pPrinterUpdateTimer; + static int nActiveJobs; + + static void doUpdate(); + DECL_STATIC_LINK( PrinterUpdate, UpdateTimerHdl, void* ); +public: + static void update(); + static void jobStarted() { nActiveJobs++; } + static void jobEnded(); +}; +} + +#endif // _SVP_SVPPRN_HXX + + diff --git a/vcl/unx/headless/svppspgraphics.hxx b/vcl/unx/headless/svppspgraphics.hxx new file mode 100644 index 000000000000..8555d577647d --- /dev/null +++ b/vcl/unx/headless/svppspgraphics.hxx @@ -0,0 +1,206 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svppspgraphics.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:28:40 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _SVP_PSPGRAPHICS_HXX +#define _SVP_PSPGRAPHICS_HXX + + +#ifndef _PSPRINT_FONTMANAGER_HXX +#include <psprint/fontmanager.hxx> +#endif +#ifndef _SV_SALLAYOUT_HXX +#include <vcl/sallayout.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <vcl/salgdi.hxx> +#endif + +namespace psp { struct JobData; class PrinterGfx; } + +class ServerFont; +class ImplDevFontAttributes; +class SalInfoPrinter; + +class PspGraphics : public SalGraphics +{ + psp::JobData* m_pJobData; + psp::PrinterGfx* m_pPrinterGfx; + String* m_pPhoneNr; + bool m_bSwallowFaxNo; + String m_aPhoneCollection; + bool m_bPhoneCollectionActive; + + ServerFont* m_pServerFont[ MAX_FALLBACK ]; + bool m_bFontVertical; + SalInfoPrinter* m_pInfoPrinter; + +protected: + virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); + +public: + PspGraphics( psp::JobData* pJob, psp::PrinterGfx* pGfx, String* pPhone, bool bSwallow, SalInfoPrinter* pInfoPrinter ) + : m_pJobData( pJob ), + m_pPrinterGfx( pGfx ), + m_pPhoneNr( pPhone ), + m_bSwallowFaxNo( bSwallow ), + m_bPhoneCollectionActive( false ), + m_bFontVertical( false ), + m_pInfoPrinter( pInfoPrinter ) + { for( int i = 0; i < MAX_FALLBACK; i++ ) m_pServerFont[i] = 0; } + virtual ~PspGraphics(); + + // helper methods for sharing with X11SalGraphics + static bool DoCreateFontSubset( const rtl::OUString& rToFile, + psp::fontID aFont, + sal_Int32* pGlyphIDs, + sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphs, + FontSubsetInfo& rInfo ); + static const void* DoGetEmbedFontData( psp::fontID aFont, const sal_Unicode* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ); + static void DoFreeEmbedFontData( const void* pData, long nLen ); + static const std::map< sal_Unicode, sal_Int32 >* DoGetFontEncodingVector( psp::fontID aFont, const std::map< sal_Unicode, rtl::OString >** pNonEncoded ); + static void DoGetGlyphWidths( psp::fontID aFont, + bool bVertical, + std::vector< sal_Int32 >& rWidths, + std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ); + static ImplDevFontAttributes Info2DevFontAttributes( const psp::FastPrintFontInfo& ); + static void AnnounceFonts( ImplDevFontList*, const psp::FastPrintFontInfo& ); + static FontWidth ToFontWidth (psp::width::type eWidth); + static FontWeight ToFontWeight (psp::weight::type eWeight); + static FontPitch ToFontPitch (psp::pitch::type ePitch); + static FontItalic ToFontItalic (psp::italic::type eItalic); + static FontFamily ToFontFamily (psp::family::type eFamily); + + // overload all pure virtual methods + virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ); + virtual void GetScreenFontResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ); + virtual USHORT GetBitCount(); + virtual long GetGraphicsWidth() const; + + virtual void ResetClipRegion(); + virtual void BeginSetClipRegion( ULONG nCount ); + virtual BOOL unionClipRegion( long nX, long nY, long nWidth, long nHeight ); + virtual void EndSetClipRegion(); + + virtual void SetLineColor(); + virtual void SetLineColor( SalColor nSalColor ); + virtual void SetFillColor(); + virtual void SetFillColor( SalColor nSalColor ); + virtual void SetXORMode( BOOL bSet ); + virtual void SetROPLineColor( SalROPColor nROPColor ); + virtual void SetROPFillColor( SalROPColor nROPColor ); + + virtual void SetTextColor( SalColor nSalColor ); + virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); + virtual void GetFontMetric( ImplFontMetricData* ); + virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); + virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual void GetDevFontList( ImplDevFontList* ); + virtual void GetDevFontSubstList( OutputDevice* ); + virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); + virtual BOOL CreateFontSubset( const rtl::OUString& rToFile, + ImplFontData* pFont, + sal_Int32* pGlyphIDs, + sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphs, + FontSubsetInfo& rInfo + ); + virtual const std::map< sal_Unicode, sal_Int32 >* GetFontEncodingVector( ImplFontData* pFont, const std::map< sal_Unicode, rtl::OString >** ppNonEncoded ); + virtual const void* GetEmbedFontData( ImplFontData* pFont, + const sal_Unicode* pUnicodes, + sal_Int32* pWidths, + FontSubsetInfo& rInfo, + long* pDataLen ); + virtual void FreeEmbedFontData( const void* pData, long nDataLen ); + virtual void GetGlyphWidths( ImplFontData* pFont, + bool bVertical, + std::vector< sal_Int32 >& rWidths, + std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ); + virtual BOOL GetGlyphBoundRect( long nIndex, Rectangle& ); + virtual BOOL GetGlyphOutline( long nIndex, ::basegfx::B2DPolyPolygon& ); + virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ); + virtual void DrawServerFontLayout( const ServerFontLayout& ); + virtual void drawPixel( long nX, long nY ); + virtual void drawPixel( long nX, long nY, SalColor nSalColor ); + virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ); + virtual void drawRect( long nX, long nY, long nWidth, long nHeight ); + virtual void drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ); + virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); + virtual void drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32* pPoints, + PCONSTSALPOINT* pPtAry ); + virtual sal_Bool drawPolyLineBezier( ULONG nPoints, + const SalPoint* pPtAry, + const BYTE* pFlgAry ); + virtual sal_Bool drawPolygonBezier( ULONG nPoints, + const SalPoint* pPtAry, + const BYTE* pFlgAry ); + virtual sal_Bool drawPolyPolygonBezier( sal_uInt32 nPoly, + const sal_uInt32* pPoints, + const SalPoint* const* pPtAry, + const BYTE* const* pFlgAry ); + virtual void copyArea( long nDestX, + long nDestY, + long nSrcX, + long nSrcY, + long nSrcWidth, + long nSrcHeight, + USHORT nFlags ); + virtual void copyBits( const SalTwoRect* pPosAry, + SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nTransparentColor ); + virtual void drawBitmap( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + const SalBitmap& rTransparentBitmap ); + virtual void drawMask( const SalTwoRect* pPosAry, + const SalBitmap& rSalBitmap, + SalColor nMaskColor ); + virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); + virtual SalColor getPixel( long nX, long nY ); + virtual void invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ); + virtual void invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nFlags ); + + virtual BOOL drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ); + virtual bool filterText( const String& rOrigText, String& rNewText, xub_StrLen nIndex, xub_StrLen& rLen, xub_StrLen& rCutStart, xub_StrLen& rCutStop ); +}; + +#endif // _SVP_PSPGRAPHICS_HXX diff --git a/vcl/unx/headless/svptext.cxx b/vcl/unx/headless/svptext.cxx new file mode 100644 index 000000000000..1e1a4cd56675 --- /dev/null +++ b/vcl/unx/headless/svptext.cxx @@ -0,0 +1,510 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: svptext.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2007-07-24 10:28:49 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "svpgdi.hxx" +#include "svpbmp.hxx" + +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2irange.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basebmp/scanlineformats.hxx> + +#include <tools/debug.hxx> + +#if OSL_DEBUG_LEVEL > 2 +#include <basebmp/debug.hxx> +#endif + +#include <vcl/outfont.hxx> +#include <vcl/glyphcache.hxx> +#include <vcl/impfont.hxx> + +#include "svppspgraphics.hxx" + +using namespace basegfx; +using namespace basebmp; + +// =========================================================================== + +class SvpGlyphPeer +: public GlyphCachePeer +{ +public: + SvpGlyphPeer() {} + + BitmapDeviceSharedPtr GetGlyphBmp( ServerFont&, int nGlyphIndex, + sal_uInt32 nBmpFormat, B2IPoint& rTargetPos ); + +protected: + virtual void RemovingFont( ServerFont& ); + virtual void RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex ); + + class SvpGcpHelper + { + public: + RawBitmap maRawBitmap; + BitmapDeviceSharedPtr maBitmapDev; + }; +}; + +// =========================================================================== + +class SvpGlyphCache : public GlyphCache +{ +public: + SvpGlyphPeer& GetPeer() { return reinterpret_cast<SvpGlyphPeer&>( mrPeer ); } +static SvpGlyphCache& GetInstance(); +private: + SvpGlyphCache( SvpGlyphPeer& rPeer ) : GlyphCache( rPeer) {} +}; + +//-------------------------------------------------------------------------- + +SvpGlyphCache& SvpGlyphCache::GetInstance() +{ + static SvpGlyphPeer aSvpGlyphPeer; + static SvpGlyphCache aGC( aSvpGlyphPeer ); + return aGC; +} + +// =========================================================================== + +BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont, + int nGlyphIndex, sal_uInt32 nBmpFormat, B2IPoint& rTargetPos ) +{ + GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex ); + SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData; + + // nothing to do if the GlyphPeer hasn't allocated resources for the glyph + if( rGlyphData.ExtDataRef().meInfo != sal::static_int_cast<int>(nBmpFormat) ) + { + if( rGlyphData.ExtDataRef().meInfo == Format::NONE ) + pGcpHelper = new SvpGcpHelper; + RawBitmap& rRawBitmap = pGcpHelper->maRawBitmap; + + // get glyph bitmap in matching format + bool bFound = false; + switch( nBmpFormat ) + { + case Format::ONE_BIT_LSB_GREY: + bFound = rServerFont.GetGlyphBitmap1( nGlyphIndex, pGcpHelper->maRawBitmap ); + break; + case Format::EIGHT_BIT_GREY: + bFound = rServerFont.GetGlyphBitmap8( nGlyphIndex, pGcpHelper->maRawBitmap ); + break; + default: + DBG_ERROR( "SVP GCP::GetGlyphBmp(): illegal scanline format"); + // fall back to black&white mask + nBmpFormat = Format::ONE_BIT_LSB_GREY; + bFound = false; + break; + } + + // return .notdef glyph if needed + if( !bFound && (nGlyphIndex != 0) ) + { + delete pGcpHelper; + return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos ); + } + + // construct alpha mask from raw bitmap + const B2IVector aSize( rRawBitmap.mnScanlineSize, rRawBitmap.mnHeight ); + if( aSize.getX() && aSize.getY() ) + { + static PaletteMemorySharedVector aDummyPAL; + RawMemorySharedArray aRawPtr( rRawBitmap.mpBits ); + pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aRawPtr, aDummyPAL ); + } + + rServerFont.SetExtended( nBmpFormat, (void*)pGcpHelper ); + } + + rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset ); + return pGcpHelper->maBitmapDev; +} + +//-------------------------------------------------------------------------- + +void SvpGlyphPeer::RemovingFont( ServerFont& ) +{ + // nothing to do: no font resources held in SvpGlyphPeer +} + +//-------------------------------------------------------------------------- + +void SvpGlyphPeer::RemovingGlyph( ServerFont&, GlyphData& rGlyphData, int /*nGlyphIndex*/ ) +{ + if( rGlyphData.ExtDataRef().mpData != Format::NONE ) + { + // release the glyph related resources + DBG_ASSERT( (rGlyphData.ExtDataRef().meInfo <= Format::MAX), "SVP::RG() invalid alpha format" ); + SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData; + delete[] pGcpHelper->maRawBitmap.mpBits; + delete pGcpHelper; + } +} + +// =========================================================================== + +// PspKernInfo allows on-demand-querying of psprint provided kerning info (#i29881#) +class PspKernInfo : public ExtraKernInfo +{ +public: + PspKernInfo( int nFontId ) : ExtraKernInfo(nFontId) {} +protected: + virtual void Initialize() const; +}; + +//-------------------------------------------------------------------------- + +void PspKernInfo::Initialize() const +{ + mbInitialized = true; + + // get the kerning pairs from psprint + const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + typedef std::list< psp::KernPair > PspKernPairs; + const PspKernPairs& rKernPairs = rMgr.getKernPairs( mnFontId ); + if( rKernPairs.empty() ) + return; + + // feed psprint's kerning list into a lookup-friendly container + maUnicodeKernPairs.resize( rKernPairs.size() ); + PspKernPairs::const_iterator it = rKernPairs.begin(); + for(; it != rKernPairs.end(); ++it ) + { + ImplKernPairData aKernPair = { it->first, it->second, it->kern_x }; + maUnicodeKernPairs.insert( aKernPair ); + } +} + +// =========================================================================== + +USHORT SvpSalGraphics::SetFont( ImplFontSelectData* pIFSD, int nFallbackLevel ) +{ + // release all no longer needed font resources + for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) + { + if( m_pServerFont[i] != NULL ) + { + // old server side font is no longer referenced + SvpGlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] ); + m_pServerFont[i] = NULL; + } + } + + // return early if there is no new font + if( !pIFSD ) + return 0; + + // handle the request for a non-native X11-font => use the GlyphCache + ServerFont* pServerFont = SvpGlyphCache::GetInstance().CacheFont( *pIFSD ); + if( !pServerFont ) + return SAL_SETFONT_BADFONT; + + // check selected font + if( !pServerFont->TestFont() ) + { + SvpGlyphCache::GetInstance().UncacheFont( *pServerFont ); + return SAL_SETFONT_BADFONT; + } + + // update SalGraphics font settings + m_pServerFont[ nFallbackLevel ] = pServerFont; + return SAL_SETFONT_USEDRAWTEXTARRAY; +} + +// --------------------------------------------------------------------------- + +void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) +{ + if( m_pServerFont[0] != NULL ) + { + long rDummyFactor; + m_pServerFont[0]->FetchFontMetric( *pMetric, rDummyFactor ); + } +} + +// --------------------------------------------------------------------------- + +ULONG SvpSalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) +{ + ULONG nGotPairs = 0; + + if( m_pServerFont[0] != NULL ) + { + ImplKernPairData* pTmpKernPairs = NULL; + nGotPairs = m_pServerFont[0]->GetKernPairs( &pTmpKernPairs ); + for( ULONG i = 0; i < nPairs && i < nGotPairs; ++i ) + pKernPairs[ i ] = pTmpKernPairs[ i ]; + delete[] pTmpKernPairs; + } + + return nGotPairs; +} + +// --------------------------------------------------------------------------- + +ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const +{ + ImplFontCharMap* pMap = NULL; + + int nPairCount = 0; + if( m_pServerFont[0] ) + nPairCount = m_pServerFont[0]->GetFontCodeRanges( NULL ); + + if( nPairCount > 0 ) + { + sal_uInt32* pCodePairs = new sal_uInt32[ 2 * nPairCount ]; + m_pServerFont[0]->GetFontCodeRanges( pCodePairs ); + pMap = new ImplFontCharMap( nPairCount, pCodePairs ); + } + + return pMap; +} + +// --------------------------------------------------------------------------- + +void SvpSalGraphics::GetDevFontList( ImplDevFontList* pDevFontList ) +{ + GlyphCache& rGC = SvpGlyphCache::GetInstance(); + + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + psp::FastPrintFontInfo aInfo; + ::std::list< psp::fontID > aList; + rMgr.getFontList( aList ); + ::std::list< psp::fontID >::iterator it; + for( it = aList.begin(); it != aList.end(); ++it ) + { + if( !rMgr.getFontFastInfo( *it, aInfo ) ) + continue; + + // the GlyphCache must not bother with builtin fonts because + // it cannot access or use them anyway + if( aInfo.m_eType == psp::fonttype::Builtin ) + continue; + + // normalize face number to the GlyphCache + int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); + if( nFaceNum < 0 ) + nFaceNum = 0; + + // for fonts where extra kerning info can be provided on demand + // an ExtraKernInfo object is supplied + const ExtraKernInfo* pExtraKernInfo = NULL; + if( aInfo.m_eType == psp::fonttype::Type1 ) + pExtraKernInfo = new PspKernInfo( *it ); + + // inform GlyphCache about this font provided by the PsPrint subsystem + ImplDevFontAttributes aDFA = PspGraphics::Info2DevFontAttributes( aInfo ); + aDFA.mnQuality += 4096; + const rtl::OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); + rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA, pExtraKernInfo ); + } + + // announce glyphcache fonts + rGC.AnnounceFonts( pDevFontList ); +} + +// --------------------------------------------------------------------------- + +void SvpSalGraphics::GetDevFontSubstList( OutputDevice* ) +{} + +// --------------------------------------------------------------------------- + +bool SvpSalGraphics::AddTempDevFont( ImplDevFontList*, + const String&, const String& ) +{ + return false; +} + +// --------------------------------------------------------------------------- + +BOOL SvpSalGraphics::CreateFontSubset( + const rtl::OUString& rToFile, + ImplFontData* pFont, + sal_Int32* pGlyphIDs, + sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphs, + FontSubsetInfo& rInfo + ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the ImplFontData pFont + psp::fontID aFont = pFont->GetFontId(); + return PspGraphics::DoCreateFontSubset( rToFile, aFont, pGlyphIDs, pEncoding, pWidths, nGlyphs, rInfo ); +} + +// --------------------------------------------------------------------------- + +const std::map< sal_Unicode, sal_Int32 >* SvpSalGraphics::GetFontEncodingVector( + ImplFontData* pFont, + const std::map< sal_Unicode, rtl::OString >** pNonEncoded + ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the ImplFontData pFont + psp::fontID aFont = pFont->GetFontId(); + return PspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded ); +} + +// --------------------------------------------------------------------------- + +const void* SvpSalGraphics::GetEmbedFontData( + ImplFontData* pFont, + const sal_Unicode* pUnicodes, + sal_Int32* pWidths, + FontSubsetInfo& rInfo, + long* pDataLen + ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the ImplFontData pFont + psp::fontID aFont = pFont->GetFontId(); + return PspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen ); +} + +// --------------------------------------------------------------------------- + +void SvpSalGraphics::FreeEmbedFontData( const void* pData, long nLen ) +{ + PspGraphics::DoFreeEmbedFontData( pData, nLen ); +} + +void SvpSalGraphics::GetGlyphWidths( ImplFontData* pFont, + bool bVertical, + std::vector< sal_Int32 >& rWidths, + std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the ImplFontData pFont + psp::fontID aFont = pFont->GetFontId(); + PspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); +} + +// --------------------------------------------------------------------------- + +BOOL SvpSalGraphics::GetGlyphBoundRect( long nGlyphIndex, Rectangle& rRect ) +{ + int nLevel = nGlyphIndex >> GF_FONTSHIFT; + if( nLevel >= MAX_FALLBACK ) + return FALSE; + + ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + return FALSE; + + nGlyphIndex &= ~GF_FONTMASK; + const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex ); + rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() ); + return TRUE; +} + +// --------------------------------------------------------------------------- + +BOOL SvpSalGraphics::GetGlyphOutline( long nGlyphIndex, B2DPolyPolygon& rPolyPoly ) +{ + int nLevel = nGlyphIndex >> GF_FONTSHIFT; + if( nLevel >= MAX_FALLBACK ) + return FALSE; + + const ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + return FALSE; + + nGlyphIndex &= ~GF_FONTMASK; + if( pSF->GetGlyphOutline( nGlyphIndex, rPolyPoly ) ) + return TRUE; + + return FALSE; +} + +// --------------------------------------------------------------------------- + +SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) +{ + GenericSalLayout* pLayout = NULL; + + if( m_pServerFont[ nFallbackLevel ] ) + pLayout = new ServerFontLayout( *m_pServerFont[ nFallbackLevel ] ); + + return pLayout; +} + +// --------------------------------------------------------------------------- + +void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout ) +{ + // iterate over all glyphs in the layout + Point aPos; + sal_Int32 nGlyphIndex; + SvpGlyphPeer& rGlyphPeer = SvpGlyphCache::GetInstance().GetPeer(); + for( int nStart = 0; rSalLayout.GetNextGlyphs( 1, &nGlyphIndex, aPos, nStart ); ) + { + int nLevel = nGlyphIndex >> GF_FONTSHIFT; + DBG_ASSERT( nLevel < MAX_FALLBACK, "SvpGDI: invalid glyph fallback level" ); + ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + continue; + + // get the glyph's alpha mask and adjust the drawing position + nGlyphIndex &= ~GF_FONTMASK; + B2IPoint aDstPoint( aPos.X(), aPos.Y() ); + BitmapDeviceSharedPtr aAlphaMask + = rGlyphPeer.GetGlyphBmp( *pSF, nGlyphIndex, m_eTextFmt, aDstPoint ); + if( !aAlphaMask ) // ignore empty glyphs + continue; + + // blend text color into target using the glyph's mask + const B2IRange aSrcRect( B2ITuple(0,0), aAlphaMask->getSize() ); + m_aDevice->drawMaskedColor( m_aTextColor, aAlphaMask, aSrcRect, aDstPoint, m_aClipMap ); + } +} + +// =========================================================================== |