bump product version to 4.1.6.2
[LibreOffice.git] / vcl / headless / svpelement.cxx
blob8b6f3604ca417bad157de42d002bdf9261c29988
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "headless/svpelement.hxx"
22 #include <basebmp/scanlineformats.hxx>
23 #include <osl/diagnose.h>
25 #if defined WITH_SVP_LISTENING
26 #include <osl/thread.h>
27 #include <vcl/svapp.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <vcl/bitmap.hxx>
30 #include <tools/stream.hxx>
32 #include "headless/svpvd.hxx"
33 #include "headless/svpbmp.hxx"
34 #include "headless/svpframe.hxx"
36 #include <list>
37 #include <boost/unordered_map.hpp>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/ip.h>
42 #include <stdio.h>
43 #include <errno.h>
45 using namespace basegfx;
47 class SvpElementContainer
49 std::list< SvpElement* > m_aElements;
50 int m_nSocket;
51 oslThread m_aThread;
53 SvpElementContainer();
54 ~SvpElementContainer();
55 public:
56 void registerElement( SvpElement* pElement ) { m_aElements.push_back(pElement); }
57 void deregisterElement( SvpElement* pElement ) { m_aElements.remove(pElement); }
59 void run();
60 DECL_LINK(processRequest,void*);
62 static SvpElementContainer& get();
65 extern "C" void SAL_CALL SvpContainerThread( void* );
67 SvpElementContainer& SvpElementContainer::get()
69 static SvpElementContainer* pInstance = new SvpElementContainer();
70 return *pInstance;
73 SvpElementContainer::SvpElementContainer()
75 static const char* pEnv = getenv("SVP_LISTENER_PORT");
76 int nPort = (pEnv && *pEnv) ? atoi(pEnv) : 8000;
77 m_nSocket = socket( PF_INET, SOCK_STREAM, 0 );
78 if( m_nSocket >= 0)
80 int nOn = 1;
81 if( setsockopt(m_nSocket, SOL_SOCKET, SO_REUSEADDR,
82 (char*)&nOn, sizeof(nOn)) )
84 perror( "SvpElementContainer: changing socket options failed" );
85 close( m_nSocket );
87 else
89 struct sockaddr_in addr;
90 memset(&addr, 0, sizeof(struct sockaddr_in));
91 addr.sin_family = AF_INET;
92 addr.sin_port = htons(nPort);
93 addr.sin_addr.s_addr = INADDR_ANY;
94 if( bind(m_nSocket,(struct sockaddr*)&addr,sizeof(addr)) )
96 perror( "SvpElementContainer: bind() failed" );
97 close( m_nSocket );
99 else
101 if( listen( m_nSocket, 0 ) )
103 perror( "SvpElementContainer: listen() failed" );
104 close(m_nSocket);
106 else
108 m_aThread = osl_createThread( SvpContainerThread, this );
113 else
114 perror( "SvpElementContainer: socket() failed\n" );
117 SvpElementContainer::~SvpElementContainer()
121 void SAL_CALL SvpContainerThread(void* pSvpContainer)
123 ((SvpElementContainer*)pSvpContainer)->run();
126 void SvpElementContainer::run()
128 bool bRun = m_nSocket != 0;
129 while( bRun )
131 int nLocalSocket = accept( m_nSocket, NULL, NULL );
132 if( nLocalSocket < 0 )
134 bRun = false;
135 perror( "accept() failed" );
137 else
139 Application::PostUserEvent( LINK( this, SvpElementContainer, processRequest ), (void*)nLocalSocket );
142 if( m_nSocket )
143 close( m_nSocket );
146 static const char* matchType( SvpElement* pEle )
148 if( dynamic_cast<SvpSalBitmap*>(pEle) )
149 return "Bitmap";
150 else if( dynamic_cast<SvpSalFrame*>(pEle) )
151 return "Frame";
152 else if( dynamic_cast<SvpSalVirtualDevice*>(pEle) )
153 return "VirtualDevice";
154 return typeid(*pEle).name();
157 IMPL_LINK( SvpElementContainer, processRequest, void*, pSocket )
159 int nFile = (int)pSocket;
161 OStringBuffer aBuf( 256 ), aAnswer( 256 );
162 char c;
163 while( read( nFile, &c, 1 ) && c != '\n' )
164 aBuf.append( sal_Char(c) );
165 OString aCommand( aBuf.makeStringAndClear() );
166 if( aCommand.startsWith( "list" ) )
168 boost::unordered_map< OString, std::list<SvpElement*>, OStringHash > aMap;
169 for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
170 it != m_aElements.end(); ++it )
172 std::list<SvpElement*>& rList = aMap[matchType(*it)];
173 rList.push_back( *it );
175 for( boost::unordered_map< OString, std::list<SvpElement*>, OStringHash>::const_iterator hash_it = aMap.begin();
176 hash_it != aMap.end(); ++hash_it )
178 aAnswer.append( "ElementType: " );
179 aAnswer.append( hash_it->first );
180 aAnswer.append( '\n' );
181 for( std::list<SvpElement*>::const_iterator it = hash_it->second.begin();
182 it != hash_it->second.end(); ++it )
184 aAnswer.append( sal_Int64(reinterpret_cast<sal_uInt32>(*it)), 16 );
185 aAnswer.append( '\n' );
189 else if( aCommand.startsWith( "get" ) )
191 sal_IntPtr aId = aCommand.copy( 3 ).toInt64( 16 );
192 SvpElement* pElement = reinterpret_cast<SvpElement*>(aId);
193 for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
194 it != m_aElements.end(); ++it )
196 if( *it == pElement )
198 const basebmp::BitmapDeviceSharedPtr& rDevice = pElement->getDevice();
199 if( rDevice.get() )
201 SvpSalBitmap* pSalBitmap = new SvpSalBitmap();
202 pSalBitmap->setBitmap( rDevice );
203 Bitmap aBitmap( pSalBitmap );
204 SvMemoryStream aStream( 256, 256 );
205 aStream << aBitmap;
206 aStream.Seek( STREAM_SEEK_TO_END );
207 int nBytes = aStream.Tell();
208 aStream.Seek( STREAM_SEEK_TO_BEGIN );
209 aAnswer.append( (const sal_Char*)aStream.GetData(), nBytes );
211 break;
215 else if( aCommand.startsWith( "quit" ) )
217 Application::Quit();
218 close( m_nSocket );
219 m_nSocket = 0;
221 write( nFile, aAnswer.getStr(), aAnswer.getLength() );
222 close( nFile );
224 return 0;
227 #endif
229 using namespace basebmp;
231 SvpElement::SvpElement()
233 #if defined WITH_SVP_LISTENING
234 SvpElementContainer::get().registerElement( this );
235 #endif
238 SvpElement::~SvpElement()
240 #if defined WITH_SVP_LISTENING
241 SvpElementContainer::get().deregisterElement( this );
242 #endif
245 sal_uInt32 SvpElement::getBitCountFromScanlineFormat( sal_Int32 nFormat )
247 sal_uInt32 nBitCount = 1;
248 switch( nFormat )
250 case Format::ONE_BIT_MSB_GREY:
251 case Format::ONE_BIT_LSB_GREY:
252 case Format::ONE_BIT_MSB_PAL:
253 case Format::ONE_BIT_LSB_PAL:
254 nBitCount = 1;
255 break;
256 case Format::FOUR_BIT_MSB_GREY:
257 case Format::FOUR_BIT_LSB_GREY:
258 case Format::FOUR_BIT_MSB_PAL:
259 case Format::FOUR_BIT_LSB_PAL:
260 nBitCount = 4;
261 break;
262 case Format::EIGHT_BIT_PAL:
263 case Format::EIGHT_BIT_GREY:
264 nBitCount = 8;
265 break;
266 case Format::SIXTEEN_BIT_LSB_TC_MASK:
267 case Format::SIXTEEN_BIT_MSB_TC_MASK:
268 nBitCount = 16;
269 break;
270 case Format::TWENTYFOUR_BIT_TC_MASK:
271 nBitCount = 24;
272 break;
273 case Format::THIRTYTWO_BIT_TC_MASK_BGRA:
274 case Format::THIRTYTWO_BIT_TC_MASK_ARGB:
275 case Format::THIRTYTWO_BIT_TC_MASK_ABGR:
276 case Format::THIRTYTWO_BIT_TC_MASK_RGBA:
277 nBitCount = 32;
278 break;
279 default:
280 OSL_FAIL( "unsupported basebmp format" );
281 break;
283 return nBitCount;
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */