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
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 3505 : SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance,
65 : SalFrame* pParent,
66 : sal_uLong nSalFrameStyle,
67 : bool bTopDown,
68 : sal_Int32 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 3505 : m_nMaxHeight( 0 )
81 : {
82 : // fast and easy cross-platform wiping of the data
83 3505 : memset( (void *)&m_aSystemChildData, 0, sizeof( SystemChildData ) );
84 3505 : m_aSystemChildData.nSize = sizeof( SystemChildData );
85 : #ifdef IOS
86 : // Nothing
87 : #elif defined ANDROID
88 : // Nothing
89 : #else
90 3505 : m_aSystemChildData.pSalFrame = this;
91 3505 : m_aSystemChildData.nDepth = 24;
92 : #endif
93 :
94 3505 : if( m_pParent )
95 2192 : m_pParent->m_aChildren.push_back( this );
96 :
97 3505 : if( m_pInstance )
98 3505 : m_pInstance->registerFrame( this );
99 :
100 3505 : SetPosSize( 0, 0, 800, 600, SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
101 3505 : }
102 :
103 10347 : SvpSalFrame::~SvpSalFrame()
104 : {
105 3449 : if( m_pInstance )
106 3449 : m_pInstance->deregisterFrame( this );
107 :
108 3449 : std::list<SvpSalFrame*> Children = m_aChildren;
109 10347 : for( std::list<SvpSalFrame*>::iterator it = Children.begin();
110 6898 : it != Children.end(); ++it )
111 0 : (*it)->SetParent( m_pParent );
112 3449 : if( m_pParent )
113 2190 : m_pParent->m_aChildren.remove( this );
114 :
115 3449 : if( s_pFocusFrame == this )
116 : {
117 21 : s_pFocusFrame = NULL;
118 : // call directly here, else an event for a destroyed frame would be dispatched
119 21 : 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 21 : if( s_pFocusFrame == NULL )
123 : {
124 21 : const std::list< SalFrame* >& rFrames( m_pInstance->getFrames() );
125 42 : for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
126 : {
127 39 : SvpSalFrame* pFrame = const_cast<SvpSalFrame*>(static_cast<const SvpSalFrame*>(*it));
128 57 : if( pFrame->m_bVisible &&
129 36 : pFrame->m_pParent == NULL &&
130 18 : (pFrame->m_nStyle & (SAL_FRAME_STYLE_MOVEABLE |
131 : SAL_FRAME_STYLE_SIZEABLE |
132 : SAL_FRAME_STYLE_CLOSEABLE) ) != 0
133 : )
134 : {
135 18 : pFrame->GetFocus();
136 18 : break;
137 : }
138 : }
139 : }
140 3449 : }
141 6898 : }
142 :
143 3387 : void SvpSalFrame::GetFocus()
144 : {
145 3387 : if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_FLOAT)) == 0 )
146 : {
147 3387 : if( s_pFocusFrame )
148 2298 : s_pFocusFrame->LoseFocus();
149 3387 : s_pFocusFrame = this;
150 3387 : m_pInstance->PostEvent( this, NULL, SALEVENT_GETFOCUS );
151 : }
152 3387 : }
153 :
154 3433 : void SvpSalFrame::LoseFocus()
155 : {
156 3433 : if( s_pFocusFrame == this )
157 : {
158 3364 : m_pInstance->PostEvent( this, NULL, SALEVENT_LOSEFOCUS );
159 3364 : s_pFocusFrame = NULL;
160 : }
161 3433 : }
162 :
163 78727 : SalGraphics* SvpSalFrame::GetGraphics()
164 : {
165 78727 : SvpSalGraphics* pGraphics = new SvpSalGraphics();
166 78727 : pGraphics->setDevice( m_aFrame );
167 78727 : m_aGraphics.push_back( pGraphics );
168 78727 : return pGraphics;
169 : }
170 :
171 78402 : void SvpSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
172 : {
173 78402 : SvpSalGraphics* pSvpGraphics = dynamic_cast<SvpSalGraphics*>(pGraphics);
174 78402 : m_aGraphics.remove( pSvpGraphics );
175 78402 : delete pSvpGraphics;
176 78402 : }
177 :
178 16331 : sal_Bool SvpSalFrame::PostEvent( void* pData )
179 : {
180 16331 : m_pInstance->PostEvent( this, pData, SALEVENT_USEREVENT );
181 16331 : return sal_True;
182 : }
183 :
184 1009 : void SvpSalFrame::PostPaint(bool bImmediate) const
185 : {
186 1009 : if( m_bVisible )
187 : {
188 971 : SalPaintEvent aPEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight);
189 971 : aPEvt.mbImmediateUpdate = bImmediate;
190 971 : CallCallback( SALEVENT_PAINT, &aPEvt );
191 : }
192 1009 : }
193 :
194 2367 : void SvpSalFrame::SetTitle( const OUString& )
195 : {
196 2367 : }
197 :
198 1111 : void SvpSalFrame::SetIcon( sal_uInt16 )
199 : {
200 1111 : }
201 :
202 0 : void SvpSalFrame::SetMenu( SalMenu* )
203 : {
204 0 : }
205 :
206 0 : void SvpSalFrame::DrawMenuBar()
207 : {
208 0 : }
209 :
210 2158 : void SvpSalFrame::SetExtendedFrameStyle( SalExtStyle )
211 : {
212 2158 : }
213 :
214 2272 : void SvpSalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate )
215 : {
216 2272 : if( bVisible && ! m_bVisible )
217 : {
218 1137 : m_bVisible = true;
219 1137 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
220 2274 : if( ! bNoActivate )
221 1091 : GetFocus();
222 : }
223 1135 : else if( ! bVisible && m_bVisible )
224 : {
225 1135 : m_bVisible = false;
226 1135 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
227 1135 : LoseFocus();
228 : }
229 2272 : }
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 7456 : void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
248 : {
249 7456 : if( (nFlags & SAL_FRAME_POSSIZE_X) != 0 )
250 1098 : maGeometry.nX = nX;
251 7456 : if( (nFlags & SAL_FRAME_POSSIZE_Y) != 0 )
252 1098 : maGeometry.nY = nY;
253 7456 : if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
254 : {
255 7438 : maGeometry.nWidth = nWidth;
256 7438 : if( m_nMaxWidth > 0 && maGeometry.nWidth > (unsigned int)m_nMaxWidth )
257 0 : maGeometry.nWidth = m_nMaxWidth;
258 7438 : if( m_nMinWidth > 0 && maGeometry.nWidth < (unsigned int)m_nMinWidth )
259 0 : maGeometry.nWidth = m_nMinWidth;
260 : }
261 7456 : if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0 )
262 : {
263 7438 : maGeometry.nHeight = nHeight;
264 7438 : if( m_nMaxHeight > 0 && maGeometry.nHeight > (unsigned int)m_nMaxHeight )
265 0 : maGeometry.nHeight = m_nMaxHeight;
266 7438 : if( m_nMinHeight > 0 && maGeometry.nHeight < (unsigned int)m_nMinHeight )
267 0 : maGeometry.nHeight = m_nMinHeight;
268 : }
269 7456 : B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight );
270 7456 : if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize )
271 : {
272 5895 : if( aFrameSize.getX() == 0 )
273 19 : aFrameSize.setX( 1 );
274 5895 : if( aFrameSize.getY() == 0 )
275 19 : aFrameSize.setY( 1 );
276 5895 : m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat );
277 5895 : if (m_bDamageTracking)
278 : m_aFrame->setDamageTracker(
279 0 : basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker( *this ) ) );
280 : // update device in existing graphics
281 67920 : for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin();
282 45280 : it != m_aGraphics.end(); ++it )
283 16745 : (*it)->setDevice( m_aFrame );
284 : }
285 7456 : if( m_bVisible )
286 11 : m_pInstance->PostEvent( this, NULL, SALEVENT_RESIZE );
287 7456 : }
288 :
289 2242 : void SvpSalFrame::GetClientSize( long& rWidth, long& rHeight )
290 : {
291 2242 : if( m_bVisible )
292 : {
293 1009 : rWidth = maGeometry.nWidth;
294 1009 : rHeight = maGeometry.nHeight;
295 : }
296 : else
297 1233 : rWidth = rHeight = 0;
298 2242 : }
299 :
300 7272 : void SvpSalFrame::GetWorkArea( Rectangle& rRect )
301 : {
302 : rRect = Rectangle( Point( 0, 0 ),
303 7272 : Size( VIRTUAL_DESKTOP_WIDTH, VIRTUAL_DESKTOP_HEIGHT ) );
304 7272 : }
305 :
306 20376 : SalFrame* SvpSalFrame::GetParent() const
307 : {
308 20376 : return m_pParent;
309 : }
310 :
311 : #define _FRAMESTATE_MASK_GEOMETRY \
312 : (WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | \
313 : WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT)
314 :
315 1143 : void SvpSalFrame::SetWindowState( const SalFrameState *pState )
316 : {
317 1143 : if (pState == NULL)
318 1143 : return;
319 :
320 : // Request for position or size change
321 1143 : if (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY)
322 : {
323 1069 : long nX = maGeometry.nX;
324 1069 : long nY = maGeometry.nY;
325 1069 : long nWidth = maGeometry.nWidth;
326 1069 : long nHeight = maGeometry.nHeight;
327 :
328 : // change requested properties
329 1069 : if (pState->mnMask & WINDOWSTATE_MASK_X)
330 1069 : nX = pState->mnX;
331 1069 : if (pState->mnMask & WINDOWSTATE_MASK_Y)
332 1069 : nY = pState->mnY;
333 1069 : if (pState->mnMask & WINDOWSTATE_MASK_WIDTH)
334 1039 : nWidth = pState->mnWidth;
335 1069 : if (pState->mnMask & WINDOWSTATE_MASK_HEIGHT)
336 1039 : nHeight = pState->mnHeight;
337 :
338 : SetPosSize( nX, nY, nWidth, nHeight,
339 : SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y |
340 1069 : SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
341 : }
342 : }
343 :
344 4327 : sal_Bool SvpSalFrame::GetWindowState( SalFrameState* pState )
345 : {
346 4327 : pState->mnState = WINDOWSTATE_STATE_NORMAL;
347 4327 : pState->mnX = maGeometry.nX;
348 4327 : pState->mnY = maGeometry.nY;
349 4327 : pState->mnWidth = maGeometry.nWidth;
350 4327 : pState->mnHeight = maGeometry.nHeight;
351 4327 : pState->mnMask = _FRAMESTATE_MASK_GEOMETRY | WINDOWSTATE_MASK_STATE;
352 :
353 4327 : 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 2278 : void SvpSalFrame::ToTop( sal_uInt16 )
371 : {
372 2278 : GetFocus();
373 2278 : }
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 21285 : void SvpSalFrame::Flush()
388 : {
389 21285 : }
390 :
391 0 : void SvpSalFrame::Sync()
392 : {
393 0 : }
394 :
395 1993 : void SvpSalFrame::SetInputContext( SalInputContext* )
396 : {
397 1993 : }
398 :
399 0 : void SvpSalFrame::EndExtTextInput( sal_uInt16 )
400 : {
401 0 : }
402 :
403 30413 : OUString SvpSalFrame::GetKeyName( sal_uInt16 )
404 : {
405 30413 : return OUString();
406 : }
407 :
408 0 : sal_Bool SvpSalFrame::MapUnicodeToKeyCode( sal_Unicode, LanguageType, KeyCode& )
409 : {
410 0 : return sal_False;
411 : }
412 :
413 1624 : LanguageType SvpSalFrame::GetInputLanguage()
414 : {
415 1624 : return LANGUAGE_DONTKNOW;
416 : }
417 :
418 280 : void SvpSalFrame::UpdateSettings( AllSettings& )
419 : {
420 280 : }
421 :
422 0 : void SvpSalFrame::Beep()
423 : {
424 0 : }
425 :
426 2286 : const SystemEnvData* SvpSalFrame::GetSystemData() const
427 : {
428 2286 : return &m_aSystemChildData;
429 : }
430 :
431 248 : SalFrame::SalPointerState SvpSalFrame::GetPointerState()
432 : {
433 248 : SalPointerState aState;
434 248 : aState.mnState = 0;
435 248 : return aState;
436 : }
437 :
438 0 : SalFrame::SalIndicatorState SvpSalFrame::GetIndicatorState()
439 : {
440 : SalIndicatorState aState;
441 0 : aState.mnState = 0;
442 0 : return aState;
443 : }
444 :
445 0 : void SvpSalFrame::SimulateKeyPress( sal_uInt16 /*nKeyCode*/ )
446 : {
447 0 : }
448 :
449 2324 : void SvpSalFrame::SetParent( SalFrame* pNewParent )
450 : {
451 2324 : if( m_pParent )
452 2324 : m_pParent->m_aChildren.remove( this );
453 2324 : m_pParent = static_cast<SvpSalFrame*>(pNewParent);
454 2324 : }
455 :
456 0 : bool SvpSalFrame::SetPluginParent( SystemParentData* )
457 : {
458 0 : return true;
459 : }
460 :
461 0 : void SvpSalFrame::ResetClipRegion()
462 : {
463 0 : }
464 :
465 0 : void SvpSalFrame::BeginSetClipRegion( sal_uLong )
466 : {
467 0 : }
468 :
469 0 : void SvpSalFrame::UnionClipRegion( long, long, long, long )
470 : {
471 0 : }
472 :
473 0 : void SvpSalFrame::EndSetClipRegion()
474 : {
475 453 : }
476 :
477 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|