Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "headless/svpelement.hxx"
30 : :
31 : : #include <basebmp/scanlineformats.hxx>
32 : : #include <osl/diagnose.h>
33 : :
34 : : #if defined WITH_SVP_LISTENING
35 : : #include <osl/thread.h>
36 : : #include <vcl/svapp.hxx>
37 : : #include <rtl/strbuf.hxx>
38 : : #include <vcl/bitmap.hxx>
39 : : #include <tools/stream.hxx>
40 : :
41 : : #include "headless/svpvd.hxx"
42 : : #include "headless/svpbmp.hxx"
43 : : #include "headless/svpframe.hxx"
44 : :
45 : : #include <list>
46 : : #include <boost/unordered_map.hpp>
47 : :
48 : : #include <sys/types.h>
49 : : #include <sys/socket.h>
50 : : #include <netinet/ip.h>
51 : : #include <stdio.h>
52 : : #include <errno.h>
53 : :
54 : : using namespace basegfx;
55 : :
56 : : class SvpElementContainer
57 : : {
58 : : std::list< SvpElement* > m_aElements;
59 : : int m_nSocket;
60 : : oslThread m_aThread;
61 : :
62 : : SvpElementContainer();
63 : : ~SvpElementContainer();
64 : : public:
65 : : void registerElement( SvpElement* pElement ) { m_aElements.push_back(pElement); }
66 : : void deregisterElement( SvpElement* pElement ) { m_aElements.remove(pElement); }
67 : :
68 : : void run();
69 : : DECL_LINK(processRequest,void*);
70 : :
71 : : static SvpElementContainer& get();
72 : : };
73 : :
74 : : extern "C" void SAL_CALL SvpContainerThread( void* );
75 : :
76 : : SvpElementContainer& SvpElementContainer::get()
77 : : {
78 : : static SvpElementContainer* pInstance = new SvpElementContainer();
79 : : return *pInstance;
80 : : }
81 : :
82 : : SvpElementContainer::SvpElementContainer()
83 : : {
84 : : static const char* pEnv = getenv("SVP_LISTENER_PORT");
85 : : int nPort = (pEnv && *pEnv) ? atoi(pEnv) : 8000;
86 : : m_nSocket = socket( PF_INET, SOCK_STREAM, 0 );
87 : : if( m_nSocket >= 0)
88 : : {
89 : : int nOn = 1;
90 : : if( setsockopt(m_nSocket, SOL_SOCKET, SO_REUSEADDR,
91 : : (char*)&nOn, sizeof(nOn)) )
92 : : {
93 : : perror( "SvpElementContainer: changing socket options failed" );
94 : : close( m_nSocket );
95 : : }
96 : : else
97 : : {
98 : : struct sockaddr_in addr;
99 : : memset(&addr, 0, sizeof(struct sockaddr_in));
100 : : addr.sin_family = AF_INET;
101 : : addr.sin_port = htons(nPort);
102 : : addr.sin_addr.s_addr = INADDR_ANY;
103 : : if( bind(m_nSocket,(struct sockaddr*)&addr,sizeof(addr)) )
104 : : {
105 : : perror( "SvpElementContainer: bind() failed" );
106 : : close( m_nSocket );
107 : : }
108 : : else
109 : : {
110 : : if( listen( m_nSocket, 0 ) )
111 : : {
112 : : perror( "SvpElementContainer: listen() failed" );
113 : : close(m_nSocket);
114 : : }
115 : : else
116 : : {
117 : : m_aThread = osl_createThread( SvpContainerThread, this );
118 : : }
119 : : }
120 : : }
121 : : }
122 : : else
123 : : perror( "SvpElementContainer: socket() failed\n" );
124 : : }
125 : :
126 : : SvpElementContainer::~SvpElementContainer()
127 : : {
128 : : }
129 : :
130 : : void SAL_CALL SvpContainerThread(void* pSvpContainer)
131 : : {
132 : : ((SvpElementContainer*)pSvpContainer)->run();
133 : : }
134 : :
135 : : void SvpElementContainer::run()
136 : : {
137 : : bool bRun = m_nSocket != 0;
138 : : while( bRun )
139 : : {
140 : : int nLocalSocket = accept( m_nSocket, NULL, NULL );
141 : : if( nLocalSocket < 0 )
142 : : {
143 : : bRun = false;
144 : : perror( "accept() failed" );
145 : : }
146 : : else
147 : : {
148 : : Application::PostUserEvent( LINK( this, SvpElementContainer, processRequest ), (void*)nLocalSocket );
149 : : }
150 : : }
151 : : if( m_nSocket )
152 : : close( m_nSocket );
153 : : }
154 : :
155 : : static const char* matchType( SvpElement* pEle )
156 : : {
157 : : if( dynamic_cast<SvpSalBitmap*>(pEle) )
158 : : return "Bitmap";
159 : : else if( dynamic_cast<SvpSalFrame*>(pEle) )
160 : : return "Frame";
161 : : else if( dynamic_cast<SvpSalVirtualDevice*>(pEle) )
162 : : return "VirtualDevice";
163 : : return typeid(*pEle).name();
164 : : }
165 : :
166 : : IMPL_LINK( SvpElementContainer, processRequest, void*, pSocket )
167 : : {
168 : : int nFile = (int)pSocket;
169 : :
170 : : rtl::OStringBuffer aBuf( 256 ), aAnswer( 256 );
171 : : char c;
172 : : while( read( nFile, &c, 1 ) && c != '\n' )
173 : : aBuf.append( sal_Char(c) );
174 : : rtl::OString aCommand( aBuf.makeStringAndClear() );
175 : : if( aCommand.compareTo( "list", 4 ) == 0 )
176 : : {
177 : : boost::unordered_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash > aMap;
178 : : for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
179 : : it != m_aElements.end(); ++it )
180 : : {
181 : : std::list<SvpElement*>& rList = aMap[matchType(*it)];
182 : : rList.push_back( *it );
183 : : }
184 : : for( boost::unordered_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash>::const_iterator hash_it = aMap.begin();
185 : : hash_it != aMap.end(); ++hash_it )
186 : : {
187 : : aAnswer.append( "ElementType: " );
188 : : aAnswer.append( hash_it->first );
189 : : aAnswer.append( '\n' );
190 : : for( std::list<SvpElement*>::const_iterator it = hash_it->second.begin();
191 : : it != hash_it->second.end(); ++it )
192 : : {
193 : : aAnswer.append( sal_Int64(reinterpret_cast<sal_uInt32>(*it)), 16 );
194 : : aAnswer.append( '\n' );
195 : : }
196 : : }
197 : : }
198 : : else if( aCommand.compareTo( "get", 3 ) == 0 )
199 : : {
200 : : sal_IntPtr aId = aCommand.copy( 3 ).toInt64( 16 );
201 : : SvpElement* pElement = reinterpret_cast<SvpElement*>(aId);
202 : : for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
203 : : it != m_aElements.end(); ++it )
204 : : {
205 : : if( *it == pElement )
206 : : {
207 : : const basebmp::BitmapDeviceSharedPtr& rDevice = pElement->getDevice();
208 : : if( rDevice.get() )
209 : : {
210 : : SvpSalBitmap* pSalBitmap = new SvpSalBitmap();
211 : : pSalBitmap->setBitmap( rDevice );
212 : : Bitmap aBitmap( pSalBitmap );
213 : : SvMemoryStream aStream( 256, 256 );
214 : : aStream << aBitmap;
215 : : aStream.Seek( STREAM_SEEK_TO_END );
216 : : int nBytes = aStream.Tell();
217 : : aStream.Seek( STREAM_SEEK_TO_BEGIN );
218 : : aAnswer.append( (const sal_Char*)aStream.GetData(), nBytes );
219 : : }
220 : : break;
221 : : }
222 : : }
223 : : }
224 : : else if( aCommand.compareTo( "quit", 4 ) == 0 )
225 : : {
226 : : Application::Quit();
227 : : close( m_nSocket );
228 : : m_nSocket = 0;
229 : : }
230 : : write( nFile, aAnswer.getStr(), aAnswer.getLength() );
231 : : close( nFile );
232 : :
233 : : return 0;
234 : : }
235 : :
236 : : #endif
237 : :
238 : : using namespace basebmp;
239 : :
240 : 993696 : SvpElement::SvpElement()
241 : : {
242 : : #if defined WITH_SVP_LISTENING
243 : : SvpElementContainer::get().registerElement( this );
244 : : #endif
245 : 993696 : }
246 : :
247 : 992256 : SvpElement::~SvpElement()
248 : : {
249 : : #if defined WITH_SVP_LISTENING
250 : : SvpElementContainer::get().deregisterElement( this );
251 : : #endif
252 [ - + ]: 992256 : }
253 : :
254 : 667125 : sal_uInt32 SvpElement::getBitCountFromScanlineFormat( sal_Int32 nFormat )
255 : : {
256 : 667125 : sal_uInt32 nBitCount = 1;
257 [ + + + - : 667125 : switch( nFormat )
+ - - ]
258 : : {
259 : : case Format::ONE_BIT_MSB_GREY:
260 : : case Format::ONE_BIT_LSB_GREY:
261 : : case Format::ONE_BIT_MSB_PAL:
262 : : case Format::ONE_BIT_LSB_PAL:
263 : 3752 : nBitCount = 1;
264 : 3752 : break;
265 : : case Format::FOUR_BIT_MSB_GREY:
266 : : case Format::FOUR_BIT_LSB_GREY:
267 : : case Format::FOUR_BIT_MSB_PAL:
268 : : case Format::FOUR_BIT_LSB_PAL:
269 : 654 : nBitCount = 4;
270 : 654 : break;
271 : : case Format::EIGHT_BIT_PAL:
272 : : case Format::EIGHT_BIT_GREY:
273 : 368709 : nBitCount = 8;
274 : 368709 : break;
275 : : case Format::SIXTEEN_BIT_LSB_TC_MASK:
276 : : case Format::SIXTEEN_BIT_MSB_TC_MASK:
277 : 0 : nBitCount = 16;
278 : 0 : break;
279 : : case Format::TWENTYFOUR_BIT_TC_MASK:
280 : 294010 : nBitCount = 24;
281 : 294010 : break;
282 : : case Format::THIRTYTWO_BIT_TC_MASK_BGRA:
283 : : case Format::THIRTYTWO_BIT_TC_MASK_ARGB:
284 : : case Format::THIRTYTWO_BIT_TC_MASK_ABGR:
285 : : case Format::THIRTYTWO_BIT_TC_MASK_RGBA:
286 : 0 : nBitCount = 32;
287 : 0 : break;
288 : : default:
289 : : OSL_FAIL( "unsupported basebmp format" );
290 : 0 : break;
291 : : }
292 : 667125 : return nBitCount;
293 : : }
294 : :
295 : :
296 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|