Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / headless / svpinst.cxx
blob7c94f66f04955664bfc6758bdea5aed2df43846f
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 <unistd.h>
21 #include <fcntl.h>
22 #include <sys/time.h>
23 #include <sys/poll.h>
25 #include <sal/types.h>
27 #include <vcl/apptypes.hxx>
29 #include "headless/svpinst.hxx"
30 #include "headless/svpframe.hxx"
31 #include "headless/svpdummies.hxx"
32 #include "headless/svpvd.hxx"
33 #ifdef IOS
34 #include "headless/svpgdi.hxx"
35 #include "quartz/salbmp.h"
36 #include "quartz/salgdi.h"
37 #include "quartz/salvd.h"
38 #endif
39 #include "headless/svpbmp.hxx"
41 #include <salframe.hxx>
42 #include <svdata.hxx>
43 #include <generic/gendata.hxx>
44 #include <basebmp/scanlineformats.hxx>
45 // FIXME: remove when we re-work the svp mainloop
46 #include <unx/salunxtime.h>
48 using namespace basebmp;
50 bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
52 for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
53 it != m_aFrames.end(); ++it )
55 if( *it == pFrame )
57 return true;
60 return false;
63 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
65 SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
66 SalGenericInstance( pMutex )
68 m_aTimeout.tv_sec = 0;
69 m_aTimeout.tv_usec = 0;
70 m_nTimeoutMS = 0;
72 m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
73 if (pipe (m_pTimeoutFDS) != -1)
75 // initialize 'wakeup' pipe.
76 int flags;
78 // set close-on-exec descriptor flag.
79 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
81 flags |= FD_CLOEXEC;
82 (void)fcntl(m_pTimeoutFDS[0], F_SETFD, flags);
84 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
86 flags |= FD_CLOEXEC;
87 (void)fcntl(m_pTimeoutFDS[1], F_SETFD, flags);
90 // set non-blocking I/O flag.
91 if ((flags = fcntl(m_pTimeoutFDS[0], F_GETFL)) != -1)
93 flags |= O_NONBLOCK;
94 (void)fcntl(m_pTimeoutFDS[0], F_SETFL, flags);
96 if ((flags = fcntl(m_pTimeoutFDS[1], F_GETFL)) != -1)
98 flags |= O_NONBLOCK;
99 (void)fcntl(m_pTimeoutFDS[1], F_SETFL, flags);
102 m_aEventGuard = osl_createMutex();
103 if( s_pDefaultInstance == NULL )
104 s_pDefaultInstance = this;
107 SvpSalInstance::~SvpSalInstance()
109 if( s_pDefaultInstance == this )
110 s_pDefaultInstance = NULL;
112 // close 'wakeup' pipe.
113 close (m_pTimeoutFDS[0]);
114 close (m_pTimeoutFDS[1]);
115 osl_destroyMutex( m_aEventGuard );
118 void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
120 if( osl_acquireMutex( m_aEventGuard ) )
122 m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
123 osl_releaseMutex( m_aEventGuard );
125 Wakeup();
128 bool SvpSalInstance::PostedEventsInQueue()
130 bool result = false;
131 if( osl_acquireMutex( m_aEventGuard ) )
133 result = m_aUserEvents.size() > 0;
134 osl_releaseMutex( m_aEventGuard );
136 return result;
139 void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
141 m_aFrames.remove( pFrame );
143 if( osl_acquireMutex( m_aEventGuard ) )
145 // cancel outstanding events for this frame
146 if( ! m_aUserEvents.empty() )
148 std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
151 if( it->m_pFrame == pFrame )
153 it = m_aUserEvents.erase( it );
155 else
156 ++it;
157 } while( it != m_aUserEvents.end() );
159 osl_releaseMutex( m_aEventGuard );
163 void SvpSalInstance::Wakeup()
165 OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
168 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
170 bool bRet = false;
171 if( m_aTimeout.tv_sec ) // timer is started
173 timeval aTimeOfDay;
174 gettimeofday( &aTimeOfDay, 0 );
175 if( aTimeOfDay >= m_aTimeout )
177 bRet = true;
178 if( bExecuteTimers )
180 // timed out, update timeout
181 m_aTimeout = aTimeOfDay;
182 m_aTimeout += m_nTimeoutMS;
184 osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );
186 // notify
187 ImplSVData* pSVData = ImplGetSVData();
188 if( pSVData->mpSalTimer )
190 bool idle = true; // TODO
191 pSVData->mpSalTimer->CallCallback( idle );
196 return bRet;
199 SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
201 return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
204 SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
206 return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
209 void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
211 delete pFrame;
214 SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
216 return new SvpSalObject();
219 void SvpSalInstance::DestroyObject( SalObject* pObject )
221 delete pObject;
224 #ifndef IOS
226 SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
227 long &nDX, long &nDY,
228 sal_uInt16 nBitCount,
229 const SystemGraphicsData* /* pData */ )
231 SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
232 pNew->SetSize( nDX, nDY );
233 return pNew;
236 #endif
238 SalTimer* SvpSalInstance::CreateSalTimer()
240 return new SvpSalTimer( this );
243 SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
245 return new SvpImeStatus();
248 SalSystem* SvpSalInstance::CreateSalSystem()
250 return new SvpSalSystem();
253 SalBitmap* SvpSalInstance::CreateSalBitmap()
255 #ifdef IOS
256 return new QuartzSalBitmap();
257 #else
258 return new SvpSalBitmap();
259 #endif
262 void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
264 // first, check for already queued events.
266 // release yield mutex
267 std::list< SalUserEvent > aEvents;
268 sal_uLong nAcquireCount = ReleaseYieldMutex();
269 if( osl_acquireMutex( m_aEventGuard ) )
271 if( ! m_aUserEvents.empty() )
273 if( bHandleAllCurrentEvents )
275 aEvents = m_aUserEvents;
276 m_aUserEvents.clear();
278 else
280 aEvents.push_back( m_aUserEvents.front() );
281 m_aUserEvents.pop_front();
284 osl_releaseMutex( m_aEventGuard );
286 // acquire yield mutex again
287 AcquireYieldMutex( nAcquireCount );
289 bool bEvent = !aEvents.empty();
290 if( bEvent )
292 for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
294 if ( isFrameAlive( it->m_pFrame ) )
296 it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
297 if( it->m_nEvent == SALEVENT_RESIZE )
299 // this would be a good time to post a paint
300 const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
301 pSvpFrame->PostPaint(false);
307 bEvent = CheckTimeout() || bEvent;
309 if (bWait && ! bEvent )
311 int nTimeoutMS = 0;
312 if (m_aTimeout.tv_sec) // Timer is started.
314 timeval Timeout;
315 // determine remaining timeout.
316 gettimeofday (&Timeout, 0);
317 nTimeoutMS = (m_aTimeout.tv_sec - Timeout.tv_sec) * 1000
318 + m_aTimeout.tv_usec/1000 - Timeout.tv_usec/1000;
319 if( nTimeoutMS < 0 )
320 nTimeoutMS = 0;
322 else
323 nTimeoutMS = -1; // wait until something happens
325 DoReleaseYield(nTimeoutMS);
329 void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
331 // poll
332 struct pollfd aPoll;
333 aPoll.fd = m_pTimeoutFDS[0];
334 aPoll.events = POLLIN;
335 aPoll.revents = 0;
337 // release yield mutex
338 sal_uLong nAcquireCount = ReleaseYieldMutex();
340 (void)poll( &aPoll, 1, nTimeoutMS );
342 // acquire yield mutex again
343 AcquireYieldMutex( nAcquireCount );
345 // clean up pipe
346 if( (aPoll.revents & POLLIN) != 0 )
348 int buffer;
349 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
350 continue;
354 bool SvpSalInstance::AnyInput( VclInputFlags nType )
356 if( nType & VclInputFlags::TIMER )
357 return CheckTimeout( false );
358 return false;
361 SalSession* SvpSalInstance::CreateSalSession()
363 return NULL;
366 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
368 rReturnedBytes = 1;
369 rReturnedType = AsciiCString;
370 return const_cast<char*>("");
373 void SvpSalInstance::StopTimer()
375 m_aTimeout.tv_sec = 0;
376 m_aTimeout.tv_usec = 0;
377 m_nTimeoutMS = 0;
380 void SvpSalInstance::StartTimer( sal_uLong nMS )
382 timeval aPrevTimeout (m_aTimeout);
383 gettimeofday (&m_aTimeout, 0);
385 m_nTimeoutMS = nMS;
386 m_aTimeout += m_nTimeoutMS;
388 if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
390 // Wakeup from previous timeout (or stopped timer).
391 Wakeup();
395 void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
399 SvpSalTimer::~SvpSalTimer()
403 void SvpSalTimer::Stop()
405 m_pInstance->StopTimer();
408 void SvpSalTimer::Start( sal_uLong nMS )
410 m_pInstance->StartTimer( nMS );
413 void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount,
414 Format aFormat )
416 m_aBitCountFormatMap[nBitCount] = aFormat;
419 Format SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount )
421 BitCountFormatMap::iterator aIt;
422 if ( (aIt = m_aBitCountFormatMap.find( nBitCount )) != m_aBitCountFormatMap.end() )
424 return aIt->second;
427 switch( nBitCount )
429 case 1:
430 return FORMAT_ONE_BIT_MSB_PAL;
431 case 4:
432 return FORMAT_FOUR_BIT_MSB_PAL;
433 case 8:
434 return FORMAT_EIGHT_BIT_PAL;
435 case 16:
436 #ifdef OSL_BIGENDIAN
437 return FORMAT_SIXTEEN_BIT_MSB_TC_MASK;
438 #else
439 return FORMAT_SIXTEEN_BIT_LSB_TC_MASK;
440 #endif
441 case 24:
442 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX;
443 case 32:
444 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA;
445 case 0:
446 #ifdef ANDROID
447 return FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA;
448 #else
449 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX;
450 #endif
451 default:
452 return SVP_DEFAULT_BITMAP_FORMAT;
456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */