xref: /aoo42x/main/vcl/unx/headless/svpelement.cxx (revision 9f62ea84)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "svpelement.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <basebmp/scanlineformats.hxx>
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #if defined WITH_SVP_LISTENING
30cdf0e10cSrcweir #include <osl/thread.h>
31cdf0e10cSrcweir #include <vcl/svapp.hxx>
32cdf0e10cSrcweir #include <rtl/strbuf.hxx>
33cdf0e10cSrcweir #include <vcl/bitmap.hxx>
34cdf0e10cSrcweir #include <tools/stream.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "svpvd.hxx"
37cdf0e10cSrcweir #include "svpbmp.hxx"
38cdf0e10cSrcweir #include "svpframe.hxx"
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <list>
41cdf0e10cSrcweir #include <hash_map>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <sys/types.h>
44cdf0e10cSrcweir #include <sys/socket.h>
45cdf0e10cSrcweir #include <netinet/ip.h>
46cdf0e10cSrcweir #include <stdio.h>
47cdf0e10cSrcweir #include <errno.h>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir using namespace basegfx;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir class SvpElementContainer
52cdf0e10cSrcweir {
53cdf0e10cSrcweir     std::list< SvpElement* >        m_aElements;
54cdf0e10cSrcweir     int                             m_nSocket;
55cdf0e10cSrcweir     oslThread                       m_aThread;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir     SvpElementContainer();
58cdf0e10cSrcweir     ~SvpElementContainer();
59cdf0e10cSrcweir     public:
registerElement(SvpElement * pElement)60cdf0e10cSrcweir     void registerElement( SvpElement* pElement ) { m_aElements.push_back(pElement); }
deregisterElement(SvpElement * pElement)61cdf0e10cSrcweir     void deregisterElement( SvpElement* pElement ) { m_aElements.remove(pElement); }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir     void run();
64cdf0e10cSrcweir     DECL_LINK(processRequest,void*);
65cdf0e10cSrcweir 
66cdf0e10cSrcweir     static SvpElementContainer& get();
67cdf0e10cSrcweir };
68cdf0e10cSrcweir 
69cdf0e10cSrcweir extern "C" void SAL_CALL SvpContainerThread( void* );
70cdf0e10cSrcweir 
get()71cdf0e10cSrcweir SvpElementContainer& SvpElementContainer::get()
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     static SvpElementContainer* pInstance = new SvpElementContainer();
74cdf0e10cSrcweir     return *pInstance;
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
SvpElementContainer()77cdf0e10cSrcweir SvpElementContainer::SvpElementContainer()
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     static const char* pEnv = getenv("SVP_LISTENER_PORT");
80cdf0e10cSrcweir     int nPort = (pEnv && *pEnv) ? atoi(pEnv) : 8000;
81cdf0e10cSrcweir     m_nSocket = socket( PF_INET, SOCK_STREAM, 0 );
82cdf0e10cSrcweir     if( m_nSocket >= 0)
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         int nOn = 1;
85cdf0e10cSrcweir         if( setsockopt(m_nSocket, SOL_SOCKET, SO_REUSEADDR,
86cdf0e10cSrcweir                        (char*)&nOn, sizeof(nOn)) )
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             perror( "SvpElementContainer: changing socket options failed" );
89cdf0e10cSrcweir             close( m_nSocket );
90cdf0e10cSrcweir         }
91cdf0e10cSrcweir         else
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             struct sockaddr_in addr;
94cdf0e10cSrcweir             memset(&addr, 0, sizeof(struct sockaddr_in));
95cdf0e10cSrcweir             addr.sin_family = AF_INET;
96cdf0e10cSrcweir             addr.sin_port = htons(nPort);
97cdf0e10cSrcweir             addr.sin_addr.s_addr = INADDR_ANY;
98cdf0e10cSrcweir             if( bind(m_nSocket,(struct sockaddr*)&addr,sizeof(addr)) )
99cdf0e10cSrcweir             {
100cdf0e10cSrcweir                 perror( "SvpElementContainer: bind() failed" );
101cdf0e10cSrcweir                 close( m_nSocket );
102cdf0e10cSrcweir             }
103cdf0e10cSrcweir             else
104cdf0e10cSrcweir             {
105cdf0e10cSrcweir                 if( listen( m_nSocket, 0 ) )
106cdf0e10cSrcweir                 {
107cdf0e10cSrcweir                     perror( "SvpElementContainer: listen() failed" );
108cdf0e10cSrcweir                     close(m_nSocket);
109cdf0e10cSrcweir                 }
110cdf0e10cSrcweir                 else
111cdf0e10cSrcweir                 {
112cdf0e10cSrcweir                     m_aThread = osl_createThread( SvpContainerThread, this );
113cdf0e10cSrcweir                 }
114cdf0e10cSrcweir             }
115cdf0e10cSrcweir         }
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir     else
118cdf0e10cSrcweir         perror( "SvpElementContainer: socket() failed\n" );
119cdf0e10cSrcweir }
120cdf0e10cSrcweir 
~SvpElementContainer()121cdf0e10cSrcweir SvpElementContainer::~SvpElementContainer()
122cdf0e10cSrcweir {
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
SvpContainerThread(void * pSvpContainer)125cdf0e10cSrcweir void SAL_CALL SvpContainerThread(void* pSvpContainer)
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     ((SvpElementContainer*)pSvpContainer)->run();
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
run()130cdf0e10cSrcweir void SvpElementContainer::run()
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     bool bRun = m_nSocket != 0;
133cdf0e10cSrcweir     while( bRun )
134cdf0e10cSrcweir     {
135cdf0e10cSrcweir         int nLocalSocket = accept( m_nSocket, NULL, NULL );
136cdf0e10cSrcweir         if( nLocalSocket < 0 )
137cdf0e10cSrcweir         {
138cdf0e10cSrcweir             bRun = false;
139cdf0e10cSrcweir             perror( "accept() failed" );
140cdf0e10cSrcweir         }
141cdf0e10cSrcweir         else
142cdf0e10cSrcweir         {
143cdf0e10cSrcweir             Application::PostUserEvent( LINK( this, SvpElementContainer, processRequest ), (void*)nLocalSocket );
144cdf0e10cSrcweir         }
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir     if( m_nSocket )
147cdf0e10cSrcweir         close( m_nSocket );
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
matchType(SvpElement * pEle)150cdf0e10cSrcweir static const char* matchType( SvpElement* pEle )
151cdf0e10cSrcweir {
152cdf0e10cSrcweir     if( dynamic_cast<SvpSalBitmap*>(pEle) )
153cdf0e10cSrcweir         return "Bitmap";
154cdf0e10cSrcweir     else if( dynamic_cast<SvpSalFrame*>(pEle) )
155cdf0e10cSrcweir         return "Frame";
156cdf0e10cSrcweir     else if( dynamic_cast<SvpSalVirtualDevice*>(pEle) )
157cdf0e10cSrcweir         return "VirtualDevice";
158cdf0e10cSrcweir     return typeid(*pEle).name();
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
IMPL_LINK(SvpElementContainer,processRequest,void *,pSocket)161cdf0e10cSrcweir IMPL_LINK( SvpElementContainer, processRequest, void*, pSocket )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     int nFile = (int)pSocket;
164cdf0e10cSrcweir 
165cdf0e10cSrcweir     rtl::OStringBuffer aBuf( 256 ), aAnswer( 256 );
166cdf0e10cSrcweir     char c;
167cdf0e10cSrcweir     while( read( nFile, &c, 1 ) && c != '\n' )
168cdf0e10cSrcweir         aBuf.append( sal_Char(c) );
169cdf0e10cSrcweir     rtl::OString aCommand( aBuf.makeStringAndClear() );
170cdf0e10cSrcweir     if( aCommand.compareTo( "list", 4 ) == 0 )
171cdf0e10cSrcweir     {
172cdf0e10cSrcweir         std::hash_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash > aMap;
173cdf0e10cSrcweir         for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
174cdf0e10cSrcweir              it != m_aElements.end(); ++it )
175cdf0e10cSrcweir         {
176cdf0e10cSrcweir             std::list<SvpElement*>& rList = aMap[matchType(*it)];
177cdf0e10cSrcweir             rList.push_back( *it );
178cdf0e10cSrcweir         }
179cdf0e10cSrcweir         for( std::hash_map< rtl::OString, std::list<SvpElement*>, rtl::OStringHash>::const_iterator hash_it = aMap.begin();
180cdf0e10cSrcweir              hash_it != aMap.end(); ++hash_it )
181cdf0e10cSrcweir         {
182cdf0e10cSrcweir             aAnswer.append( "ElementType: " );
183cdf0e10cSrcweir             aAnswer.append( hash_it->first );
184cdf0e10cSrcweir             aAnswer.append( '\n' );
185cdf0e10cSrcweir             for( std::list<SvpElement*>::const_iterator it = hash_it->second.begin();
186cdf0e10cSrcweir                  it != hash_it->second.end(); ++it )
187cdf0e10cSrcweir             {
188cdf0e10cSrcweir                 aAnswer.append( sal_Int64(reinterpret_cast<sal_uInt32>(*it)), 16 );
189cdf0e10cSrcweir                 aAnswer.append( '\n' );
190cdf0e10cSrcweir             }
191cdf0e10cSrcweir         }
192cdf0e10cSrcweir     }
193cdf0e10cSrcweir     else if( aCommand.compareTo( "get", 3 ) == 0 )
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir         sal_IntPtr aId = aCommand.copy( 3 ).toInt64( 16 );
196cdf0e10cSrcweir         SvpElement* pElement = reinterpret_cast<SvpElement*>(aId);
197cdf0e10cSrcweir         for( std::list< SvpElement* >::const_iterator it = m_aElements.begin();
198cdf0e10cSrcweir              it != m_aElements.end(); ++it )
199cdf0e10cSrcweir         {
200cdf0e10cSrcweir             if( *it == pElement )
201cdf0e10cSrcweir             {
202cdf0e10cSrcweir                 const basebmp::BitmapDeviceSharedPtr& rDevice = pElement->getDevice();
203cdf0e10cSrcweir                 if( rDevice.get() )
204cdf0e10cSrcweir                 {
205cdf0e10cSrcweir                     SvpSalBitmap* pSalBitmap = new SvpSalBitmap();
206cdf0e10cSrcweir                     pSalBitmap->setBitmap( rDevice );
207cdf0e10cSrcweir                     Bitmap aBitmap( pSalBitmap );
208cdf0e10cSrcweir                     SvMemoryStream aStream( 256, 256 );
209cdf0e10cSrcweir                     aStream << aBitmap;
210cdf0e10cSrcweir                     aStream.Seek( STREAM_SEEK_TO_END );
211cdf0e10cSrcweir                     int nBytes = aStream.Tell();
212cdf0e10cSrcweir                     aStream.Seek( STREAM_SEEK_TO_BEGIN );
213cdf0e10cSrcweir                     aAnswer.append( (const sal_Char*)aStream.GetData(), nBytes );
214cdf0e10cSrcweir                 }
215cdf0e10cSrcweir                 break;
216cdf0e10cSrcweir             }
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir     else if( aCommand.compareTo( "quit", 4 ) == 0 )
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         Application::Quit();
222cdf0e10cSrcweir         close( m_nSocket );
223cdf0e10cSrcweir         m_nSocket = 0;
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir     write( nFile, aAnswer.getStr(), aAnswer.getLength() );
226cdf0e10cSrcweir     close( nFile );
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     return 0;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir #endif
232cdf0e10cSrcweir 
233cdf0e10cSrcweir using namespace basebmp;
234cdf0e10cSrcweir 
SvpElement()235cdf0e10cSrcweir SvpElement::SvpElement()
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     #if defined WITH_SVP_LISTENING
238cdf0e10cSrcweir     SvpElementContainer::get().registerElement( this );
239cdf0e10cSrcweir     #endif
240cdf0e10cSrcweir }
241cdf0e10cSrcweir 
~SvpElement()242cdf0e10cSrcweir SvpElement::~SvpElement()
243cdf0e10cSrcweir {
244cdf0e10cSrcweir     #if defined WITH_SVP_LISTENING
245cdf0e10cSrcweir     SvpElementContainer::get().deregisterElement( this );
246cdf0e10cSrcweir     #endif
247cdf0e10cSrcweir }
248cdf0e10cSrcweir 
getBitCountFromScanlineFormat(sal_Int32 nFormat)249cdf0e10cSrcweir sal_uInt32 SvpElement::getBitCountFromScanlineFormat( sal_Int32 nFormat )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir     sal_uInt32 nBitCount = 1;
252cdf0e10cSrcweir     switch( nFormat )
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir         case Format::ONE_BIT_MSB_GREY:
255cdf0e10cSrcweir         case Format::ONE_BIT_LSB_GREY:
256cdf0e10cSrcweir         case Format::ONE_BIT_MSB_PAL:
257cdf0e10cSrcweir         case Format::ONE_BIT_LSB_PAL:
258cdf0e10cSrcweir             nBitCount = 1;
259cdf0e10cSrcweir             break;
260cdf0e10cSrcweir         case Format::FOUR_BIT_MSB_GREY:
261cdf0e10cSrcweir         case Format::FOUR_BIT_LSB_GREY:
262cdf0e10cSrcweir         case Format::FOUR_BIT_MSB_PAL:
263cdf0e10cSrcweir         case Format::FOUR_BIT_LSB_PAL:
264cdf0e10cSrcweir             nBitCount = 4;
265cdf0e10cSrcweir             break;
266cdf0e10cSrcweir         case Format::EIGHT_BIT_PAL:
267cdf0e10cSrcweir         case Format::EIGHT_BIT_GREY:
268cdf0e10cSrcweir             nBitCount = 8;
269cdf0e10cSrcweir             break;
270cdf0e10cSrcweir         case Format::SIXTEEN_BIT_LSB_TC_MASK:
271cdf0e10cSrcweir         case Format::SIXTEEN_BIT_MSB_TC_MASK:
272cdf0e10cSrcweir             nBitCount = 16;
273cdf0e10cSrcweir             break;
274cdf0e10cSrcweir         case Format::TWENTYFOUR_BIT_TC_MASK:
275cdf0e10cSrcweir             nBitCount = 24;
276cdf0e10cSrcweir             break;
277cdf0e10cSrcweir         case Format::THIRTYTWO_BIT_TC_MASK:
278cdf0e10cSrcweir             nBitCount = 32;
279cdf0e10cSrcweir             break;
280cdf0e10cSrcweir         default:
281cdf0e10cSrcweir         DBG_ERROR( "unsupported basebmp format" );
282cdf0e10cSrcweir         break;
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir     return nBitCount;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 
288