Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <unistd.h>
21 : #include <fcntl.h>
22 : #include <sys/time.h>
23 : #include <sys/poll.h>
24 :
25 : #include <sal/types.h>
26 :
27 : #include <vcl/apptypes.hxx>
28 :
29 : #include "headless/svpinst.hxx"
30 : #include "headless/svpframe.hxx"
31 : #include "headless/svpdummies.hxx"
32 : #include "headless/svpvd.hxx"
33 : #ifdef IOS
34 : #include "headless/svpgdi.hxx"
35 : #include "quartz/salbmp.h"
36 : #include "quartz/salgdi.h"
37 : #include "quartz/salvd.h"
38 : #endif
39 : #include "headless/svpbmp.hxx"
40 :
41 : #include <salframe.hxx>
42 : #include <svdata.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>
47 :
48 : using namespace basebmp;
49 :
50 100009 : bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
51 : {
52 320361 : for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
53 213574 : it != m_aFrames.end(); ++it )
54 : {
55 106786 : if( *it == pFrame )
56 : {
57 100008 : return true;
58 : }
59 : }
60 1 : return false;
61 : }
62 :
63 : SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
64 :
65 242 : SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
66 242 : SalGenericInstance( pMutex )
67 : {
68 242 : m_aTimeout.tv_sec = 0;
69 242 : m_aTimeout.tv_usec = 0;
70 242 : m_nTimeoutMS = 0;
71 :
72 242 : m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
73 242 : if (pipe (m_pTimeoutFDS) != -1)
74 : {
75 : // initialize 'wakeup' pipe.
76 : int flags;
77 :
78 : // set close-on-exec descriptor flag.
79 242 : if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
80 : {
81 242 : flags |= FD_CLOEXEC;
82 242 : (void)fcntl(m_pTimeoutFDS[0], F_SETFD, flags);
83 : }
84 242 : if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
85 : {
86 242 : flags |= FD_CLOEXEC;
87 242 : (void)fcntl(m_pTimeoutFDS[1], F_SETFD, flags);
88 : }
89 :
90 : // set non-blocking I/O flag.
91 242 : if ((flags = fcntl(m_pTimeoutFDS[0], F_GETFL)) != -1)
92 : {
93 242 : flags |= O_NONBLOCK;
94 242 : (void)fcntl(m_pTimeoutFDS[0], F_SETFL, flags);
95 : }
96 242 : if ((flags = fcntl(m_pTimeoutFDS[1], F_GETFL)) != -1)
97 : {
98 242 : flags |= O_NONBLOCK;
99 242 : (void)fcntl(m_pTimeoutFDS[1], F_SETFL, flags);
100 : }
101 : }
102 242 : m_aEventGuard = osl_createMutex();
103 242 : if( s_pDefaultInstance == NULL )
104 242 : s_pDefaultInstance = this;
105 242 : }
106 :
107 723 : SvpSalInstance::~SvpSalInstance()
108 : {
109 241 : if( s_pDefaultInstance == this )
110 241 : s_pDefaultInstance = NULL;
111 :
112 : // close 'wakeup' pipe.
113 241 : close (m_pTimeoutFDS[0]);
114 241 : close (m_pTimeoutFDS[1]);
115 241 : osl_destroyMutex( m_aEventGuard );
116 482 : }
117 :
118 111843 : void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
119 : {
120 111843 : if( osl_acquireMutex( m_aEventGuard ) )
121 : {
122 111843 : m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
123 111843 : osl_releaseMutex( m_aEventGuard );
124 : }
125 111843 : Wakeup();
126 111843 : }
127 :
128 0 : bool SvpSalInstance::PostedEventsInQueue()
129 : {
130 0 : bool result = false;
131 0 : if( osl_acquireMutex( m_aEventGuard ) )
132 : {
133 0 : result = m_aUserEvents.size() > 0;
134 0 : osl_releaseMutex( m_aEventGuard );
135 : }
136 0 : return result;
137 : }
138 :
139 6909 : void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
140 : {
141 6909 : m_aFrames.remove( pFrame );
142 :
143 6909 : if( osl_acquireMutex( m_aEventGuard ) )
144 : {
145 : // cancel outstanding events for this frame
146 6909 : if( ! m_aUserEvents.empty() )
147 : {
148 6785 : std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
149 438934 : do
150 : {
151 219467 : if( it->m_pFrame == pFrame )
152 : {
153 11832 : it = m_aUserEvents.erase( it );
154 : }
155 : else
156 207635 : ++it;
157 438934 : } while( it != m_aUserEvents.end() );
158 : }
159 6909 : osl_releaseMutex( m_aEventGuard );
160 : }
161 6909 : }
162 :
163 132903 : void SvpSalInstance::Wakeup()
164 : {
165 132903 : OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
166 132903 : }
167 :
168 24941357 : bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
169 : {
170 24941357 : bool bRet = false;
171 24941357 : if( m_aTimeout.tv_sec ) // timer is started
172 : {
173 : timeval aTimeOfDay;
174 24941055 : gettimeofday( &aTimeOfDay, 0 );
175 24941055 : if( aTimeOfDay >= m_aTimeout )
176 : {
177 18403924 : bRet = true;
178 18403924 : if( bExecuteTimers )
179 : {
180 : // timed out, update timeout
181 13383082 : m_aTimeout = aTimeOfDay;
182 13383082 : m_aTimeout += m_nTimeoutMS;
183 :
184 13383082 : osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );
185 :
186 : // notify
187 13383082 : ImplSVData* pSVData = ImplGetSVData();
188 13383082 : if( pSVData->mpSalTimer )
189 : {
190 13383082 : bool idle = true; // TODO
191 13383082 : pSVData->mpSalTimer->CallCallback( idle );
192 13383082 : }
193 : }
194 : }
195 : }
196 24941357 : return bRet;
197 : }
198 :
199 0 : SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
200 : {
201 0 : return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
202 : }
203 :
204 6925 : SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
205 : {
206 6925 : return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
207 : }
208 :
209 6909 : void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
210 : {
211 6909 : delete pFrame;
212 6909 : }
213 :
214 17 : SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
215 : {
216 17 : return new SvpSalObject();
217 : }
218 :
219 17 : void SvpSalInstance::DestroyObject( SalObject* pObject )
220 : {
221 17 : delete pObject;
222 17 : }
223 :
224 : #ifndef IOS
225 :
226 156652 : SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
227 : long &nDX, long &nDY,
228 : sal_uInt16 nBitCount,
229 : const SystemGraphicsData* /* pData */ )
230 : {
231 156652 : SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
232 156652 : pNew->SetSize( nDX, nDY );
233 156652 : return pNew;
234 : }
235 :
236 : #endif
237 :
238 330 : SalTimer* SvpSalInstance::CreateSalTimer()
239 : {
240 330 : return new SvpSalTimer( this );
241 : }
242 :
243 205 : SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
244 : {
245 205 : return new SvpImeStatus();
246 : }
247 :
248 96 : SalSystem* SvpSalInstance::CreateSalSystem()
249 : {
250 96 : return new SvpSalSystem();
251 : }
252 :
253 108398 : SalBitmap* SvpSalInstance::CreateSalBitmap()
254 : {
255 : #ifdef IOS
256 : return new QuartzSalBitmap();
257 : #else
258 108398 : return new SvpSalBitmap();
259 : #endif
260 : }
261 :
262 13482011 : void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
263 : {
264 : // first, check for already queued events.
265 :
266 : // release yield mutex
267 13482011 : std::list< SalUserEvent > aEvents;
268 13482011 : sal_uLong nAcquireCount = ReleaseYieldMutex();
269 13482011 : if( osl_acquireMutex( m_aEventGuard ) )
270 : {
271 13482011 : if( ! m_aUserEvents.empty() )
272 : {
273 32033 : if( bHandleAllCurrentEvents )
274 : {
275 5190 : aEvents = m_aUserEvents;
276 5190 : m_aUserEvents.clear();
277 : }
278 : else
279 : {
280 26843 : aEvents.push_back( m_aUserEvents.front() );
281 26843 : m_aUserEvents.pop_front();
282 : }
283 : }
284 13482011 : osl_releaseMutex( m_aEventGuard );
285 : }
286 : // acquire yield mutex again
287 13482011 : AcquireYieldMutex( nAcquireCount );
288 :
289 13482011 : bool bEvent = !aEvents.empty();
290 13482011 : if( bEvent )
291 : {
292 132042 : for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
293 : {
294 100009 : if ( isFrameAlive( it->m_pFrame ) )
295 : {
296 100008 : it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
297 100008 : if( it->m_nEvent == SALEVENT_RESIZE )
298 : {
299 : // this would be a good time to post a paint
300 2949 : const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
301 2949 : pSvpFrame->PostPaint(false);
302 : }
303 : }
304 : }
305 : }
306 :
307 13482011 : bEvent = CheckTimeout() || bEvent;
308 :
309 13482011 : if (bWait && ! bEvent )
310 : {
311 75134 : int nTimeoutMS = 0;
312 75134 : if (m_aTimeout.tv_sec) // Timer is started.
313 : {
314 : timeval Timeout;
315 : // determine remaining timeout.
316 75029 : gettimeofday (&Timeout, 0);
317 75029 : nTimeoutMS = (m_aTimeout.tv_sec - Timeout.tv_sec) * 1000
318 75029 : + m_aTimeout.tv_usec/1000 - Timeout.tv_usec/1000;
319 75029 : if( nTimeoutMS < 0 )
320 0 : nTimeoutMS = 0;
321 : }
322 : else
323 105 : nTimeoutMS = -1; // wait until something happens
324 :
325 75134 : DoReleaseYield(nTimeoutMS);
326 13482011 : }
327 13482011 : }
328 :
329 75134 : void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
330 : {
331 : // poll
332 : struct pollfd aPoll;
333 75134 : aPoll.fd = m_pTimeoutFDS[0];
334 75134 : aPoll.events = POLLIN;
335 75134 : aPoll.revents = 0;
336 :
337 : // release yield mutex
338 75134 : sal_uLong nAcquireCount = ReleaseYieldMutex();
339 :
340 75134 : (void)poll( &aPoll, 1, nTimeoutMS );
341 :
342 : // acquire yield mutex again
343 75134 : AcquireYieldMutex( nAcquireCount );
344 :
345 : // clean up pipe
346 75134 : if( (aPoll.revents & POLLIN) != 0 )
347 : {
348 : int buffer;
349 61358 : while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
350 25108 : continue;
351 : }
352 75134 : }
353 :
354 60027144 : bool SvpSalInstance::AnyInput( VclInputFlags nType )
355 : {
356 60027144 : if( nType & VclInputFlags::TIMER )
357 11459346 : return CheckTimeout( false );
358 48567798 : return false;
359 : }
360 :
361 0 : SalSession* SvpSalInstance::CreateSalSession()
362 : {
363 0 : return NULL;
364 : }
365 :
366 108 : void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
367 : {
368 108 : rReturnedBytes = 1;
369 108 : rReturnedType = AsciiCString;
370 108 : return const_cast<char*>("");
371 : }
372 :
373 613 : void SvpSalInstance::StopTimer()
374 : {
375 613 : m_aTimeout.tv_sec = 0;
376 613 : m_aTimeout.tv_usec = 0;
377 613 : m_nTimeoutMS = 0;
378 613 : }
379 :
380 44625 : void SvpSalInstance::StartTimer( sal_uLong nMS )
381 : {
382 44625 : timeval aPrevTimeout (m_aTimeout);
383 44625 : gettimeofday (&m_aTimeout, 0);
384 :
385 44625 : m_nTimeoutMS = nMS;
386 44625 : m_aTimeout += m_nTimeoutMS;
387 :
388 44625 : if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
389 : {
390 : // Wakeup from previous timeout (or stopped timer).
391 21060 : Wakeup();
392 : }
393 44625 : }
394 :
395 6288 : void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
396 : {
397 6288 : }
398 :
399 658 : SvpSalTimer::~SvpSalTimer()
400 : {
401 658 : }
402 :
403 613 : void SvpSalTimer::Stop()
404 : {
405 613 : m_pInstance->StopTimer();
406 613 : }
407 :
408 44625 : void SvpSalTimer::Start( sal_uLong nMS )
409 : {
410 44625 : m_pInstance->StartTimer( nMS );
411 44625 : }
412 :
413 0 : void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount,
414 : Format aFormat )
415 : {
416 0 : m_aBitCountFormatMap[nBitCount] = aFormat;
417 0 : }
418 :
419 302628 : Format SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount )
420 : {
421 302628 : BitCountFormatMap::iterator aIt;
422 302628 : if ( (aIt = m_aBitCountFormatMap.find( nBitCount )) != m_aBitCountFormatMap.end() )
423 : {
424 0 : return aIt->second;
425 : }
426 :
427 302628 : switch( nBitCount )
428 : {
429 : case 1:
430 9506 : return Format::OneBitMsbPal;
431 : case 4:
432 137 : return Format::FourBitMsbPal;
433 : case 8:
434 49339 : return Format::EightBitPal;
435 : case 16:
436 : #ifdef OSL_BIGENDIAN
437 : return Format::SixteenBitMsbTcMask;
438 : #else
439 1 : return Format::SixteenBitLsbTcMask;
440 : #endif
441 : case 24:
442 21551 : return Format::ThirtyTwoBitTcMaskBGRX;
443 : case 32:
444 3409 : return Format::ThirtyTwoBitTcMaskBGRA;
445 : case 0:
446 : #ifdef ANDROID
447 : return Format::ThirtyTwoBitTcMaskRGBA;
448 : #else
449 218685 : return Format::ThirtyTwoBitTcMaskBGRX;
450 : #endif
451 : default:
452 0 : return SVP_DEFAULT_BITMAP_FORMAT;
453 : }
454 :
455 801 : }
456 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|