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 using namespace basebmp
;
50 bool SvpSalInstance::isFrameAlive( const SalFrame
* pFrame
) const
52 for( std::list
< SalFrame
* >::const_iterator it
= m_aFrames
.begin();
53 it
!= m_aFrames
.end(); ++it
)
63 SvpSalInstance
* SvpSalInstance::s_pDefaultInstance
= NULL
;
65 SvpSalInstance::SvpSalInstance( SalYieldMutex
*pMutex
) :
66 SalGenericInstance( pMutex
)
68 m_aTimeout
.tv_sec
= 0;
69 m_aTimeout
.tv_usec
= 0;
72 m_pTimeoutFDS
[0] = m_pTimeoutFDS
[1] = -1;
73 if (pipe (m_pTimeoutFDS
) != -1)
75 // initialize 'wakeup' pipe.
78 // set close-on-exec descriptor flag.
79 if ((flags
= fcntl (m_pTimeoutFDS
[0], F_GETFD
)) != -1)
82 (void)fcntl(m_pTimeoutFDS
[0], F_SETFD
, flags
);
84 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFD
)) != -1)
87 (void)fcntl(m_pTimeoutFDS
[1], F_SETFD
, flags
);
90 // set non-blocking I/O flag.
91 if ((flags
= fcntl(m_pTimeoutFDS
[0], F_GETFL
)) != -1)
94 (void)fcntl(m_pTimeoutFDS
[0], F_SETFL
, flags
);
96 if ((flags
= fcntl(m_pTimeoutFDS
[1], F_GETFL
)) != -1)
99 (void)fcntl(m_pTimeoutFDS
[1], F_SETFL
, flags
);
102 m_aEventGuard
= osl_createMutex();
103 if( s_pDefaultInstance
== NULL
)
104 s_pDefaultInstance
= this;
107 SvpSalInstance::~SvpSalInstance()
109 if( s_pDefaultInstance
== this )
110 s_pDefaultInstance
= NULL
;
112 // close 'wakeup' pipe.
113 close (m_pTimeoutFDS
[0]);
114 close (m_pTimeoutFDS
[1]);
115 osl_destroyMutex( m_aEventGuard
);
118 void SvpSalInstance::PostEvent( const SalFrame
* pFrame
, void* pData
, sal_uInt16 nEvent
)
120 if( osl_acquireMutex( m_aEventGuard
) )
122 m_aUserEvents
.push_back( SalUserEvent( pFrame
, pData
, nEvent
) );
123 osl_releaseMutex( m_aEventGuard
);
128 bool SvpSalInstance::PostedEventsInQueue()
131 if( osl_acquireMutex( m_aEventGuard
) )
133 result
= m_aUserEvents
.size() > 0;
134 osl_releaseMutex( m_aEventGuard
);
139 void SvpSalInstance::deregisterFrame( SalFrame
* pFrame
)
141 m_aFrames
.remove( pFrame
);
143 if( osl_acquireMutex( m_aEventGuard
) )
145 // cancel outstanding events for this frame
146 if( ! m_aUserEvents
.empty() )
148 std::list
< SalUserEvent
>::iterator it
= m_aUserEvents
.begin();
151 if( it
->m_pFrame
== pFrame
)
153 it
= m_aUserEvents
.erase( it
);
157 } while( it
!= m_aUserEvents
.end() );
159 osl_releaseMutex( m_aEventGuard
);
163 void SvpSalInstance::Wakeup()
165 OSL_VERIFY(write (m_pTimeoutFDS
[1], "", 1) == 1);
168 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers
)
171 if( m_aTimeout
.tv_sec
) // timer is started
174 gettimeofday( &aTimeOfDay
, 0 );
175 if( aTimeOfDay
>= m_aTimeout
)
180 // timed out, update timeout
181 m_aTimeout
= aTimeOfDay
;
182 m_aTimeout
+= m_nTimeoutMS
;
184 osl::Guard
< comphelper::SolarMutex
> aGuard( mpSalYieldMutex
);
187 ImplSVData
* pSVData
= ImplGetSVData();
188 if( pSVData
->mpSalTimer
)
190 bool idle
= true; // TODO
191 pSVData
->mpSalTimer
->CallCallback( idle
);
199 SalFrame
* SvpSalInstance::CreateChildFrame( SystemParentData
* pParent
, sal_uLong nStyle
)
201 return new SvpSalFrame( this, NULL
, nStyle
, false, SVP_DEFAULT_BITMAP_FORMAT
, pParent
);
204 SalFrame
* SvpSalInstance::CreateFrame( SalFrame
* pParent
, sal_uLong nStyle
)
206 return new SvpSalFrame( this, pParent
, nStyle
, false, SVP_DEFAULT_BITMAP_FORMAT
);
209 void SvpSalInstance::DestroyFrame( SalFrame
* pFrame
)
214 SalObject
* SvpSalInstance::CreateObject( SalFrame
*, SystemWindowData
*, bool )
216 return new SvpSalObject();
219 void SvpSalInstance::DestroyObject( SalObject
* pObject
)
226 SalVirtualDevice
* SvpSalInstance::CreateVirtualDevice( SalGraphics
* /* pGraphics */,
227 long &nDX
, long &nDY
,
228 sal_uInt16 nBitCount
,
229 const SystemGraphicsData
* /* pData */ )
231 SvpSalVirtualDevice
* pNew
= new SvpSalVirtualDevice( nBitCount
);
232 pNew
->SetSize( nDX
, nDY
);
238 SalTimer
* SvpSalInstance::CreateSalTimer()
240 return new SvpSalTimer( this );
243 SalI18NImeStatus
* SvpSalInstance::CreateI18NImeStatus()
245 return new SvpImeStatus();
248 SalSystem
* SvpSalInstance::CreateSalSystem()
250 return new SvpSalSystem();
253 SalBitmap
* SvpSalInstance::CreateSalBitmap()
256 return new QuartzSalBitmap();
258 return new SvpSalBitmap();
262 void SvpSalInstance::Yield( bool bWait
, bool bHandleAllCurrentEvents
)
264 // first, check for already queued events.
266 // release yield mutex
267 std::list
< SalUserEvent
> aEvents
;
268 sal_uLong nAcquireCount
= ReleaseYieldMutex();
269 if( osl_acquireMutex( m_aEventGuard
) )
271 if( ! m_aUserEvents
.empty() )
273 if( bHandleAllCurrentEvents
)
275 aEvents
= m_aUserEvents
;
276 m_aUserEvents
.clear();
280 aEvents
.push_back( m_aUserEvents
.front() );
281 m_aUserEvents
.pop_front();
284 osl_releaseMutex( m_aEventGuard
);
286 // acquire yield mutex again
287 AcquireYieldMutex( nAcquireCount
);
289 bool bEvent
= !aEvents
.empty();
292 for( std::list
<SalUserEvent
>::const_iterator it
= aEvents
.begin(); it
!= aEvents
.end(); ++it
)
294 if ( isFrameAlive( it
->m_pFrame
) )
296 it
->m_pFrame
->CallCallback( it
->m_nEvent
, it
->m_pData
);
297 if( it
->m_nEvent
== SALEVENT_RESIZE
)
299 // this would be a good time to post a paint
300 const SvpSalFrame
* pSvpFrame
= static_cast<const SvpSalFrame
*>(it
->m_pFrame
);
301 pSvpFrame
->PostPaint(false);
307 bEvent
= CheckTimeout() || bEvent
;
309 if (bWait
&& ! bEvent
)
312 if (m_aTimeout
.tv_sec
) // Timer is started.
315 // determine remaining timeout.
316 gettimeofday (&Timeout
, 0);
317 nTimeoutMS
= (m_aTimeout
.tv_sec
- Timeout
.tv_sec
) * 1000
318 + m_aTimeout
.tv_usec
/1000 - Timeout
.tv_usec
/1000;
323 nTimeoutMS
= -1; // wait until something happens
325 DoReleaseYield(nTimeoutMS
);
329 void SvpSalInstance::DoReleaseYield( int nTimeoutMS
)
333 aPoll
.fd
= m_pTimeoutFDS
[0];
334 aPoll
.events
= POLLIN
;
337 // release yield mutex
338 sal_uLong nAcquireCount
= ReleaseYieldMutex();
340 (void)poll( &aPoll
, 1, nTimeoutMS
);
342 // acquire yield mutex again
343 AcquireYieldMutex( nAcquireCount
);
346 if( (aPoll
.revents
& POLLIN
) != 0 )
349 while (read (m_pTimeoutFDS
[0], &buffer
, sizeof(buffer
)) > 0)
354 bool SvpSalInstance::AnyInput( VclInputFlags nType
)
356 if( nType
& VclInputFlags::TIMER
)
357 return CheckTimeout( false );
361 SalSession
* SvpSalInstance::CreateSalSession()
366 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
369 rReturnedType
= AsciiCString
;
370 return const_cast<char*>("");
373 void SvpSalInstance::StopTimer()
375 m_aTimeout
.tv_sec
= 0;
376 m_aTimeout
.tv_usec
= 0;
380 void SvpSalInstance::StartTimer( sal_uLong nMS
)
382 timeval
aPrevTimeout (m_aTimeout
);
383 gettimeofday (&m_aTimeout
, 0);
386 m_aTimeout
+= m_nTimeoutMS
;
388 if ((aPrevTimeout
> m_aTimeout
) || (aPrevTimeout
.tv_sec
== 0))
390 // Wakeup from previous timeout (or stopped timer).
395 void SvpSalInstance::AddToRecentDocumentList(const OUString
&, const OUString
&, const OUString
&)
399 SvpSalTimer::~SvpSalTimer()
403 void SvpSalTimer::Stop()
405 m_pInstance
->StopTimer();
408 void SvpSalTimer::Start( sal_uLong nMS
)
410 m_pInstance
->StartTimer( nMS
);
413 void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount
,
416 m_aBitCountFormatMap
[nBitCount
] = aFormat
;
419 Format
SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount
)
421 BitCountFormatMap::iterator aIt
;
422 if ( (aIt
= m_aBitCountFormatMap
.find( nBitCount
)) != m_aBitCountFormatMap
.end() )
430 return FORMAT_ONE_BIT_MSB_PAL
;
432 return FORMAT_FOUR_BIT_MSB_PAL
;
434 return FORMAT_EIGHT_BIT_PAL
;
437 return FORMAT_SIXTEEN_BIT_MSB_TC_MASK
;
439 return FORMAT_SIXTEEN_BIT_LSB_TC_MASK
;
442 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX
;
444 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA
;
447 return FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA
;
449 return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX
;
452 return SVP_DEFAULT_BITMAP_FORMAT
;
456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */