1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "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"
37 #include <boost/unordered_map.hpp>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/ip.h>
45 using namespace basegfx
;
47 class SvpElementContainer
49 std::list
< SvpElement
* > m_aElements
;
53 SvpElementContainer();
54 ~SvpElementContainer();
56 void registerElement( SvpElement
* pElement
) { m_aElements
.push_back(pElement
); }
57 void deregisterElement( SvpElement
* pElement
) { m_aElements
.remove(pElement
); }
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();
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 );
81 if( setsockopt(m_nSocket
, SOL_SOCKET
, SO_REUSEADDR
,
82 (char*)&nOn
, sizeof(nOn
)) )
84 perror( "SvpElementContainer: changing socket options failed" );
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" );
101 if( listen( m_nSocket
, 0 ) )
103 perror( "SvpElementContainer: listen() failed" );
108 m_aThread
= osl_createThread( SvpContainerThread
, this );
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;
131 int nLocalSocket
= accept( m_nSocket
, NULL
, NULL
);
132 if( nLocalSocket
< 0 )
135 perror( "accept() failed" );
139 Application::PostUserEvent( LINK( this, SvpElementContainer
, processRequest
), (void*)nLocalSocket
);
146 static const char* matchType( SvpElement
* pEle
)
148 if( dynamic_cast<SvpSalBitmap
*>(pEle
) )
150 else if( dynamic_cast<SvpSalFrame
*>(pEle
) )
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 );
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();
201 SvpSalBitmap
* pSalBitmap
= new SvpSalBitmap();
202 pSalBitmap
->setBitmap( rDevice
);
203 Bitmap
aBitmap( pSalBitmap
);
204 SvMemoryStream
aStream( 256, 256 );
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
);
215 else if( aCommand
.startsWith( "quit" ) )
221 write( nFile
, aAnswer
.getStr(), aAnswer
.getLength() );
229 using namespace basebmp
;
231 SvpElement::SvpElement()
233 #if defined WITH_SVP_LISTENING
234 SvpElementContainer::get().registerElement( this );
238 SvpElement::~SvpElement()
240 #if defined WITH_SVP_LISTENING
241 SvpElementContainer::get().deregisterElement( this );
245 sal_uInt32
SvpElement::getBitCountFromScanlineFormat( sal_Int32 nFormat
)
247 sal_uInt32 nBitCount
= 1;
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
:
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
:
262 case Format::EIGHT_BIT_PAL
:
263 case Format::EIGHT_BIT_GREY
:
266 case Format::SIXTEEN_BIT_LSB_TC_MASK
:
267 case Format::SIXTEEN_BIT_MSB_TC_MASK
:
270 case Format::TWENTYFOUR_BIT_TC_MASK
:
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
:
280 OSL_FAIL( "unsupported basebmp format" );
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */