Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <unistd.h>
30 : : #include <fcntl.h>
31 : : #include <sys/time.h>
32 : : #include <sys/poll.h>
33 : :
34 : : #include <sal/types.h>
35 : :
36 : : #include <vcl/apptypes.hxx>
37 : :
38 : : #include "headless/svpinst.hxx"
39 : : #include "headless/svpframe.hxx"
40 : : #include "headless/svpdummies.hxx"
41 : : #include "headless/svpvd.hxx"
42 : : #include "headless/svpbmp.hxx"
43 : :
44 : : #include <salframe.hxx>
45 : : #include <svdata.hxx>
46 : : #include <generic/gendata.hxx>
47 : : #include <basebmp/scanlineformats.hxx>
48 : : #include <vcl/solarmutex.hxx>
49 : : // FIXME: remove when we re-work the svp mainloop
50 : : #include <unx/salunxtime.h>
51 : :
52 : 34851 : bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
53 : : {
54 [ + - + - ]: 127876 : for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
[ + + ]
55 : 63938 : it != m_aFrames.end(); ++it )
56 : : {
57 [ + - ][ + + ]: 63934 : if( *it == pFrame )
58 : : {
59 : 34847 : return true;
60 : : }
61 : : }
62 : 34851 : return false;
63 : : }
64 : :
65 : : SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
66 : :
67 : 266 : SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
68 [ + - ][ + - ]: 266 : SalGenericInstance( pMutex )
69 : : {
70 : 266 : m_aTimeout.tv_sec = 0;
71 : 266 : m_aTimeout.tv_usec = 0;
72 : 266 : m_nTimeoutMS = 0;
73 : :
74 : 266 : m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
75 [ + - ]: 266 : if (pipe (m_pTimeoutFDS) != -1)
76 : : {
77 : : // initialize 'wakeup' pipe.
78 : : int flags;
79 : :
80 : : // set close-on-exec descriptor flag.
81 [ + - ][ + - ]: 266 : if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
82 : : {
83 : 266 : flags |= FD_CLOEXEC;
84 [ + - ]: 266 : fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
85 : : }
86 [ + - ][ + - ]: 266 : if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
87 : : {
88 : 266 : flags |= FD_CLOEXEC;
89 [ + - ]: 266 : fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
90 : : }
91 : :
92 : : // set non-blocking I/O flag.
93 [ + - ][ + - ]: 266 : if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
94 : : {
95 : 266 : flags |= O_NONBLOCK;
96 [ + - ]: 266 : fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
97 : : }
98 [ + - ][ + - ]: 266 : if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
99 : : {
100 : 266 : flags |= O_NONBLOCK;
101 [ + - ]: 266 : fcntl (m_pTimeoutFDS[1], F_SETFL, flags);
102 : : }
103 : : }
104 [ + - ]: 266 : m_aEventGuard = osl_createMutex();
105 [ + - ]: 266 : if( s_pDefaultInstance == NULL )
106 : 266 : s_pDefaultInstance = this;
107 : 266 : }
108 : :
109 : 158 : SvpSalInstance::~SvpSalInstance()
110 : : {
111 [ + - ]: 158 : if( s_pDefaultInstance == this )
112 : 158 : s_pDefaultInstance = NULL;
113 : :
114 : : // close 'wakeup' pipe.
115 [ + - ]: 158 : close (m_pTimeoutFDS[0]);
116 [ + - ]: 158 : close (m_pTimeoutFDS[1]);
117 [ + - ]: 158 : osl_destroyMutex( m_aEventGuard );
118 [ - + ]: 316 : }
119 : :
120 : 41676 : void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
121 : : {
122 [ + - ]: 41676 : if( osl_acquireMutex( m_aEventGuard ) )
123 : : {
124 [ + - ]: 41676 : m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
125 : 41676 : osl_releaseMutex( m_aEventGuard );
126 : : }
127 : 41676 : Wakeup();
128 : 41676 : }
129 : :
130 : 5802 : void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
131 : : {
132 : 5802 : m_aFrames.remove( pFrame );
133 : :
134 [ + - ]: 5802 : if( osl_acquireMutex( m_aEventGuard ) )
135 : : {
136 : : // cancel outstanding events for this frame
137 [ + + ]: 5802 : if( ! m_aUserEvents.empty() )
138 : : {
139 : 5515 : std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
140 [ + + ]: 43770 : do
141 : : {
142 [ + + ]: 43770 : if( it->m_pFrame == pFrame )
143 : : {
144 [ + - ]: 4746 : it = m_aUserEvents.erase( it );
145 : : }
146 : : else
147 : 39024 : ++it;
148 : 43770 : } while( it != m_aUserEvents.end() );
149 : : }
150 : 5802 : osl_releaseMutex( m_aEventGuard );
151 : : }
152 : 5802 : }
153 : :
154 : 60999 : void SvpSalInstance::Wakeup()
155 : : {
156 : 60999 : OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
157 : 60999 : }
158 : :
159 : 227598 : bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
160 : : {
161 : 227598 : bool bRet = false;
162 [ + + ]: 227598 : if( m_aTimeout.tv_sec ) // timer is started
163 : : {
164 : : timeval aTimeOfDay;
165 : 227414 : gettimeofday( &aTimeOfDay, 0 );
166 [ + + ]: 227414 : if( aTimeOfDay >= m_aTimeout )
167 : : {
168 : 34583 : bRet = true;
169 [ + + ]: 34583 : if( bExecuteTimers )
170 : : {
171 : : // timed out, update timeout
172 : 33012 : m_aTimeout = aTimeOfDay;
173 : 33012 : m_aTimeout += m_nTimeoutMS;
174 : : // notify
175 [ + - ]: 33012 : ImplSVData* pSVData = ImplGetSVData();
176 [ + - ]: 33012 : if( pSVData->mpSalTimer )
177 [ + - ]: 227414 : pSVData->mpSalTimer->CallCallback();
178 : : }
179 : : }
180 : : }
181 : 227598 : return bRet;
182 : : }
183 : :
184 : 0 : SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
185 : : {
186 [ # # ]: 0 : return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
187 : : }
188 : :
189 : 5988 : SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
190 : : {
191 [ + - ]: 5988 : return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
192 : : }
193 : :
194 : 5802 : void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
195 : : {
196 [ + - ]: 5802 : delete pFrame;
197 : 5802 : }
198 : :
199 : 0 : SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, sal_Bool )
200 : : {
201 [ # # ]: 0 : return new SvpSalObject();
202 : : }
203 : :
204 : 0 : void SvpSalInstance::DestroyObject( SalObject* pObject )
205 : : {
206 [ # # ]: 0 : delete pObject;
207 : 0 : }
208 : :
209 : 94869 : SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics*,
210 : : long nDX, long nDY,
211 : : sal_uInt16 nBitCount, const SystemGraphicsData* )
212 : : {
213 [ + - ]: 94869 : SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
214 : 94869 : pNew->SetSize( nDX, nDY );
215 : 94869 : return pNew;
216 : : }
217 : :
218 : 94195 : void SvpSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
219 : : {
220 [ + - ]: 94195 : delete pDevice;
221 : 94195 : }
222 : :
223 : 233 : SalTimer* SvpSalInstance::CreateSalTimer()
224 : : {
225 [ + - ]: 233 : return new SvpSalTimer( this );
226 : : }
227 : :
228 : 233 : SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
229 : : {
230 [ + - ]: 233 : return new SvpImeStatus();
231 : : }
232 : :
233 : 106 : SalSystem* SvpSalInstance::CreateSalSystem()
234 : : {
235 [ + - ]: 106 : return new SvpSalSystem();
236 : : }
237 : :
238 : 671556 : SalBitmap* SvpSalInstance::CreateSalBitmap()
239 : : {
240 [ + - ]: 671556 : return new SvpSalBitmap();
241 : : }
242 : :
243 : 222321 : void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
244 : : {
245 : : // first, check for already queued events.
246 : :
247 : : // release yield mutex
248 [ + - ]: 222321 : std::list< SalUserEvent > aEvents;
249 [ + - ]: 222321 : sal_uLong nAcquireCount = ReleaseYieldMutex();
250 [ + - ][ + - ]: 222321 : if( osl_acquireMutex( m_aEventGuard ) )
251 : : {
252 [ + + ]: 222321 : if( ! m_aUserEvents.empty() )
253 : : {
254 [ + + ]: 28422 : if( bHandleAllCurrentEvents )
255 : : {
256 [ + - ]: 1483 : aEvents = m_aUserEvents;
257 : 1483 : m_aUserEvents.clear();
258 : : }
259 : : else
260 : : {
261 [ + - ][ + - ]: 26939 : aEvents.push_back( m_aUserEvents.front() );
262 [ + - ]: 26939 : m_aUserEvents.pop_front();
263 : : }
264 : : }
265 [ + - ]: 222321 : osl_releaseMutex( m_aEventGuard );
266 : : }
267 : : // acquire yield mutex again
268 [ + - ]: 222321 : AcquireYieldMutex( nAcquireCount );
269 : :
270 : 222321 : bool bEvent = !aEvents.empty();
271 [ + + ]: 222321 : if( bEvent )
272 : : {
273 [ + + ]: 63273 : for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
274 : : {
275 [ + - ][ + + ]: 34851 : if ( isFrameAlive( it->m_pFrame ) )
276 : : {
277 [ + - ]: 34847 : it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
278 [ + + ]: 34847 : if( it->m_nEvent == SALEVENT_RESIZE )
279 : : {
280 : : // this would be a good time to post a paint
281 : 1695 : const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
282 [ + - ]: 1695 : pSvpFrame->PostPaint(false);
283 : : }
284 : : }
285 : : }
286 : : }
287 : :
288 [ + - ][ + + ]: 222321 : bEvent = CheckTimeout() || bEvent;
[ + + ]
289 : :
290 [ + + ][ + + ]: 222321 : if (bWait && ! bEvent )
291 : : {
292 : 167745 : int nTimeoutMS = 0;
293 [ + + ]: 167745 : if (m_aTimeout.tv_sec) // Timer is started.
294 : : {
295 : : timeval Timeout;
296 : : // determine remaining timeout.
297 : 167618 : gettimeofday (&Timeout, 0);
298 : : nTimeoutMS = m_aTimeout.tv_sec*1000 + m_aTimeout.tv_usec/1000
299 : 167618 : - Timeout.tv_sec*1000 - Timeout.tv_usec/1000;
300 [ + + ]: 167618 : if( nTimeoutMS < 0 )
301 : 167618 : nTimeoutMS = 0;
302 : : }
303 : : else
304 : 127 : nTimeoutMS = -1; // wait until something happens
305 : :
306 [ + - ]: 167745 : DoReleaseYield(nTimeoutMS);
307 : 222321 : }
308 : 222321 : }
309 : :
310 : 167745 : void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
311 : : {
312 : : // poll
313 : : struct pollfd aPoll;
314 : 167745 : aPoll.fd = m_pTimeoutFDS[0];
315 : 167745 : aPoll.events = POLLIN;
316 : 167745 : aPoll.revents = 0;
317 : :
318 : : // release yield mutex
319 [ + - ]: 167745 : sal_uLong nAcquireCount = ReleaseYieldMutex();
320 : :
321 [ + - ]: 167745 : poll( &aPoll, 1, nTimeoutMS );
322 : :
323 : : // acquire yield mutex again
324 [ + - ]: 167745 : AcquireYieldMutex( nAcquireCount );
325 : :
326 : : // clean up pipe
327 [ + + ]: 167745 : if( (aPoll.revents & POLLIN) != 0 )
328 : : {
329 : : int buffer;
330 [ + - ][ + + ]: 43312 : while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
331 : 24185 : continue;
332 : : }
333 : 167745 : }
334 : :
335 : 49360 : bool SvpSalInstance::AnyInput( sal_uInt16 nType )
336 : : {
337 [ + + ]: 49360 : if( (nType & VCL_INPUT_TIMER) != 0 )
338 : 5277 : return CheckTimeout( false );
339 : 49360 : return false;
340 : : }
341 : :
342 : 0 : SalSession* SvpSalInstance::CreateSalSession()
343 : : {
344 : 0 : return NULL;
345 : : }
346 : :
347 : 113 : void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
348 : : {
349 : 113 : rReturnedBytes = 1;
350 : 113 : rReturnedType = AsciiCString;
351 : 113 : return const_cast<char*>("");
352 : : }
353 : :
354 : : // ---------------
355 : : // - SalTimer -
356 : : // ---------------
357 : :
358 : 93 : void SvpSalInstance::StopTimer()
359 : : {
360 : 93 : m_aTimeout.tv_sec = 0;
361 : 93 : m_aTimeout.tv_usec = 0;
362 : 93 : m_nTimeoutMS = 0;
363 : 93 : }
364 : :
365 : 43475 : void SvpSalInstance::StartTimer( sal_uLong nMS )
366 : : {
367 : 43475 : timeval Timeout (m_aTimeout); // previous timeout.
368 : 43475 : gettimeofday (&m_aTimeout, 0);
369 : :
370 : 43475 : m_nTimeoutMS = nMS;
371 : 43475 : m_aTimeout += m_nTimeoutMS;
372 : :
373 [ + + ][ + + ]: 43475 : if ((Timeout > m_aTimeout) || (Timeout.tv_sec == 0))
[ + + ]
374 : : {
375 : : // Wakeup from previous timeout (or stopped timer).
376 [ + - ]: 19323 : Wakeup();
377 : : }
378 : 43475 : }
379 : :
380 : 1456 : void SvpSalInstance::AddToRecentDocumentList(const rtl::OUString&, const rtl::OUString&)
381 : : {
382 : 1456 : }
383 : :
384 : 158 : SvpSalTimer::~SvpSalTimer()
385 : : {
386 [ - + ]: 316 : }
387 : :
388 : 93 : void SvpSalTimer::Stop()
389 : : {
390 : 93 : m_pInstance->StopTimer();
391 : 93 : }
392 : :
393 : 43475 : void SvpSalTimer::Start( sal_uLong nMS )
394 : : {
395 : 43475 : m_pInstance->StartTimer( nMS );
396 : 43475 : }
397 : :
398 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|