Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / vcl / headless / svpinst.cxx
blob2ce2a01c0b70362f58c2954fbc04136b56a1ad97
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 bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
50 for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
51 it != m_aFrames.end(); ++it )
53 if( *it == pFrame )
55 return true;
58 return false;
61 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
63 SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
64 SalGenericInstance( pMutex )
66 m_aTimeout.tv_sec = 0;
67 m_aTimeout.tv_usec = 0;
68 m_nTimeoutMS = 0;
70 m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
71 if (pipe (m_pTimeoutFDS) != -1)
73 // initialize 'wakeup' pipe.
74 int flags;
76 // set close-on-exec descriptor flag.
77 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
79 flags |= FD_CLOEXEC;
80 fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
82 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
84 flags |= FD_CLOEXEC;
85 fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
88 // set non-blocking I/O flag.
89 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
91 flags |= O_NONBLOCK;
92 fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
94 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
96 flags |= O_NONBLOCK;
97 fcntl (m_pTimeoutFDS[1], F_SETFL, flags);
100 m_aEventGuard = osl_createMutex();
101 if( s_pDefaultInstance == NULL )
102 s_pDefaultInstance = this;
105 SvpSalInstance::~SvpSalInstance()
107 if( s_pDefaultInstance == this )
108 s_pDefaultInstance = NULL;
110 // close 'wakeup' pipe.
111 close (m_pTimeoutFDS[0]);
112 close (m_pTimeoutFDS[1]);
113 osl_destroyMutex( m_aEventGuard );
116 void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
118 if( osl_acquireMutex( m_aEventGuard ) )
120 m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
121 osl_releaseMutex( m_aEventGuard );
123 Wakeup();
126 bool SvpSalInstance::PostedEventsInQueue()
128 bool result = false;
129 if( osl_acquireMutex( m_aEventGuard ) )
131 result = m_aUserEvents.size() > 0;
132 osl_releaseMutex( m_aEventGuard );
134 return result;
137 void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
139 m_aFrames.remove( pFrame );
141 if( osl_acquireMutex( m_aEventGuard ) )
143 // cancel outstanding events for this frame
144 if( ! m_aUserEvents.empty() )
146 std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
149 if( it->m_pFrame == pFrame )
151 it = m_aUserEvents.erase( it );
153 else
154 ++it;
155 } while( it != m_aUserEvents.end() );
157 osl_releaseMutex( m_aEventGuard );
161 void SvpSalInstance::Wakeup()
163 OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
166 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
168 bool bRet = false;
169 if( m_aTimeout.tv_sec ) // timer is started
171 timeval aTimeOfDay;
172 gettimeofday( &aTimeOfDay, 0 );
173 if( aTimeOfDay >= m_aTimeout )
175 bRet = true;
176 if( bExecuteTimers )
178 // timed out, update timeout
179 m_aTimeout = aTimeOfDay;
180 m_aTimeout += m_nTimeoutMS;
182 osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );
184 // notify
185 ImplSVData* pSVData = ImplGetSVData();
186 if( pSVData->mpSalTimer )
187 pSVData->mpSalTimer->CallCallback();
191 return bRet;
194 SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
196 return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
199 SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
201 return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
204 void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
206 delete pFrame;
209 SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
211 return new SvpSalObject();
214 void SvpSalInstance::DestroyObject( SalObject* pObject )
216 delete pObject;
219 #ifndef IOS
221 SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
222 long nDX, long nDY,
223 sal_uInt16 nBitCount,
224 const SystemGraphicsData* /* pData */ )
226 SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
227 pNew->SetSize( nDX, nDY );
228 return pNew;
231 #endif
233 SalTimer* SvpSalInstance::CreateSalTimer()
235 return new SvpSalTimer( this );
238 SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
240 return new SvpImeStatus();
243 SalSystem* SvpSalInstance::CreateSalSystem()
245 return new SvpSalSystem();
248 SalBitmap* SvpSalInstance::CreateSalBitmap()
250 #ifdef IOS
251 return new QuartzSalBitmap();
252 #else
253 return new SvpSalBitmap();
254 #endif
257 void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
259 // first, check for already queued events.
261 // release yield mutex
262 std::list< SalUserEvent > aEvents;
263 sal_uLong nAcquireCount = ReleaseYieldMutex();
264 if( osl_acquireMutex( m_aEventGuard ) )
266 if( ! m_aUserEvents.empty() )
268 if( bHandleAllCurrentEvents )
270 aEvents = m_aUserEvents;
271 m_aUserEvents.clear();
273 else
275 aEvents.push_back( m_aUserEvents.front() );
276 m_aUserEvents.pop_front();
279 osl_releaseMutex( m_aEventGuard );
281 // acquire yield mutex again
282 AcquireYieldMutex( nAcquireCount );
284 bool bEvent = !aEvents.empty();
285 if( bEvent )
287 for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
289 if ( isFrameAlive( it->m_pFrame ) )
291 it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
292 if( it->m_nEvent == SALEVENT_RESIZE )
294 // this would be a good time to post a paint
295 const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
296 pSvpFrame->PostPaint(false);
302 bEvent = CheckTimeout() || bEvent;
304 if (bWait && ! bEvent )
306 int nTimeoutMS = 0;
307 if (m_aTimeout.tv_sec) // Timer is started.
309 timeval Timeout;
310 // determine remaining timeout.
311 gettimeofday (&Timeout, 0);
312 nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
313 - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
314 if( nTimeoutMS < 0 )
315 nTimeoutMS = 0;
317 else
318 nTimeoutMS = -1; // wait until something happens
320 DoReleaseYield(nTimeoutMS);
324 void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
326 // poll
327 struct pollfd aPoll;
328 aPoll.fd = m_pTimeoutFDS[0];
329 aPoll.events = POLLIN;
330 aPoll.revents = 0;
332 // release yield mutex
333 sal_uLong nAcquireCount = ReleaseYieldMutex();
335 poll( &aPoll, 1, nTimeoutMS );
337 // acquire yield mutex again
338 AcquireYieldMutex( nAcquireCount );
340 // clean up pipe
341 if( (aPoll.revents & POLLIN) != 0 )
343 int buffer;
344 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
345 continue;
349 bool SvpSalInstance::AnyInput( sal_uInt16 nType )
351 if( (nType & VCL_INPUT_TIMER) != 0 )
352 return CheckTimeout( false );
353 return false;
356 SalSession* SvpSalInstance::CreateSalSession()
358 return NULL;
361 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
363 rReturnedBytes = 1;
364 rReturnedType = AsciiCString;
365 return const_cast<char*>("");
368 void SvpSalInstance::StopTimer()
370 m_aTimeout.tv_sec = 0;
371 m_aTimeout.tv_usec = 0;
372 m_nTimeoutMS = 0;
375 void SvpSalInstance::StartTimer( sal_uLong nMS )
377 timeval aPrevTimeout (m_aTimeout);
378 gettimeofday (&m_aTimeout, 0);
380 m_nTimeoutMS = nMS;
381 m_aTimeout += m_nTimeoutMS;
383 if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
385 // Wakeup from previous timeout (or stopped timer).
386 Wakeup();
390 void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
394 SvpSalTimer::~SvpSalTimer()
398 void SvpSalTimer::Stop()
400 m_pInstance->StopTimer();
403 void SvpSalTimer::Start( sal_uLong nMS )
405 m_pInstance->StartTimer( nMS );
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */