Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / vcl / headless / svpinst.cxx
blob6d7c6a900817280cf524d8dc506e582f4d5aca2f
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 void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
123 m_aFrames.remove( pFrame );
125 if( osl_acquireMutex( m_aEventGuard ) )
127 // cancel outstanding events for this frame
128 if( ! m_aUserEvents.empty() )
130 std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
133 if( it->m_pFrame == pFrame )
135 it = m_aUserEvents.erase( it );
137 else
138 ++it;
139 } while( it != m_aUserEvents.end() );
141 osl_releaseMutex( m_aEventGuard );
145 void SvpSalInstance::Wakeup()
147 OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
150 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
152 bool bRet = false;
153 if( m_aTimeout.tv_sec ) // timer is started
155 timeval aTimeOfDay;
156 gettimeofday( &aTimeOfDay, 0 );
157 if( aTimeOfDay >= m_aTimeout )
159 bRet = true;
160 if( bExecuteTimers )
162 // timed out, update timeout
163 m_aTimeout = aTimeOfDay;
164 m_aTimeout += m_nTimeoutMS;
166 osl::SolarGuard aGuard( mpSalYieldMutex );
168 // notify
169 ImplSVData* pSVData = ImplGetSVData();
170 if( pSVData->mpSalTimer )
171 pSVData->mpSalTimer->CallCallback();
175 return bRet;
178 SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
180 return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
183 SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
185 return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
188 void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
190 delete pFrame;
193 SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, sal_Bool )
195 return new SvpSalObject();
198 void SvpSalInstance::DestroyObject( SalObject* pObject )
200 delete pObject;
203 SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics*,
204 long nDX, long nDY,
205 sal_uInt16 nBitCount, const SystemGraphicsData* )
207 SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
208 pNew->SetSize( nDX, nDY );
209 return pNew;
212 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
214 delete pDevice;
217 SalTimer* SvpSalInstance::CreateSalTimer()
219 return new SvpSalTimer( this );
222 SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
224 return new SvpImeStatus();
227 SalSystem* SvpSalInstance::CreateSalSystem()
229 return new SvpSalSystem();
232 SalBitmap* SvpSalInstance::CreateSalBitmap()
234 return new SvpSalBitmap();
237 void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
239 // first, check for already queued events.
241 // release yield mutex
242 std::list< SalUserEvent > aEvents;
243 sal_uLong nAcquireCount = ReleaseYieldMutex();
244 if( osl_acquireMutex( m_aEventGuard ) )
246 if( ! m_aUserEvents.empty() )
248 if( bHandleAllCurrentEvents )
250 aEvents = m_aUserEvents;
251 m_aUserEvents.clear();
253 else
255 aEvents.push_back( m_aUserEvents.front() );
256 m_aUserEvents.pop_front();
259 osl_releaseMutex( m_aEventGuard );
261 // acquire yield mutex again
262 AcquireYieldMutex( nAcquireCount );
264 bool bEvent = !aEvents.empty();
265 if( bEvent )
267 for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
269 if ( isFrameAlive( it->m_pFrame ) )
271 it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
272 if( it->m_nEvent == SALEVENT_RESIZE )
274 // this would be a good time to post a paint
275 const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
276 pSvpFrame->PostPaint(false);
282 bEvent = CheckTimeout() || bEvent;
284 if (bWait && ! bEvent )
286 int nTimeoutMS = 0;
287 if (m_aTimeout.tv_sec) // Timer is started.
289 timeval Timeout;
290 // determine remaining timeout.
291 gettimeofday (&Timeout, 0);
292 nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
293 - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
294 if( nTimeoutMS < 0 )
295 nTimeoutMS = 0;
297 else
298 nTimeoutMS = -1; // wait until something happens
300 DoReleaseYield(nTimeoutMS);
304 void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
306 // poll
307 struct pollfd aPoll;
308 aPoll.fd = m_pTimeoutFDS[0];
309 aPoll.events = POLLIN;
310 aPoll.revents = 0;
312 // release yield mutex
313 sal_uLong nAcquireCount = ReleaseYieldMutex();
315 poll( &aPoll, 1, nTimeoutMS );
317 // acquire yield mutex again
318 AcquireYieldMutex( nAcquireCount );
320 // clean up pipe
321 if( (aPoll.revents & POLLIN) != 0 )
323 int buffer;
324 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
325 continue;
329 bool SvpSalInstance::AnyInput( sal_uInt16 nType )
331 if( (nType & VCL_INPUT_TIMER) != 0 )
332 return CheckTimeout( false );
333 return false;
336 SalSession* SvpSalInstance::CreateSalSession()
338 return NULL;
341 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
343 rReturnedBytes = 1;
344 rReturnedType = AsciiCString;
345 return const_cast<char*>("");
348 // ---------------
349 // - SalTimer -
350 // ---------------
352 void SvpSalInstance::StopTimer()
354 m_aTimeout.tv_sec = 0;
355 m_aTimeout.tv_usec = 0;
356 m_nTimeoutMS = 0;
359 void SvpSalInstance::StartTimer( sal_uLong nMS )
361 timeval Timeout (m_aTimeout); // previous timeout.
362 gettimeofday (&m_aTimeout, 0);
364 m_nTimeoutMS = nMS;
365 m_aTimeout += m_nTimeoutMS;
367 if ((Timeout > m_aTimeout) || (Timeout.tv_sec == 0))
369 // Wakeup from previous timeout (or stopped timer).
370 Wakeup();
374 void SvpSalInstance::AddToRecentDocumentList(const rtl::OUString&, const rtl::OUString&)
378 SvpSalTimer::~SvpSalTimer()
382 void SvpSalTimer::Stop()
384 m_pInstance->StopTimer();
387 void SvpSalTimer::Start( sal_uLong nMS )
389 m_pInstance->StartTimer( nMS );
392 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */