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