Update ooo320-m1
[ooovba.git] / vcl / unx / headless / svpinst.cxx
blob2f370adb0bf255a4d1d50c7b02e5a3506a625ecb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 ************************************************************************/
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/time.h>
34 #include <sys/poll.h>
36 #include "svpinst.hxx"
37 #include "svpframe.hxx"
38 #include "svpdummies.hxx"
39 #include "svpvd.hxx"
40 #include "svpbmp.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
49 extern "C"
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 );
57 return pInstance;
61 SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
63 SvpSalInstance::SvpSalInstance()
65 m_aTimeout.tv_sec = 0;
66 m_aTimeout.tv_usec = 0;
67 m_nTimeoutMS = 0;
69 m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
70 if (pipe (m_pTimeoutFDS) != -1)
72 // initialize 'wakeup' pipe.
73 int flags;
75 // set close-on-exec descriptor flag.
76 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
78 flags |= FD_CLOEXEC;
79 fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
81 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
83 flags |= FD_CLOEXEC;
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)
90 flags |= O_NONBLOCK;
91 fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
93 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
95 flags |= O_NONBLOCK;
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 );
122 Wakeup();
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 );
140 else
141 ++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 );
164 else
165 ++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 )
191 t1.tv_sec++;
192 t1.tv_usec -= 1000000;
194 return t1;
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 )
205 bool bRet = false;
206 if( m_aTimeout.tv_sec ) // timer is started
208 timeval aTimeOfDay;
209 gettimeofday( &aTimeOfDay, 0 );
210 if( aTimeOfDay >= m_aTimeout )
212 bRet = true;
213 if( bExecuteTimers )
215 // timed out, update timeout
216 m_aTimeout = aTimeOfDay;
217 m_aTimeout += m_nTimeoutMS;
218 // notify
219 ImplSVData* pSVData = ImplGetSVData();
220 if( pSVData->mpSalTimer )
221 pSVData->mpSalTimer->CallCallback();
225 return bRet;
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 )
240 delete pFrame;
243 SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, BOOL )
245 return new SvpSalObject();
248 void SvpSalInstance::DestroyObject( SalObject* pObject )
250 delete pObject;
253 SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics*,
254 long nDX, long nDY,
255 USHORT nBitCount, const SystemGraphicsData* )
257 SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
258 pNew->SetSize( nDX, nDY );
259 return pNew;
262 void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
264 delete 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();
298 ULONG n = nCount;
299 while ( n )
301 m_aYieldMutex.release();
302 n--;
305 return nCount;
307 else
308 return 0;
311 void SvpSalInstance::AcquireYieldMutex( ULONG nCount )
313 while ( nCount )
315 m_aYieldMutex.acquire();
316 nCount--;
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();
336 else
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();
348 if( bEvent )
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 )
366 int nTimeoutMS = 0;
367 if (m_aTimeout.tv_sec) // Timer is started.
369 timeval Timeout;
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;
374 if( nTimeoutMS < 0 )
375 nTimeoutMS = 0;
377 else
378 nTimeoutMS = -1; // wait until something happens
380 // release yield mutex
381 nAcquireCount = ReleaseYieldMutex();
382 // poll
383 struct pollfd aPoll;
384 aPoll.fd = m_pTimeoutFDS[0];
385 aPoll.events = POLLIN;
386 aPoll.revents = 0;
387 poll( &aPoll, 1, nTimeoutMS );
389 // acquire yield mutex again
390 AcquireYieldMutex( nAcquireCount );
392 // clean up pipe
393 if( (aPoll.revents & POLLIN) != 0 )
395 int buffer;
396 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
397 continue;
402 bool SvpSalInstance::AnyInput( USHORT nType )
404 if( (nType & INPUT_TIMER) != 0 )
405 return CheckTimeout( false );
406 return false;
409 SalMenu* SvpSalInstance::CreateMenu( BOOL )
411 return NULL;
414 void SvpSalInstance::DestroyMenu( SalMenu* )
418 SalMenuItem* SvpSalInstance::CreateMenuItem( const SalItemParams* )
420 return NULL;
423 void SvpSalInstance::DestroyMenuItem( SalMenuItem* )
427 SalSession* SvpSalInstance::CreateSalSession()
429 return NULL;
432 void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
434 rReturnedBytes = 1;
435 rReturnedType = AsciiCString;
436 return const_cast<char*>("");
439 // -------------------------------------------------------------------------
441 // SalYieldMutex
443 // -------------------------------------------------------------------------
445 SvpSalYieldMutex::SvpSalYieldMutex()
447 mnCount = 0;
448 mnThreadId = 0;
451 void SvpSalYieldMutex::acquire()
453 OMutex::acquire();
454 mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
455 mnCount++;
458 void SvpSalYieldMutex::release()
460 if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() )
462 if ( mnCount == 1 )
463 mnThreadId = 0;
464 mnCount--;
466 OMutex::release();
469 sal_Bool SvpSalYieldMutex::tryToAcquire()
471 if ( OMutex::tryToAcquire() )
473 mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier();
474 mnCount++;
475 return sal_True;
477 else
478 return sal_False;
481 // ---------------
482 // - SalTimer -
483 // ---------------
485 void SvpSalInstance::StopTimer()
487 m_aTimeout.tv_sec = 0;
488 m_aTimeout.tv_usec = 0;
489 m_nTimeoutMS = 0;
492 void SvpSalInstance::StartTimer( ULONG nMS )
494 timeval Timeout (m_aTimeout); // previous timeout.
495 gettimeofday (&m_aTimeout, 0);
497 m_nTimeoutMS = nMS;
498 m_aTimeout += m_nTimeoutMS;
500 if ((Timeout > m_aTimeout) || (Timeout.tv_sec == 0))
502 // Wakeup from previous timeout (or stopped timer).
503 Wakeup();
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 );