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 <string.h>
21 : #include "headless/svpframe.hxx"
22 : #include "headless/svpinst.hxx"
23 : #include "headless/svpgdi.hxx"
24 :
25 : #include <basebmp/bitmapdevice.hxx>
26 : #include <basebmp/scanlineformats.hxx>
27 : #include <basegfx/vector/b2ivector.hxx>
28 :
29 : using namespace basebmp;
30 : using namespace basegfx;
31 :
32 : SvpSalFrame* SvpSalFrame::s_pFocusFrame = NULL;
33 :
34 : namespace {
35 : /// Decouple SalFrame lifetime from damagetracker lifetime
36 : struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker
37 : {
38 0 : DamageTracker( SvpSalFrame& rFrame ) : m_rFrame( rFrame ) {}
39 0 : virtual ~DamageTracker() {}
40 0 : virtual void damaged( const basegfx::B2IBox& rDamageRect ) const
41 : {
42 0 : m_rFrame.damaged( rDamageRect );
43 0 : }
44 : SvpSalFrame& m_rFrame;
45 : };
46 : }
47 :
48 0 : void SvpSalFrame::enableDamageTracker( bool bOn )
49 : {
50 0 : if( m_bDamageTracking == bOn )
51 0 : return;
52 0 : if( m_aFrame.get() )
53 : {
54 0 : if( m_bDamageTracking )
55 0 : m_aFrame->setDamageTracker( basebmp::IBitmapDeviceDamageTrackerSharedPtr() );
56 : else
57 : m_aFrame->setDamageTracker(
58 0 : basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker( *this ) ) );
59 : }
60 0 : m_bDamageTracking = bOn;
61 : }
62 :
63 267 : SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance,
64 : SalFrame* pParent,
65 : sal_uLong nSalFrameStyle,
66 : bool bTopDown,
67 : sal_Int32 nScanlineFormat,
68 : SystemParentData* ) :
69 : m_pInstance( pInstance ),
70 : m_pParent( static_cast<SvpSalFrame*>(pParent) ),
71 : m_nStyle( nSalFrameStyle ),
72 : m_bVisible( false ),
73 : m_bDamageTracking( false ),
74 : m_bTopDown( bTopDown ),
75 : m_nScanlineFormat( nScanlineFormat ),
76 : m_nMinWidth( 0 ),
77 : m_nMinHeight( 0 ),
78 : m_nMaxWidth( 0 ),
79 267 : m_nMaxHeight( 0 )
80 : {
81 : // fast and easy cross-platform wiping of the data
82 267 : memset( (void *)&m_aSystemChildData, 0, sizeof( SystemChildData ) );
83 267 : m_aSystemChildData.nSize = sizeof( SystemChildData );
84 : #if defined( UNX ) // FIXME: prolly redundant
85 267 : m_aSystemChildData.pSalFrame = this;
86 : #if defined(ANDROID) || defined(IOS)
87 : // We want 32-bit RGBA bitmaps
88 : m_aSystemChildData.nDepth = 32;
89 : #else
90 267 : m_aSystemChildData.nDepth = 24;
91 : #endif
92 : #endif
93 :
94 267 : if( m_pParent )
95 0 : m_pParent->m_aChildren.push_back( this );
96 :
97 267 : if( m_pInstance )
98 267 : m_pInstance->registerFrame( this );
99 :
100 267 : SetPosSize( 0, 0, 800, 600, SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
101 267 : }
102 :
103 201 : SvpSalFrame::~SvpSalFrame()
104 : {
105 67 : if( m_pInstance )
106 67 : m_pInstance->deregisterFrame( this );
107 :
108 67 : std::list<SvpSalFrame*> Children = m_aChildren;
109 201 : for( std::list<SvpSalFrame*>::iterator it = Children.begin();
110 134 : it != Children.end(); ++it )
111 0 : (*it)->SetParent( m_pParent );
112 67 : if( m_pParent )
113 0 : m_pParent->m_aChildren.remove( this );
114 :
115 67 : if( s_pFocusFrame == this )
116 : {
117 0 : s_pFocusFrame = NULL;
118 : // call directly here, else an event for a destroyed frame would be dispatched
119 0 : CallCallback( SALEVENT_LOSEFOCUS, NULL );
120 : // if the handler has not set a new focus frame
121 : // pass focus to another frame, preferably a document style window
122 0 : if( s_pFocusFrame == NULL )
123 : {
124 0 : const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() );
125 0 : for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
126 : {
127 0 : SvpSalFrame* pFrame = const_cast<SvpSalFrame*>(static_cast<const SvpSalFrame*>(*it));
128 0 : if( pFrame->m_bVisible &&
129 : pFrame->m_pParent == NULL &&
130 : (pFrame->m_nStyle & (SAL_FRAME_STYLE_MOVEABLE |
131 : SAL_FRAME_STYLE_SIZEABLE |
132 : SAL_FRAME_STYLE_CLOSEABLE) ) != 0
133 : )
134 : {
135 0 : pFrame->GetFocus();
136 0 : break;
137 : }
138 : }
139 : }
140 67 : }
141 134 : }
142 :
143 716 : void SvpSalFrame::GetFocus()
144 : {
145 716 : if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_FLOAT)) == 0 )
146 : {
147 716 : if( s_pFocusFrame )
148 649 : s_pFocusFrame->LoseFocus();
149 716 : s_pFocusFrame = this;
150 716 : m_pInstance->PostEvent( this, NULL, SALEVENT_GETFOCUS );
151 : }
152 716 : }
153 :
154 716 : void SvpSalFrame::LoseFocus()
155 : {
156 716 : if( s_pFocusFrame == this )
157 : {
158 716 : m_pInstance->PostEvent( this, NULL, SALEVENT_LOSEFOCUS );
159 716 : s_pFocusFrame = NULL;
160 : }
161 716 : }
162 :
163 9459 : SalGraphics* SvpSalFrame::GetGraphics()
164 : {
165 9459 : SvpSalGraphics* pGraphics = new SvpSalGraphics();
166 9459 : pGraphics->setDevice( m_aFrame );
167 9459 : m_aGraphics.push_back( pGraphics );
168 9459 : return pGraphics;
169 : }
170 :
171 2860 : void SvpSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
172 : {
173 2860 : SvpSalGraphics* pSvpGraphics = dynamic_cast<SvpSalGraphics*>(pGraphics);
174 2860 : m_aGraphics.remove( pSvpGraphics );
175 2860 : delete pSvpGraphics;
176 2860 : }
177 :
178 3077 : sal_Bool SvpSalFrame::PostEvent( void* pData )
179 : {
180 3077 : m_pInstance->PostEvent( this, pData, SALEVENT_USEREVENT );
181 3077 : return sal_True;
182 : }
183 :
184 164 : void SvpSalFrame::PostPaint(bool bImmediate) const
185 : {
186 164 : if( m_bVisible )
187 : {
188 164 : SalPaintEvent aPEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight);
189 164 : aPEvt.mbImmediateUpdate = bImmediate;
190 164 : CallCallback( SALEVENT_PAINT, &aPEvt );
191 : }
192 164 : }
193 :
194 330 : void SvpSalFrame::SetTitle( const rtl::OUString& )
195 : {
196 330 : }
197 :
198 236 : void SvpSalFrame::SetIcon( sal_uInt16 )
199 : {
200 236 : }
201 :
202 0 : void SvpSalFrame::SetMenu( SalMenu* )
203 : {
204 0 : }
205 :
206 0 : void SvpSalFrame::DrawMenuBar()
207 : {
208 0 : }
209 :
210 273 : void SvpSalFrame::SetExtendedFrameStyle( SalExtStyle )
211 : {
212 273 : }
213 :
214 307 : void SvpSalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate )
215 : {
216 307 : if( bVisible && ! m_bVisible )
217 : {
218 240 : m_bVisible = true;
219 240 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
220 480 : if( ! bNoActivate )
221 240 : GetFocus();
222 : }
223 67 : else if( ! bVisible && m_bVisible )
224 : {
225 67 : m_bVisible = false;
226 67 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
227 67 : LoseFocus();
228 : }
229 307 : }
230 :
231 0 : void SvpSalFrame::Enable( sal_Bool )
232 : {
233 0 : }
234 :
235 0 : void SvpSalFrame::SetMinClientSize( long nWidth, long nHeight )
236 : {
237 0 : m_nMinWidth = nWidth;
238 0 : m_nMinHeight = nHeight;
239 0 : }
240 :
241 0 : void SvpSalFrame::SetMaxClientSize( long nWidth, long nHeight )
242 : {
243 0 : m_nMaxWidth = nWidth;
244 0 : m_nMaxHeight = nHeight;
245 0 : }
246 :
247 413 : void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
248 : {
249 413 : if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 )
250 142 : maGeometry.nX = nX;
251 413 : if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0 )
252 142 : maGeometry.nY = nY;
253 413 : if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
254 : {
255 413 : maGeometry.nWidth = nWidth;
256 413 : if( m_nMaxWidth > 0 && maGeometry.nWidth > (unsigned int)m_nMaxWidth )
257 0 : maGeometry.nWidth = m_nMaxWidth;
258 413 : if( m_nMinWidth > 0 && maGeometry.nWidth < (unsigned int)m_nMinWidth )
259 0 : maGeometry.nWidth = m_nMinWidth;
260 : }
261 413 : if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0 )
262 : {
263 413 : maGeometry.nHeight = nHeight;
264 413 : if( m_nMaxHeight > 0 && maGeometry.nHeight > (unsigned int)m_nMaxHeight )
265 0 : maGeometry.nHeight = m_nMaxHeight;
266 413 : if( m_nMinHeight > 0 && maGeometry.nHeight < (unsigned int)m_nMinHeight )
267 0 : maGeometry.nHeight = m_nMinHeight;
268 : }
269 413 : B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight );
270 413 : if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize )
271 : {
272 271 : if( aFrameSize.getX() == 0 )
273 0 : aFrameSize.setX( 1 );
274 271 : if( aFrameSize.getY() == 0 )
275 0 : aFrameSize.setY( 1 );
276 271 : m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat );
277 271 : if (m_bDamageTracking)
278 : m_aFrame->setDamageTracker(
279 0 : basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker( *this ) ) );
280 : // update device in existing graphics
281 825 : for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin();
282 550 : it != m_aGraphics.end(); ++it )
283 4 : (*it)->setDevice( m_aFrame );
284 : }
285 413 : if( m_bVisible )
286 20 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
287 413 : }
288 :
289 533 : void SvpSalFrame::GetClientSize( long& rWidth, long& rHeight )
290 : {
291 533 : if( m_bVisible )
292 : {
293 293 : rWidth = maGeometry.nWidth;
294 293 : rHeight = maGeometry.nHeight;
295 : }
296 : else
297 240 : rWidth = rHeight = 0;
298 533 : }
299 :
300 772 : void SvpSalFrame::GetWorkArea( Rectangle& rRect )
301 : {
302 : rRect = Rectangle( Point( 0, 0 ),
303 772 : Size( VIRTUAL_DESKTOP_WIDTH, VIRTUAL_DESKTOP_HEIGHT ) );
304 772 : }
305 :
306 5825 : SalFrame* SvpSalFrame::GetParent() const
307 : {
308 5825 : return m_pParent;
309 : }
310 :
311 : #define _FRAMESTATE_MASK_GEOMETRY \
312 : (SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | \
313 : SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)
314 :
315 142 : void SvpSalFrame::SetWindowState( const SalFrameState *pState )
316 : {
317 142 : if (pState == NULL)
318 142 : return;
319 :
320 : // Request for position or size change
321 142 : if (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY)
322 : {
323 142 : long nX = maGeometry.nX;
324 142 : long nY = maGeometry.nY;
325 142 : long nWidth = maGeometry.nWidth;
326 142 : long nHeight = maGeometry.nHeight;
327 :
328 : // change requested properties
329 142 : if (pState->mnMask & SAL_FRAMESTATE_MASK_X)
330 142 : nX = pState->mnX;
331 142 : if (pState->mnMask & SAL_FRAMESTATE_MASK_Y)
332 142 : nY = pState->mnY;
333 142 : if (pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH)
334 142 : nWidth = pState->mnWidth;
335 142 : if (pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT)
336 142 : nHeight = pState->mnHeight;
337 :
338 : SetPosSize( nX, nY, nWidth, nHeight,
339 : SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y |
340 142 : SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
341 : }
342 : }
343 :
344 517 : sal_Bool SvpSalFrame::GetWindowState( SalFrameState* pState )
345 : {
346 517 : pState->mnState = SAL_FRAMESTATE_NORMAL;
347 517 : pState->mnX = maGeometry.nX;
348 517 : pState->mnY = maGeometry.nY;
349 517 : pState->mnWidth = maGeometry.nWidth;
350 517 : pState->mnHeight = maGeometry.nHeight;
351 517 : pState->mnMask = _FRAMESTATE_MASK_GEOMETRY | SAL_FRAMESTATE_MASK_STATE;
352 :
353 517 : return sal_True;
354 : }
355 :
356 0 : void SvpSalFrame::ShowFullScreen( sal_Bool, sal_Int32 )
357 : {
358 : SetPosSize( 0, 0, VIRTUAL_DESKTOP_WIDTH, VIRTUAL_DESKTOP_HEIGHT,
359 0 : SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
360 0 : }
361 :
362 0 : void SvpSalFrame::StartPresentation( sal_Bool )
363 : {
364 0 : }
365 :
366 0 : void SvpSalFrame::SetAlwaysOnTop( sal_Bool )
367 : {
368 0 : }
369 :
370 476 : void SvpSalFrame::ToTop( sal_uInt16 )
371 : {
372 476 : GetFocus();
373 476 : }
374 :
375 0 : void SvpSalFrame::SetPointer( PointerStyle )
376 : {
377 0 : }
378 :
379 0 : void SvpSalFrame::CaptureMouse( sal_Bool )
380 : {
381 0 : }
382 :
383 0 : void SvpSalFrame::SetPointerPos( long, long )
384 : {
385 0 : }
386 :
387 8531 : void SvpSalFrame::Flush()
388 : {
389 8531 : }
390 :
391 0 : void SvpSalFrame::Sync()
392 : {
393 0 : }
394 :
395 182 : void SvpSalFrame::SetInputContext( SalInputContext* )
396 : {
397 182 : }
398 :
399 0 : void SvpSalFrame::EndExtTextInput( sal_uInt16 )
400 : {
401 0 : }
402 :
403 22 : rtl::OUString SvpSalFrame::GetKeyName( sal_uInt16 )
404 : {
405 22 : return rtl::OUString();
406 : }
407 :
408 0 : sal_Bool SvpSalFrame::MapUnicodeToKeyCode( sal_Unicode, LanguageType, KeyCode& )
409 : {
410 0 : return sal_False;
411 : }
412 :
413 0 : LanguageType SvpSalFrame::GetInputLanguage()
414 : {
415 0 : return LANGUAGE_DONTKNOW;
416 : }
417 :
418 9 : void SvpSalFrame::UpdateSettings( AllSettings& )
419 : {
420 9 : }
421 :
422 742 : const SystemEnvData* SvpSalFrame::GetSystemData() const
423 : {
424 742 : return &m_aSystemChildData;
425 : }
426 :
427 0 : SalFrame::SalPointerState SvpSalFrame::GetPointerState()
428 : {
429 0 : SalPointerState aState;
430 0 : aState.mnState = 0;
431 0 : return aState;
432 : }
433 :
434 0 : SalFrame::SalIndicatorState SvpSalFrame::GetIndicatorState()
435 : {
436 : SalIndicatorState aState;
437 0 : aState.mnState = 0;
438 0 : return aState;
439 : }
440 :
441 0 : void SvpSalFrame::SimulateKeyPress( sal_uInt16 /*nKeyCode*/ )
442 : {
443 0 : }
444 :
445 0 : void SvpSalFrame::SetParent( SalFrame* pNewParent )
446 : {
447 0 : if( m_pParent )
448 0 : m_pParent->m_aChildren.remove( this );
449 0 : m_pParent = static_cast<SvpSalFrame*>(pNewParent);
450 0 : }
451 :
452 0 : bool SvpSalFrame::SetPluginParent( SystemParentData* )
453 : {
454 0 : return true;
455 : }
456 :
457 0 : void SvpSalFrame::ResetClipRegion()
458 : {
459 0 : }
460 :
461 0 : void SvpSalFrame::BeginSetClipRegion( sal_uLong )
462 : {
463 0 : }
464 :
465 0 : void SvpSalFrame::UnionClipRegion( long, long, long, long )
466 : {
467 0 : }
468 :
469 0 : void SvpSalFrame::EndSetClipRegion()
470 : {
471 0 : }
472 :
473 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|