1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svpinst.cxx,v $
10 * $Revision: 1.5.154.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
36 #include "svpinst.hxx"
37 #include "svpframe.hxx"
38 #include "svpdummies.hxx"
42 #include <vcl/salframe.hxx>
43 #include <vcl/svdata.hxx>
44 #include <vcl/salatype.hxx>
45 #include <vcl/saldatabasic.hxx>
46 #include <sal/types.h>
48 // plugin factory function
51 SAL_DLLPUBLIC_EXPORT SalInstance
* create_SalInstance()
53 SvpSalInstance
* pInstance
= new SvpSalInstance();
54 SalData
* pSalData
= new SalData();
55 pSalData
->m_pInstance
= pInstance
;
56 SetSalData( pSalData
);
61 SvpSalInstance
* SvpSalInstance::s_pDefaultInstance
= NULL
;
63 SvpSalInstance::SvpSalInstance()
65 m_aTimeout
.tv_sec
= 0;
66 m_aTimeout
.tv_usec
= 0;
69 m_pTimeoutFDS
[0] = m_pTimeoutFDS
[1] = -1;
70 if (pipe (m_pTimeoutFDS
) != -1)
72 // initialize 'wakeup' pipe.
75 // set close-on-exec descriptor flag.
76 if ((flags
= fcntl (m_pTimeoutFDS
[0], F_GETFD
)) != -1)
79 fcntl (m_pTimeoutFDS
[0], F_SETFD
, flags
);
81 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFD
)) != -1)
84 fcntl (m_pTimeoutFDS
[1], F_SETFD
, flags
);
87 // set non-blocking I/O flag.
88 if ((flags
= fcntl (m_pTimeoutFDS
[0], F_GETFL
)) != -1)
91 fcntl (m_pTimeoutFDS
[0], F_SETFL
, flags
);
93 if ((flags
= fcntl (m_pTimeoutFDS
[1], F_GETFL
)) != -1)
96 fcntl (m_pTimeoutFDS
[1], F_SETFL
, flags
);
99 m_aEventGuard
= osl_createMutex();
100 if( s_pDefaultInstance
== NULL
)
101 s_pDefaultInstance
= this;
104 SvpSalInstance::~SvpSalInstance()
106 if( s_pDefaultInstance
== this )
107 s_pDefaultInstance
= NULL
;
109 // close 'wakeup' pipe.
110 close (m_pTimeoutFDS
[0]);
111 close (m_pTimeoutFDS
[1]);
112 osl_destroyMutex( m_aEventGuard
);
115 void SvpSalInstance::PostEvent( const SalFrame
* pFrame
, void* pData
, USHORT nEvent
)
117 if( osl_acquireMutex( m_aEventGuard
) )
119 m_aUserEvents
.push_back( SalUserEvent( pFrame
, pData
, nEvent
) );
120 osl_releaseMutex( m_aEventGuard
);
125 void SvpSalInstance::CancelEvent( const SalFrame
* pFrame
, void* pData
, USHORT nEvent
)
127 if( osl_acquireMutex( m_aEventGuard
) )
129 if( ! m_aUserEvents
.empty() )
131 std::list
< SalUserEvent
>::iterator it
= m_aUserEvents
.begin();
134 if( it
->m_pFrame
== pFrame
&&
135 it
->m_pData
== pData
&&
136 it
->m_nEvent
== nEvent
)
138 it
= m_aUserEvents
.erase( it
);
142 } while( it
!= m_aUserEvents
.end() );
144 osl_releaseMutex( m_aEventGuard
);
148 void SvpSalInstance::deregisterFrame( SalFrame
* pFrame
)
150 m_aFrames
.remove( pFrame
);
152 if( osl_acquireMutex( m_aEventGuard
) )
154 // cancel outstanding events for this frame
155 if( ! m_aUserEvents
.empty() )
157 std::list
< SalUserEvent
>::iterator it
= m_aUserEvents
.begin();
160 if( it
->m_pFrame
== pFrame
)
162 it
= m_aUserEvents
.erase( it
);
166 } while( it
!= m_aUserEvents
.end() );
168 osl_releaseMutex( m_aEventGuard
);
172 void SvpSalInstance::Wakeup()
174 write (m_pTimeoutFDS
[1], "", 1);
178 // -=-= timeval =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
179 inline int operator >= ( const timeval
&t1
, const timeval
&t2
)
181 if( t1
.tv_sec
== t2
.tv_sec
)
182 return t1
.tv_usec
>= t2
.tv_usec
;
183 return t1
.tv_sec
> t2
.tv_sec
;
185 inline timeval
&operator += ( timeval
&t1
, ULONG t2
)
187 t1
.tv_sec
+= t2
/ 1000;
188 t1
.tv_usec
+= t2
? (t2
% 1000) * 1000 : 500;
189 if( t1
.tv_usec
> 1000000 )
192 t1
.tv_usec
-= 1000000;
196 inline int operator > ( const timeval
&t1
, const timeval
&t2
)
198 if( t1
.tv_sec
== t2
.tv_sec
)
199 return t1
.tv_usec
> t2
.tv_usec
;
200 return t1
.tv_sec
> t2
.tv_sec
;
203 bool SvpSalInstance::CheckTimeout( bool bExecuteTimers
)
206 if( m_aTimeout
.tv_sec
) // timer is started
209 gettimeofday( &aTimeOfDay
, 0 );
210 if( aTimeOfDay
>= m_aTimeout
)
215 // timed out, update timeout
216 m_aTimeout
= aTimeOfDay
;
217 m_aTimeout
+= m_nTimeoutMS
;
219 ImplSVData
* pSVData
= ImplGetSVData();
220 if( pSVData
->mpSalTimer
)
221 pSVData
->mpSalTimer
->CallCallback();
228 SalFrame
* SvpSalInstance::CreateChildFrame( SystemParentData
* pParent
, ULONG nStyle
)
230 return new SvpSalFrame( this, NULL
, nStyle
, pParent
);
233 SalFrame
* SvpSalInstance::CreateFrame( SalFrame
* pParent
, ULONG nStyle
)
235 return new SvpSalFrame( this, pParent
, nStyle
);
238 void SvpSalInstance::DestroyFrame( SalFrame
* pFrame
)
243 SalObject
* SvpSalInstance::CreateObject( SalFrame
*, SystemWindowData
*, BOOL
)
245 return new SvpSalObject();
248 void SvpSalInstance::DestroyObject( SalObject
* pObject
)
253 SalVirtualDevice
* SvpSalInstance::CreateVirtualDevice( SalGraphics
*,
255 USHORT nBitCount
, const SystemGraphicsData
* )
257 SvpSalVirtualDevice
* pNew
= new SvpSalVirtualDevice( nBitCount
);
258 pNew
->SetSize( nDX
, nDY
);
262 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice
* pDevice
)
267 SalTimer
* SvpSalInstance::CreateSalTimer()
269 return new SvpSalTimer( this );
272 SalI18NImeStatus
* SvpSalInstance::CreateI18NImeStatus()
274 return new SvpImeStatus();
277 SalSystem
* SvpSalInstance::CreateSalSystem()
279 return new SvpSalSystem();
282 SalBitmap
* SvpSalInstance::CreateSalBitmap()
284 return new SvpSalBitmap();
287 vos::IMutex
* SvpSalInstance::GetYieldMutex()
289 return &m_aYieldMutex
;
292 ULONG
SvpSalInstance::ReleaseYieldMutex()
294 if ( m_aYieldMutex
.GetThreadId() ==
295 NAMESPACE_VOS(OThread
)::getCurrentIdentifier() )
297 ULONG nCount
= m_aYieldMutex
.GetAcquireCount();
301 m_aYieldMutex
.release();
311 void SvpSalInstance::AcquireYieldMutex( ULONG nCount
)
315 m_aYieldMutex
.acquire();
320 void SvpSalInstance::Yield( bool bWait
, bool bHandleAllCurrentEvents
)
322 // first, check for already queued events.
324 // release yield mutex
325 std::list
< SalUserEvent
> aEvents
;
326 ULONG nAcquireCount
= ReleaseYieldMutex();
327 if( osl_acquireMutex( m_aEventGuard
) )
329 if( ! m_aUserEvents
.empty() )
331 if( bHandleAllCurrentEvents
)
333 aEvents
= m_aUserEvents
;
334 m_aUserEvents
.clear();
338 aEvents
.push_back( m_aUserEvents
.front() );
339 m_aUserEvents
.pop_front();
342 osl_releaseMutex( m_aEventGuard
);
344 // acquire yield mutex again
345 AcquireYieldMutex( nAcquireCount
);
347 bool bEvent
= !aEvents
.empty();
350 for( std::list
<SalUserEvent
>::const_iterator it
= aEvents
.begin(); it
!= aEvents
.end(); ++it
)
352 it
->m_pFrame
->CallCallback( it
->m_nEvent
, it
->m_pData
);
353 if( it
->m_nEvent
== SALEVENT_RESIZE
)
355 // this would be a good time to post a paint
356 const SvpSalFrame
* pSvpFrame
= static_cast<const SvpSalFrame
*>(it
->m_pFrame
);
357 pSvpFrame
->PostPaint();
362 bEvent
= CheckTimeout() || bEvent
;
364 if (bWait
&& ! bEvent
)
367 if (m_aTimeout
.tv_sec
) // Timer is started.
370 // determine remaining timeout.
371 gettimeofday (&Timeout
, 0);
372 nTimeoutMS
= m_aTimeout
.tv_sec
*1000 + m_aTimeout
.tv_usec
/1000
373 - Timeout
.tv_sec
*1000 - Timeout
.tv_usec
/1000;
378 nTimeoutMS
= -1; // wait until something happens
380 // release yield mutex
381 nAcquireCount
= ReleaseYieldMutex();
384 aPoll
.fd
= m_pTimeoutFDS
[0];
385 aPoll
.events
= POLLIN
;
387 poll( &aPoll
, 1, nTimeoutMS
);
389 // acquire yield mutex again
390 AcquireYieldMutex( nAcquireCount
);
393 if( (aPoll
.revents
& POLLIN
) != 0 )
396 while (read (m_pTimeoutFDS
[0], &buffer
, sizeof(buffer
)) > 0)
402 bool SvpSalInstance::AnyInput( USHORT nType
)
404 if( (nType
& INPUT_TIMER
) != 0 )
405 return CheckTimeout( false );
409 SalMenu
* SvpSalInstance::CreateMenu( BOOL
)
414 void SvpSalInstance::DestroyMenu( SalMenu
* )
418 SalMenuItem
* SvpSalInstance::CreateMenuItem( const SalItemParams
* )
423 void SvpSalInstance::DestroyMenuItem( SalMenuItem
* )
427 SalSession
* SvpSalInstance::CreateSalSession()
432 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
435 rReturnedType
= AsciiCString
;
436 return const_cast<char*>("");
439 // -------------------------------------------------------------------------
443 // -------------------------------------------------------------------------
445 SvpSalYieldMutex::SvpSalYieldMutex()
451 void SvpSalYieldMutex::acquire()
454 mnThreadId
= NAMESPACE_VOS(OThread
)::getCurrentIdentifier();
458 void SvpSalYieldMutex::release()
460 if ( mnThreadId
== NAMESPACE_VOS(OThread
)::getCurrentIdentifier() )
469 sal_Bool
SvpSalYieldMutex::tryToAcquire()
471 if ( OMutex::tryToAcquire() )
473 mnThreadId
= NAMESPACE_VOS(OThread
)::getCurrentIdentifier();
485 void SvpSalInstance::StopTimer()
487 m_aTimeout
.tv_sec
= 0;
488 m_aTimeout
.tv_usec
= 0;
492 void SvpSalInstance::StartTimer( ULONG nMS
)
494 timeval
Timeout (m_aTimeout
); // previous timeout.
495 gettimeofday (&m_aTimeout
, 0);
498 m_aTimeout
+= m_nTimeoutMS
;
500 if ((Timeout
> m_aTimeout
) || (Timeout
.tv_sec
== 0))
502 // Wakeup from previous timeout (or stopped timer).
507 void SvpSalInstance::AddToRecentDocumentList(const rtl::OUString
&, const rtl::OUString
&)
511 SvpSalTimer::~SvpSalTimer()
515 void SvpSalTimer::Stop()
517 m_pInstance
->StopTimer();
520 void SvpSalTimer::Start( ULONG nMS
)
522 m_pInstance
->StartTimer( nMS
);