1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
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
)
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;
65 m_pTimeoutFDS
[0] = m_pTimeoutFDS
[1] = -1;
66 if (pipe (m_pTimeoutFDS
) != -1)
68 // initialize 'wakeup' pipe.
71 // set close-on-exec descriptor flag.
72 if ((flags
= fcntl (m_pTimeoutFDS
[0], F_GETFD
)) != -1)
75 fcntl (m_pTimeoutFDS
[0], F_SETFD
, flags
);
77 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFD
)) != -1)
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)
87 fcntl (m_pTimeoutFDS
[0], F_SETFL
, flags
);
89 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFL
)) != -1)
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
);
121 bool SvpSalInstance::PostedEventsInQueue()
124 if( osl_acquireMutex( m_aEventGuard
) )
126 result
= m_aUserEvents
.size() > 0;
127 osl_releaseMutex( m_aEventGuard
);
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
);
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
)
164 if( m_aTimeout
.tv_sec
) // timer is started
167 gettimeofday( &aTimeOfDay
, 0 );
168 if( aTimeOfDay
>= m_aTimeout
)
173 // timed out, update timeout
174 m_aTimeout
= aTimeOfDay
;
175 m_aTimeout
+= m_nTimeoutMS
;
177 osl::Guard
< comphelper::SolarMutex
> aGuard( mpSalYieldMutex
);
180 ImplSVData
* pSVData
= ImplGetSVData();
181 if( pSVData
->mpSalTimer
)
182 pSVData
->mpSalTimer
->CallCallback();
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
)
204 SalObject
* SvpSalInstance::CreateObject( SalFrame
*, SystemWindowData
*, sal_Bool
)
206 return new SvpSalObject();
209 void SvpSalInstance::DestroyObject( SalObject
* pObject
)
214 SalVirtualDevice
* SvpSalInstance::CreateVirtualDevice( SalGraphics
*,
216 sal_uInt16 nBitCount
, const SystemGraphicsData
* )
218 SvpSalVirtualDevice
* pNew
= new SvpSalVirtualDevice( nBitCount
);
219 pNew
->SetSize( nDX
, nDY
);
223 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice
* 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();
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();
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
)
298 if (m_aTimeout
.tv_sec
) // Timer is started.
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;
309 nTimeoutMS
= -1; // wait until something happens
311 DoReleaseYield(nTimeoutMS
);
315 void SvpSalInstance::DoReleaseYield( int nTimeoutMS
)
319 aPoll
.fd
= m_pTimeoutFDS
[0];
320 aPoll
.events
= POLLIN
;
323 // release yield mutex
324 sal_uLong nAcquireCount
= ReleaseYieldMutex();
326 poll( &aPoll
, 1, nTimeoutMS
);
328 // acquire yield mutex again
329 AcquireYieldMutex( nAcquireCount
);
332 if( (aPoll
.revents
& POLLIN
) != 0 )
335 while (read (m_pTimeoutFDS
[0], &buffer
, sizeof(buffer
)) > 0)
340 bool SvpSalInstance::AnyInput( sal_uInt16 nType
)
342 if( (nType
& VCL_INPUT_TIMER
) != 0 )
343 return CheckTimeout( false );
347 SalSession
* SvpSalInstance::CreateSalSession()
352 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
355 rReturnedType
= AsciiCString
;
356 return const_cast<char*>("");
363 void SvpSalInstance::StopTimer()
365 m_aTimeout
.tv_sec
= 0;
366 m_aTimeout
.tv_usec
= 0;
370 void SvpSalInstance::StartTimer( sal_uLong nMS
)
372 timeval
aPrevTimeout (m_aTimeout
);
373 gettimeofday (&m_aTimeout
, 0);
376 m_aTimeout
+= m_nTimeoutMS
;
378 if ((aPrevTimeout
> m_aTimeout
) || (aPrevTimeout
.tv_sec
== 0))
380 // Wakeup from previous timeout (or stopped timer).
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: */