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 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
);
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
)
153 if( m_aTimeout
.tv_sec
) // timer is started
156 gettimeofday( &aTimeOfDay
, 0 );
157 if( aTimeOfDay
>= m_aTimeout
)
162 // timed out, update timeout
163 m_aTimeout
= aTimeOfDay
;
164 m_aTimeout
+= m_nTimeoutMS
;
166 osl::SolarGuard
aGuard( mpSalYieldMutex
);
169 ImplSVData
* pSVData
= ImplGetSVData();
170 if( pSVData
->mpSalTimer
)
171 pSVData
->mpSalTimer
->CallCallback();
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
)
193 SalObject
* SvpSalInstance::CreateObject( SalFrame
*, SystemWindowData
*, sal_Bool
)
195 return new SvpSalObject();
198 void SvpSalInstance::DestroyObject( SalObject
* pObject
)
203 SalVirtualDevice
* SvpSalInstance::CreateVirtualDevice( SalGraphics
*,
205 sal_uInt16 nBitCount
, const SystemGraphicsData
* )
207 SvpSalVirtualDevice
* pNew
= new SvpSalVirtualDevice( nBitCount
);
208 pNew
->SetSize( nDX
, nDY
);
212 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice
* 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();
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();
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
)
287 if (m_aTimeout
.tv_sec
) // Timer is started.
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;
298 nTimeoutMS
= -1; // wait until something happens
300 DoReleaseYield(nTimeoutMS
);
304 void SvpSalInstance::DoReleaseYield( int nTimeoutMS
)
308 aPoll
.fd
= m_pTimeoutFDS
[0];
309 aPoll
.events
= POLLIN
;
312 // release yield mutex
313 sal_uLong nAcquireCount
= ReleaseYieldMutex();
315 poll( &aPoll
, 1, nTimeoutMS
);
317 // acquire yield mutex again
318 AcquireYieldMutex( nAcquireCount
);
321 if( (aPoll
.revents
& POLLIN
) != 0 )
324 while (read (m_pTimeoutFDS
[0], &buffer
, sizeof(buffer
)) > 0)
329 bool SvpSalInstance::AnyInput( sal_uInt16 nType
)
331 if( (nType
& VCL_INPUT_TIMER
) != 0 )
332 return CheckTimeout( false );
336 SalSession
* SvpSalInstance::CreateSalSession()
341 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
344 rReturnedType
= AsciiCString
;
345 return const_cast<char*>("");
352 void SvpSalInstance::StopTimer()
354 m_aTimeout
.tv_sec
= 0;
355 m_aTimeout
.tv_usec
= 0;
359 void SvpSalInstance::StartTimer( sal_uLong nMS
)
361 timeval
Timeout (m_aTimeout
); // previous timeout.
362 gettimeofday (&m_aTimeout
, 0);
365 m_aTimeout
+= m_nTimeoutMS
;
367 if ((Timeout
> m_aTimeout
) || (Timeout
.tv_sec
== 0))
369 // Wakeup from previous timeout (or stopped timer).
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: */