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