Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / vcl / headless / svpinst.cxx
blob340f4f4601a1e8ff16f13583f0fe35ffd1c89d31
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 #include "headless/svpbmp.hxx"
35 #include <salframe.hxx>
36 #include <svdata.hxx>
37 #include <generic/gendata.hxx>
38 #include <basebmp/scanlineformats.hxx>
39 #include <vcl/solarmutex.hxx>
40 // FIXME: remove when we re-work the svp mainloop
41 #include <unx/salunxtime.h>
43 bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
45 for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
46 it != m_aFrames.end(); ++it )
48 if( *it == pFrame )
50 return true;
53 return false;
56 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
58 SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
59 SalGenericInstance( pMutex )
61 m_aTimeout.tv_sec = 0;
62 m_aTimeout.tv_usec = 0;
63 m_nTimeoutMS = 0;
65 m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
66 if (pipe (m_pTimeoutFDS) != -1)
68 // initialize 'wakeup' pipe.
69 int flags;
71 // set close-on-exec descriptor flag.
72 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
74 flags |= FD_CLOEXEC;
75 fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
77 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
79 flags |= FD_CLOEXEC;
80 fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
83 // set non-blocking I/O flag.
84 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
86 flags |= O_NONBLOCK;
87 fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
89 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
91 flags |= O_NONBLOCK;
92 fcntl (m_pTimeoutFDS[1], F_SETFL, flags);
95 m_aEventGuard = osl_createMutex();
96 if( s_pDefaultInstance == NULL )
97 s_pDefaultInstance = this;
100 SvpSalInstance::~SvpSalInstance()
102 if( s_pDefaultInstance == this )
103 s_pDefaultInstance = NULL;
105 // close 'wakeup' pipe.
106 close (m_pTimeoutFDS[0]);
107 close (m_pTimeoutFDS[1]);
108 osl_destroyMutex( m_aEventGuard );
111 void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
113 if( osl_acquireMutex( m_aEventGuard ) )
115 m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
116 osl_releaseMutex( m_aEventGuard );
118 Wakeup();
121 bool SvpSalInstance::PostedEventsInQueue()
123 bool result = false;
124 if( osl_acquireMutex( m_aEventGuard ) )
126 result = m_aUserEvents.size() > 0;
127 osl_releaseMutex( m_aEventGuard );
129 return result;
132 void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
134 m_aFrames.remove( pFrame );
136 if( osl_acquireMutex( m_aEventGuard ) )
138 // cancel outstanding events for this frame
139 if( ! m_aUserEvents.empty() )
141 std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
144 if( it->m_pFrame == pFrame )
146 it = m_aUserEvents.erase( it );
148 else
149 ++it;
150 } while( it != m_aUserEvents.end() );
152 osl_releaseMutex( m_aEventGuard );
156 void SvpSalInstance::Wakeup()
158 OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
161 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
163 bool bRet = false;
164 if( m_aTimeout.tv_sec ) // timer is started
166 timeval aTimeOfDay;
167 gettimeofday( &aTimeOfDay, 0 );
168 if( aTimeOfDay >= m_aTimeout )
170 bRet = true;
171 if( bExecuteTimers )
173 // timed out, update timeout
174 m_aTimeout = aTimeOfDay;
175 m_aTimeout += m_nTimeoutMS;
177 osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );
179 // notify
180 ImplSVData* pSVData = ImplGetSVData();
181 if( pSVData->mpSalTimer )
182 pSVData->mpSalTimer->CallCallback();
186 return bRet;
189 SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
191 return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
194 SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
196 return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
199 void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
201 delete pFrame;
204 SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, sal_Bool )
206 return new SvpSalObject();
209 void SvpSalInstance::DestroyObject( SalObject* pObject )
211 delete pObject;
214 SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics*,
215 long nDX, long nDY,
216 sal_uInt16 nBitCount, const SystemGraphicsData* )
218 SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
219 pNew->SetSize( nDX, nDY );
220 return pNew;
223 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
225 delete pDevice;
228 SalTimer* SvpSalInstance::CreateSalTimer()
230 return new SvpSalTimer( this );
233 SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
235 return new SvpImeStatus();
238 SalSystem* SvpSalInstance::CreateSalSystem()
240 return new SvpSalSystem();
243 SalBitmap* SvpSalInstance::CreateSalBitmap()
245 return new SvpSalBitmap();
248 void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
250 // first, check for already queued events.
252 // release yield mutex
253 std::list< SalUserEvent > aEvents;
254 sal_uLong nAcquireCount = ReleaseYieldMutex();
255 if( osl_acquireMutex( m_aEventGuard ) )
257 if( ! m_aUserEvents.empty() )
259 if( bHandleAllCurrentEvents )
261 aEvents = m_aUserEvents;
262 m_aUserEvents.clear();
264 else
266 aEvents.push_back( m_aUserEvents.front() );
267 m_aUserEvents.pop_front();
270 osl_releaseMutex( m_aEventGuard );
272 // acquire yield mutex again
273 AcquireYieldMutex( nAcquireCount );
275 bool bEvent = !aEvents.empty();
276 if( bEvent )
278 for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
280 if ( isFrameAlive( it->m_pFrame ) )
282 it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
283 if( it->m_nEvent == SALEVENT_RESIZE )
285 // this would be a good time to post a paint
286 const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
287 pSvpFrame->PostPaint(false);
293 bEvent = CheckTimeout() || bEvent;
295 if (bWait && ! bEvent )
297 int nTimeoutMS = 0;
298 if (m_aTimeout.tv_sec) // Timer is started.
300 timeval Timeout;
301 // determine remaining timeout.
302 gettimeofday (&Timeout, 0);
303 nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
304 - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
305 if( nTimeoutMS < 0 )
306 nTimeoutMS = 0;
308 else
309 nTimeoutMS = -1; // wait until something happens
311 DoReleaseYield(nTimeoutMS);
315 void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
317 // poll
318 struct pollfd aPoll;
319 aPoll.fd = m_pTimeoutFDS[0];
320 aPoll.events = POLLIN;
321 aPoll.revents = 0;
323 // release yield mutex
324 sal_uLong nAcquireCount = ReleaseYieldMutex();
326 poll( &aPoll, 1, nTimeoutMS );
328 // acquire yield mutex again
329 AcquireYieldMutex( nAcquireCount );
331 // clean up pipe
332 if( (aPoll.revents & POLLIN) != 0 )
334 int buffer;
335 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
336 continue;
340 bool SvpSalInstance::AnyInput( sal_uInt16 nType )
342 if( (nType & VCL_INPUT_TIMER) != 0 )
343 return CheckTimeout( false );
344 return false;
347 SalSession* SvpSalInstance::CreateSalSession()
349 return NULL;
352 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
354 rReturnedBytes = 1;
355 rReturnedType = AsciiCString;
356 return const_cast<char*>("");
359 // ---------------
360 // - SalTimer -
361 // ---------------
363 void SvpSalInstance::StopTimer()
365 m_aTimeout.tv_sec = 0;
366 m_aTimeout.tv_usec = 0;
367 m_nTimeoutMS = 0;
370 void SvpSalInstance::StartTimer( sal_uLong nMS )
372 timeval aPrevTimeout (m_aTimeout);
373 gettimeofday (&m_aTimeout, 0);
375 m_nTimeoutMS = nMS;
376 m_aTimeout += m_nTimeoutMS;
378 if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
380 // Wakeup from previous timeout (or stopped timer).
381 Wakeup();
385 void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
389 SvpSalTimer::~SvpSalTimer()
393 void SvpSalTimer::Stop()
395 m_pInstance->StopTimer();
398 void SvpSalTimer::Start( sal_uLong nMS )
400 m_pInstance->StartTimer( nMS );
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */