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 90596 : bool SvpSalInstance::isFrameAlive( const SalFrame* pFrame ) const
51 : {
52 307167 : for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
53 204778 : it != m_aFrames.end(); ++it )
54 : {
55 102387 : if( *it == pFrame )
56 : {
57 90594 : return true;
58 : }
59 : }
60 2 : return false;
61 : }
62 :
63 : SvpSalInstance* SvpSalInstance::s_pDefaultInstance = NULL;
64 :
65 375 : SvpSalInstance::SvpSalInstance( SalYieldMutex *pMutex ) :
66 375 : SalGenericInstance( pMutex )
67 : {
68 375 : m_aTimeout.tv_sec = 0;
69 375 : m_aTimeout.tv_usec = 0;
70 375 : m_nTimeoutMS = 0;
71 :
72 375 : m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
73 375 : if (pipe (m_pTimeoutFDS) != -1)
74 : {
75 : // initialize 'wakeup' pipe.
76 : int flags;
77 :
78 : // set close-on-exec descriptor flag.
79 375 : if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
80 : {
81 375 : flags |= FD_CLOEXEC;
82 375 : (void)fcntl(m_pTimeoutFDS[0], F_SETFD, flags);
83 : }
84 375 : if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
85 : {
86 375 : flags |= FD_CLOEXEC;
87 375 : (void)fcntl(m_pTimeoutFDS[1], F_SETFD, flags);
88 : }
89 :
90 : // set non-blocking I/O flag.
91 375 : if ((flags = fcntl(m_pTimeoutFDS[0], F_GETFL)) != -1)
92 : {
93 375 : flags |= O_NONBLOCK;
94 375 : (void)fcntl(m_pTimeoutFDS[0], F_SETFL, flags);
95 : }
96 375 : if ((flags = fcntl(m_pTimeoutFDS[1], F_GETFL)) != -1)
97 : {
98 375 : flags |= O_NONBLOCK;
99 375 : (void)fcntl(m_pTimeoutFDS[1], F_SETFL, flags);
100 : }
101 : }
102 375 : m_aEventGuard = osl_createMutex();
103 375 : if( s_pDefaultInstance == NULL )
104 375 : s_pDefaultInstance = this;
105 375 : }
106 :
107 1107 : SvpSalInstance::~SvpSalInstance()
108 : {
109 369 : if( s_pDefaultInstance == this )
110 369 : s_pDefaultInstance = NULL;
111 :
112 : // close 'wakeup' pipe.
113 369 : close (m_pTimeoutFDS[0]);
114 369 : close (m_pTimeoutFDS[1]);
115 369 : osl_destroyMutex( m_aEventGuard );
116 738 : }
117 :
118 105832 : void SvpSalInstance::PostEvent( const SalFrame* pFrame, void* pData, sal_uInt16 nEvent )
119 : {
120 105832 : if( osl_acquireMutex( m_aEventGuard ) )
121 : {
122 105832 : m_aUserEvents.push_back( SalUserEvent( pFrame, pData, nEvent ) );
123 105832 : osl_releaseMutex( m_aEventGuard );
124 : }
125 105832 : Wakeup();
126 105832 : }
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 12420 : void SvpSalInstance::deregisterFrame( SalFrame* pFrame )
140 : {
141 12420 : m_aFrames.remove( pFrame );
142 :
143 12420 : if( osl_acquireMutex( m_aEventGuard ) )
144 : {
145 : // cancel outstanding events for this frame
146 12420 : if( ! m_aUserEvents.empty() )
147 : {
148 12175 : std::list< SalUserEvent >::iterator it = m_aUserEvents.begin();
149 448666 : do
150 : {
151 224333 : if( it->m_pFrame == pFrame )
152 : {
153 15162 : it = m_aUserEvents.erase( it );
154 : }
155 : else
156 209171 : ++it;
157 448666 : } while( it != m_aUserEvents.end() );
158 : }
159 12420 : osl_releaseMutex( m_aEventGuard );
160 : }
161 12420 : }
162 :
163 130099 : void SvpSalInstance::Wakeup()
164 : {
165 130099 : OSL_VERIFY(write (m_pTimeoutFDS[1], "", 1) == 1);
166 130099 : }
167 :
168 1302588 : bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
169 : {
170 1302588 : bool bRet = false;
171 1302588 : if( m_aTimeout.tv_sec ) // timer is started
172 : {
173 : timeval aTimeOfDay;
174 1302385 : gettimeofday( &aTimeOfDay, 0 );
175 1302385 : if( aTimeOfDay >= m_aTimeout )
176 : {
177 38834 : bRet = true;
178 38834 : if( bExecuteTimers )
179 : {
180 : // timed out, update timeout
181 38805 : m_aTimeout = aTimeOfDay;
182 38805 : m_aTimeout += m_nTimeoutMS;
183 :
184 38805 : osl::Guard< comphelper::SolarMutex > aGuard( mpSalYieldMutex );
185 :
186 : // notify
187 38805 : ImplSVData* pSVData = ImplGetSVData();
188 38805 : if( pSVData->mpSalTimer )
189 38805 : pSVData->mpSalTimer->CallCallback();
190 : }
191 : }
192 : }
193 1302588 : return bRet;
194 : }
195 :
196 0 : SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle )
197 : {
198 0 : return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent );
199 : }
200 :
201 12438 : SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle )
202 : {
203 12438 : return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT );
204 : }
205 :
206 12420 : void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
207 : {
208 12420 : delete pFrame;
209 12420 : }
210 :
211 34 : SalObject* SvpSalInstance::CreateObject( SalFrame*, SystemWindowData*, bool )
212 : {
213 34 : return new SvpSalObject();
214 : }
215 :
216 34 : void SvpSalInstance::DestroyObject( SalObject* pObject )
217 : {
218 34 : delete pObject;
219 34 : }
220 :
221 : #ifndef IOS
222 :
223 202815 : SalVirtualDevice* SvpSalInstance::CreateVirtualDevice( SalGraphics* /* pGraphics */,
224 : long nDX, long nDY,
225 : sal_uInt16 nBitCount,
226 : const SystemGraphicsData* /* pData */ )
227 : {
228 202815 : SvpSalVirtualDevice* pNew = new SvpSalVirtualDevice( nBitCount );
229 202815 : pNew->SetSize( nDX, nDY );
230 202815 : return pNew;
231 : }
232 :
233 : #endif
234 :
235 477 : SalTimer* SvpSalInstance::CreateSalTimer()
236 : {
237 477 : return new SvpSalTimer( this );
238 : }
239 :
240 305 : SalI18NImeStatus* SvpSalInstance::CreateI18NImeStatus()
241 : {
242 305 : return new SvpImeStatus();
243 : }
244 :
245 142 : SalSystem* SvpSalInstance::CreateSalSystem()
246 : {
247 142 : return new SvpSalSystem();
248 : }
249 :
250 404190 : SalBitmap* SvpSalInstance::CreateSalBitmap()
251 : {
252 : #ifdef IOS
253 : return new QuartzSalBitmap();
254 : #else
255 404190 : return new SvpSalBitmap();
256 : #endif
257 : }
258 :
259 1302043 : void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents )
260 : {
261 : // first, check for already queued events.
262 :
263 : // release yield mutex
264 1302043 : std::list< SalUserEvent > aEvents;
265 1302043 : sal_uLong nAcquireCount = ReleaseYieldMutex();
266 1302043 : if( osl_acquireMutex( m_aEventGuard ) )
267 : {
268 1302043 : if( ! m_aUserEvents.empty() )
269 : {
270 35399 : if( bHandleAllCurrentEvents )
271 : {
272 10640 : aEvents = m_aUserEvents;
273 10640 : m_aUserEvents.clear();
274 : }
275 : else
276 : {
277 24759 : aEvents.push_back( m_aUserEvents.front() );
278 24759 : m_aUserEvents.pop_front();
279 : }
280 : }
281 1302043 : osl_releaseMutex( m_aEventGuard );
282 : }
283 : // acquire yield mutex again
284 1302043 : AcquireYieldMutex( nAcquireCount );
285 :
286 1302043 : bool bEvent = !aEvents.empty();
287 1302043 : if( bEvent )
288 : {
289 125995 : for( std::list<SalUserEvent>::const_iterator it = aEvents.begin(); it != aEvents.end(); ++it )
290 : {
291 90596 : if ( isFrameAlive( it->m_pFrame ) )
292 : {
293 90594 : it->m_pFrame->CallCallback( it->m_nEvent, it->m_pData );
294 90594 : if( it->m_nEvent == SALEVENT_RESIZE )
295 : {
296 : // this would be a good time to post a paint
297 5207 : const SvpSalFrame* pSvpFrame = static_cast<const SvpSalFrame*>(it->m_pFrame);
298 5207 : pSvpFrame->PostPaint(false);
299 : }
300 : }
301 : }
302 : }
303 :
304 1302043 : bEvent = CheckTimeout() || bEvent;
305 :
306 1302043 : if (bWait && ! bEvent )
307 : {
308 1239783 : int nTimeoutMS = 0;
309 1239783 : if (m_aTimeout.tv_sec) // Timer is started.
310 : {
311 : timeval Timeout;
312 : // determine remaining timeout.
313 1239711 : gettimeofday (&Timeout, 0);
314 1239711 : nTimeoutMS = (m_aTimeout.tv_sec - Timeout.tv_sec) * 1000
315 1239711 : + m_aTimeout.tv_usec/1000 - Timeout.tv_usec/1000;
316 1239711 : if( nTimeoutMS < 0 )
317 4 : nTimeoutMS = 0;
318 : }
319 : else
320 72 : nTimeoutMS = -1; // wait until something happens
321 :
322 1239783 : DoReleaseYield(nTimeoutMS);
323 1302043 : }
324 1302043 : }
325 :
326 1239783 : void SvpSalInstance::DoReleaseYield( int nTimeoutMS )
327 : {
328 : // poll
329 : struct pollfd aPoll;
330 1239783 : aPoll.fd = m_pTimeoutFDS[0];
331 1239783 : aPoll.events = POLLIN;
332 1239783 : aPoll.revents = 0;
333 :
334 : // release yield mutex
335 1239783 : sal_uLong nAcquireCount = ReleaseYieldMutex();
336 :
337 1239783 : (void)poll( &aPoll, 1, nTimeoutMS );
338 :
339 : // acquire yield mutex again
340 1239783 : AcquireYieldMutex( nAcquireCount );
341 :
342 : // clean up pipe
343 1239783 : if( (aPoll.revents & POLLIN) != 0 )
344 : {
345 : int buffer;
346 71020 : while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
347 26330 : continue;
348 : }
349 1239783 : }
350 :
351 88532 : bool SvpSalInstance::AnyInput( sal_uInt16 nType )
352 : {
353 88532 : if( (nType & VCL_INPUT_TIMER) != 0 )
354 545 : return CheckTimeout( false );
355 87987 : return false;
356 : }
357 :
358 0 : SalSession* SvpSalInstance::CreateSalSession()
359 : {
360 0 : return NULL;
361 : }
362 :
363 164 : void* SvpSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes )
364 : {
365 164 : rReturnedBytes = 1;
366 164 : rReturnedType = AsciiCString;
367 164 : return const_cast<char*>("");
368 : }
369 :
370 556 : void SvpSalInstance::StopTimer()
371 : {
372 556 : m_aTimeout.tv_sec = 0;
373 556 : m_aTimeout.tv_usec = 0;
374 556 : m_nTimeoutMS = 0;
375 556 : }
376 :
377 56786 : void SvpSalInstance::StartTimer( sal_uLong nMS )
378 : {
379 56786 : timeval aPrevTimeout (m_aTimeout);
380 56786 : gettimeofday (&m_aTimeout, 0);
381 :
382 56786 : m_nTimeoutMS = nMS;
383 56786 : m_aTimeout += m_nTimeoutMS;
384 :
385 56786 : if ((aPrevTimeout > m_aTimeout) || (aPrevTimeout.tv_sec == 0))
386 : {
387 : // Wakeup from previous timeout (or stopped timer).
388 24267 : Wakeup();
389 : }
390 56786 : }
391 :
392 10246 : void SvpSalInstance::AddToRecentDocumentList(const OUString&, const OUString&, const OUString&)
393 : {
394 10246 : }
395 :
396 942 : SvpSalTimer::~SvpSalTimer()
397 : {
398 942 : }
399 :
400 556 : void SvpSalTimer::Stop()
401 : {
402 556 : m_pInstance->StopTimer();
403 556 : }
404 :
405 56786 : void SvpSalTimer::Start( sal_uLong nMS )
406 : {
407 56786 : m_pInstance->StartTimer( nMS );
408 56786 : }
409 :
410 0 : void SvpSalInstance::setBitCountFormatMapping( sal_uInt16 nBitCount,
411 : Format aFormat )
412 : {
413 0 : m_aBitCountFormatMap[nBitCount] = aFormat;
414 0 : }
415 :
416 360850 : Format SvpSalInstance::getFormatForBitCount( sal_uInt16 nBitCount )
417 : {
418 360850 : BitCountFormatMap::iterator aIt;
419 360850 : if ( (aIt = m_aBitCountFormatMap.find( nBitCount )) != m_aBitCountFormatMap.end() )
420 : {
421 0 : return aIt->second;
422 : }
423 :
424 360850 : switch( nBitCount )
425 : {
426 : case 1:
427 22589 : return FORMAT_ONE_BIT_MSB_PAL;
428 : case 4:
429 252 : return FORMAT_FOUR_BIT_MSB_PAL;
430 : case 8:
431 82724 : return FORMAT_EIGHT_BIT_PAL;
432 : case 16:
433 : #ifdef OSL_BIGENDIAN
434 : return FORMAT_SIXTEEN_BIT_MSB_TC_MASK;
435 : #else
436 2 : return FORMAT_SIXTEEN_BIT_LSB_TC_MASK;
437 : #endif
438 : case 24:
439 29604 : return FORMAT_TWENTYFOUR_BIT_TC_MASK;
440 : case 32:
441 0 : return FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA;
442 : case 0:
443 : #ifdef ANDROID
444 : return FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA;
445 : #else
446 225679 : return FORMAT_TWENTYFOUR_BIT_TC_MASK;
447 : #endif
448 : default:
449 0 : return SVP_DEFAULT_BITMAP_FORMAT;
450 : }
451 :
452 1125 : }
453 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|