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"
34 #include "headless/svpgdi.hxx"
35 #include "quartz/salbmp.h"
36 #include "quartz/salgdi.h"
37 #include "quartz/salvd.h"
39 #include "headless/svpbmp.hxx"
41 #include <salframe.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
)
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;
70 m_pTimeoutFDS
[0] = m_pTimeoutFDS
[1] = -1;
71 if (pipe (m_pTimeoutFDS
) != -1)
73 // initialize 'wakeup' pipe.
76 // set close-on-exec descriptor flag.
77 if ((flags
= fcntl (m_pTimeoutFDS
[0], F_GETFD
)) != -1)
80 fcntl (m_pTimeoutFDS
[0], F_SETFD
, flags
);
82 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFD
)) != -1)
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)
92 fcntl (m_pTimeoutFDS
[0], F_SETFL
, flags
);
94 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFL
)) != -1)
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
);
126 bool SvpSalInstance::PostedEventsInQueue()
129 if( osl_acquireMutex( m_aEventGuard
) )
131 result
= m_aUserEvents
.size() > 0;
132 osl_releaseMutex( m_aEventGuard
);
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
);
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
)
169 if( m_aTimeout
.tv_sec
) // timer is started
172 gettimeofday( &aTimeOfDay
, 0 );
173 if( aTimeOfDay
>= m_aTimeout
)
178 // timed out, update timeout
179 m_aTimeout
= aTimeOfDay
;
180 m_aTimeout
+= m_nTimeoutMS
;
182 osl::Guard
< comphelper::SolarMutex
> aGuard( mpSalYieldMutex
);
185 ImplSVData
* pSVData
= ImplGetSVData();
186 if( pSVData
->mpSalTimer
)
187 pSVData
->mpSalTimer
->CallCallback();
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
)
209 SalObject
* SvpSalInstance::CreateObject( SalFrame
*, SystemWindowData
*, bool )
211 return new SvpSalObject();
214 void SvpSalInstance::DestroyObject( SalObject
* pObject
)
221 SalVirtualDevice
* SvpSalInstance::CreateVirtualDevice( SalGraphics
* /* pGraphics */,
223 sal_uInt16 nBitCount
,
224 const SystemGraphicsData
* /* pData */ )
226 SvpSalVirtualDevice
* pNew
= new SvpSalVirtualDevice( nBitCount
);
227 pNew
->SetSize( nDX
, nDY
);
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()
251 return new QuartzSalBitmap();
253 return new SvpSalBitmap();
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();
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();
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
)
307 if (m_aTimeout
.tv_sec
) // Timer is started.
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;
318 nTimeoutMS
= -1; // wait until something happens
320 DoReleaseYield(nTimeoutMS
);
324 void SvpSalInstance::DoReleaseYield( int nTimeoutMS
)
328 aPoll
.fd
= m_pTimeoutFDS
[0];
329 aPoll
.events
= POLLIN
;
332 // release yield mutex
333 sal_uLong nAcquireCount
= ReleaseYieldMutex();
335 poll( &aPoll
, 1, nTimeoutMS
);
337 // acquire yield mutex again
338 AcquireYieldMutex( nAcquireCount
);
341 if( (aPoll
.revents
& POLLIN
) != 0 )
344 while (read (m_pTimeoutFDS
[0], &buffer
, sizeof(buffer
)) > 0)
349 bool SvpSalInstance::AnyInput( sal_uInt16 nType
)
351 if( (nType
& VCL_INPUT_TIMER
) != 0 )
352 return CheckTimeout( false );
356 SalSession
* SvpSalInstance::CreateSalSession()
361 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
364 rReturnedType
= AsciiCString
;
365 return const_cast<char*>("");
368 void SvpSalInstance::StopTimer()
370 m_aTimeout
.tv_sec
= 0;
371 m_aTimeout
.tv_usec
= 0;
375 void SvpSalInstance::StartTimer( sal_uLong nMS
)
377 timeval
aPrevTimeout (m_aTimeout
);
378 gettimeofday (&m_aTimeout
, 0);
381 m_aTimeout
+= m_nTimeoutMS
;
383 if ((aPrevTimeout
> m_aTimeout
) || (aPrevTimeout
.tv_sec
== 0))
385 // Wakeup from previous timeout (or stopped timer).
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: */