Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name rehearsetimingsactivity.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D BOOST_SP_ENABLE_DEBUG_HOOKS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/box2d/Box2D/ -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/slideshow/source/inc -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx

/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx

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
21#include <rtl/ustrbuf.hxx>
22#include <vcl/svapp.hxx>
23#include <vcl/gdimtf.hxx>
24#include <vcl/virdev.hxx>
25#include <vcl/metric.hxx>
26#include <vcl/settings.hxx>
27
28#include <cppcanvas/vclfactory.hxx>
29#include <basegfx/range/b2drange.hxx>
30#include <osl/diagnose.h>
31#include <tools/diagnose_ex.h>
32
33#include <com/sun/star/awt/MouseButton.hpp>
34#include <com/sun/star/awt/MouseEvent.hpp>
35#include <com/sun/star/rendering/XBitmap.hpp>
36#include <com/sun/star/rendering/XCanvas.hpp>
37
38#include <eventqueue.hxx>
39#include <screenupdater.hxx>
40#include <eventmultiplexer.hxx>
41#include <activitiesqueue.hxx>
42#include <slideshowcontext.hxx>
43#include <mouseeventhandler.hxx>
44#include "rehearsetimingsactivity.hxx"
45
46#include <algorithm>
47
48using namespace com::sun::star;
49using namespace com::sun::star::uno;
50
51namespace slideshow::internal {
52
53class RehearseTimingsActivity::WakeupEvent : public Event
54{
55public:
56 WakeupEvent( std::shared_ptr< ::canvas::tools::ElapsedTime > const& pTimeBase,
57 ActivitySharedPtr const& rActivity,
58 ActivitiesQueue & rActivityQueue ) :
59 Event("WakeupEvent"),
60 maTimer(pTimeBase),
61 mnNextTime(0.0),
62 mpActivity(rActivity),
63 mrActivityQueue( rActivityQueue )
64 {}
65
66 WakeupEvent( const WakeupEvent& ) = delete;
67 WakeupEvent& operator=( const WakeupEvent& ) = delete;
68
69 virtual void dispose() override {}
70 virtual bool fire() override
71 {
72 ActivitySharedPtr pActivity( mpActivity.lock() );
73 if( !pActivity )
74 return false;
75
76 return mrActivityQueue.addActivity( pActivity );
77 }
78
79 virtual bool isCharged() const override { return true; }
80 virtual double getActivationTime( double nCurrentTime ) const override
81 {
82 const double nElapsedTime( maTimer.getElapsedTime() );
83
84 return ::std::max( nCurrentTime,
85 nCurrentTime - nElapsedTime + mnNextTime );
86 }
87
88 /// Start the internal timer
89 void start() { maTimer.reset(); }
90
91 /** Set the next timeout this object should generate.
92
93 @param nextTime
94 Absolute time, measured from the last start() call,
95 when this event should wakeup the Activity again. If
96 your time is relative, simply call start() just before
97 every setNextTimeout() call.
98 */
99 void setNextTimeout( double nextTime ) { mnNextTime = nextTime; }
100
101private:
102 ::canvas::tools::ElapsedTime maTimer;
103 double mnNextTime;
104 std::weak_ptr<Activity> mpActivity;
105 ActivitiesQueue& mrActivityQueue;
106};
107
108class RehearseTimingsActivity::MouseHandler : public MouseEventHandler
109{
110public:
111 explicit MouseHandler( RehearseTimingsActivity& rta );
112
113 MouseHandler( const MouseHandler& ) = delete;
114 MouseHandler& operator=( const MouseHandler& ) = delete;
115
116 void reset();
117 bool hasBeenClicked() const { return mbHasBeenClicked; }
118
119 // MouseEventHandler
120 virtual bool handleMousePressed( awt::MouseEvent const & evt ) override;
121 virtual bool handleMouseReleased( awt::MouseEvent const & evt ) override;
122 virtual bool handleMouseDragged( awt::MouseEvent const & evt ) override;
123 virtual bool handleMouseMoved( awt::MouseEvent const & evt ) override;
124
125private:
126 bool isInArea( css::awt::MouseEvent const & evt ) const;
127 void updatePressedState( const bool pressedState ) const;
128
129 RehearseTimingsActivity& mrActivity;
130 bool mbHasBeenClicked;
131 bool mbMouseStartedInArea;
132};
133
134const sal_Int32 LEFT_BORDER_SPACE = 10;
135const sal_Int32 LOWER_BORDER_SPACE = 30;
136
137RehearseTimingsActivity::RehearseTimingsActivity( const SlideShowContext& rContext ) :
138 mrEventQueue(rContext.mrEventQueue),
139 mrScreenUpdater(rContext.mrScreenUpdater),
140 mrEventMultiplexer(rContext.mrEventMultiplexer),
141 mrActivitiesQueue(rContext.mrActivitiesQueue),
142 maElapsedTime( rContext.mrEventQueue.getTimer() ),
143 maViews(),
144 maSpriteRectangle(),
145 maFont( Application::GetSettings().GetStyleSettings().GetLabelFont() ),
146 mpWakeUpEvent(),
147 mpMouseHandler(),
148 maSpriteSizePixel(),
149 mnYOffset(0),
150 mbActive(false),
151 mbDrawPressed(false)
152{
153 maFont.SetFontHeight( maFont.GetFontHeight() * 2 );
154 maFont.SetAverageFontWidth( maFont.GetAverageFontWidth() * 2 );
155 maFont.SetAlignment( ALIGN_BASELINE );
156 maFont.SetColor( COL_BLACK );
157
158 // determine sprite size (in pixel):
159 ScopedVclPtrInstance< VirtualDevice > blackHole;
2
Calling default constructor for 'ScopedVclPtrInstance<VirtualDevice>'
4
Returning from default constructor for 'ScopedVclPtrInstance<VirtualDevice>'
160 blackHole->EnableOutput(false);
161 blackHole->SetFont( maFont );
162 blackHole->SetMapMode(MapMode(MapUnit::MapPixel));
163 tools::Rectangle rect;
164 const FontMetric metric( blackHole->GetFontMetric() );
165 blackHole->GetTextBoundRect( rect, "XX:XX:XX" );
166 maSpriteSizePixel.setX( rect.getWidth() * 12 / 10 );
167 maSpriteSizePixel.setY( metric.GetLineHeight() * 11 / 10 );
168 mnYOffset = (metric.GetAscent() + (metric.GetLineHeight() / 20));
169
170 for( const auto& rView : rContext.mrViewContainer )
171 viewAdded( rView );
172}
5
Calling implicit destructor for 'ScopedVclPtrInstance<VirtualDevice>'
6
Calling '~ScopedVclPtr'
173
174RehearseTimingsActivity::~RehearseTimingsActivity()
175{
176 try
177 {
178 stop();
179 }
180 catch (const uno::Exception&)
181 {
182 TOOLS_WARN_EXCEPTION("slideshow", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "slideshow")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("slideshow"), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "182" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("slideshow"), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "182" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"slideshow"), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "182" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("slideshow"), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "182" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
183 }
184}
185
186std::shared_ptr<RehearseTimingsActivity> RehearseTimingsActivity::create(
187 const SlideShowContext& rContext )
188{
189 std::shared_ptr<RehearseTimingsActivity> pActivity(
190 new RehearseTimingsActivity( rContext ));
1
Calling constructor for 'RehearseTimingsActivity'
191
192 pActivity->mpMouseHandler =
193 std::make_shared<MouseHandler>(*pActivity);
194 pActivity->mpWakeUpEvent =
195 std::make_shared<WakeupEvent>( rContext.mrEventQueue.getTimer(),
196 pActivity,
197 rContext.mrActivitiesQueue );
198
199 rContext.mrEventMultiplexer.addViewHandler( pActivity );
200
201 return pActivity;
202}
203
204void RehearseTimingsActivity::start()
205{
206 maElapsedTime.reset();
207 mbDrawPressed = false;
208 mbActive = true;
209
210 // paint and show all sprites:
211 paintAllSprites();
212 for_each_sprite( []( const ::cppcanvas::CustomSpriteSharedPtr& pSprite )
213 { return pSprite->show(); } );
214
215 mrActivitiesQueue.addActivity( std::dynamic_pointer_cast<Activity>(shared_from_this()) );
216
217 mpMouseHandler->reset();
218 mrEventMultiplexer.addClickHandler(
219 mpMouseHandler, 42 /* highest prio of all, > 3.0 */ );
220 mrEventMultiplexer.addMouseMoveHandler(
221 mpMouseHandler, 42 /* highest prio of all, > 3.0 */ );
222}
223
224double RehearseTimingsActivity::stop()
225{
226 mrEventMultiplexer.removeMouseMoveHandler( mpMouseHandler );
227 mrEventMultiplexer.removeClickHandler( mpMouseHandler );
228
229 mbActive = false; // will be removed from queue
230
231 for_each_sprite( []( const ::cppcanvas::CustomSpriteSharedPtr& pSprite )
232 { return pSprite->hide(); } );
233
234 return maElapsedTime.getElapsedTime();
235}
236
237bool RehearseTimingsActivity::hasBeenClicked() const
238{
239 if (mpMouseHandler)
240 return mpMouseHandler->hasBeenClicked();
241 return false;
242}
243
244// Disposable:
245void RehearseTimingsActivity::dispose()
246{
247 stop();
248
249 mpWakeUpEvent.reset();
250 mpMouseHandler.reset();
251
252 ViewsVecT().swap( maViews );
253}
254
255// Activity:
256double RehearseTimingsActivity::calcTimeLag() const
257{
258 return 0.0;
259}
260
261bool RehearseTimingsActivity::perform()
262{
263 if( !isActive() )
264 return false;
265
266 if( !mpWakeUpEvent )
267 return false;
268
269 mpWakeUpEvent->start();
270 mpWakeUpEvent->setNextTimeout( 0.5 );
271 mrEventQueue.addEvent( mpWakeUpEvent );
272
273 paintAllSprites();
274
275 // sprites changed, need screen update
276 mrScreenUpdater.notifyUpdate();
277
278 return false; // don't reinsert, WakeupEvent will perform
279 // that after the given timeout
280}
281
282bool RehearseTimingsActivity::isActive() const
283{
284 return mbActive;
285}
286
287void RehearseTimingsActivity::dequeued()
288{
289 // not used here
290}
291
292void RehearseTimingsActivity::end()
293{
294 if (isActive())
295 {
296 stop();
297 mbActive = false;
298 }
299}
300
301basegfx::B2DRange RehearseTimingsActivity::calcSpriteRectangle( UnoViewSharedPtr const& rView ) const
302{
303 const Reference<rendering::XBitmap> xBitmap( rView->getCanvas()->getUNOCanvas(),
304 UNO_QUERY );
305 if( !xBitmap.is() )
306 return basegfx::B2DRange();
307
308 const geometry::IntegerSize2D realSize( xBitmap->getSize() );
309 // pixel:
310 basegfx::B2DPoint spritePos(
311 std::min<sal_Int32>( realSize.Width, LEFT_BORDER_SPACE ),
312 std::max<sal_Int32>( 0, realSize.Height - maSpriteSizePixel.getY()
313 - LOWER_BORDER_SPACE ) );
314 basegfx::B2DHomMatrix transformation( rView->getTransformation() );
315 transformation.invert();
316 spritePos *= transformation;
317 basegfx::B2DSize spriteSize( maSpriteSizePixel.getX(),
318 maSpriteSizePixel.getY() );
319 spriteSize *= transformation;
320 return basegfx::B2DRange(
321 spritePos.getX(), spritePos.getY(),
322 spritePos.getX() + spriteSize.getX(),
323 spritePos.getY() + spriteSize.getY() );
324}
325
326void RehearseTimingsActivity::viewAdded( const UnoViewSharedPtr& rView )
327{
328 cppcanvas::CustomSpriteSharedPtr sprite(
329 rView->createSprite( basegfx::B2DSize(
330 maSpriteSizePixel.getX()+2,
331 maSpriteSizePixel.getY()+2 ),
332 1001.0 )); // sprite should be in front of all
333 // other sprites
334 sprite->setAlpha( 0.8 );
335 const basegfx::B2DRange spriteRectangle(
336 calcSpriteRectangle( rView ) );
337 sprite->move( basegfx::B2DPoint(
338 spriteRectangle.getMinX(),
339 spriteRectangle.getMinY() ) );
340
341 if( maViews.empty() )
342 maSpriteRectangle = spriteRectangle;
343
344 maViews.emplace_back( rView, sprite );
345
346 if (isActive())
347 sprite->show();
348}
349
350void RehearseTimingsActivity::viewRemoved( const UnoViewSharedPtr& rView )
351{
352 maViews.erase(
353 std::remove_if( maViews.begin(), maViews.end(),
354 [&rView]
355 ( const ViewsVecT::value_type& cp )
356 { return rView == cp.first; } ),
357 maViews.end() );
358}
359
360void RehearseTimingsActivity::viewChanged( const UnoViewSharedPtr& rView )
361{
362 // find entry corresponding to modified view
363 ViewsVecT::iterator aModifiedEntry(
364 std::find_if(
365 maViews.begin(),
366 maViews.end(),
367 [&rView]
368 ( const ViewsVecT::value_type& cp )
369 { return rView == cp.first; } )
370 );
371
372 OSL_ASSERT( aModifiedEntry != maViews.end() )do { if (true && (!(aModifiedEntry != maViews.end()))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "372" ": "), "OSL_ASSERT: %s", "aModifiedEntry != maViews.end()"
); } } while (false)
;
373 if( aModifiedEntry == maViews.end() )
374 return;
375
376 // new sprite pos, transformation might have changed:
377 maSpriteRectangle = calcSpriteRectangle( rView );
378
379 // reposition sprite:
380 aModifiedEntry->second->move( maSpriteRectangle.getMinimum() );
381
382 // sprites changed, need screen update
383 mrScreenUpdater.notifyUpdate( rView, false );
384}
385
386void RehearseTimingsActivity::viewsChanged()
387{
388 if( maViews.empty() )
389 return;
390
391 // new sprite pos, transformation might have changed:
392 maSpriteRectangle = calcSpriteRectangle( maViews.front().first );
393
394 ::basegfx::B2DPoint nMin = maSpriteRectangle.getMinimum();
395 // reposition sprites
396 for_each_sprite( [nMin]( const ::cppcanvas::CustomSpriteSharedPtr& pSprite )
397 { return pSprite->move( nMin ); } );
398
399 // sprites changed, need screen update
400 mrScreenUpdater.notifyUpdate();
401}
402
403void RehearseTimingsActivity::paintAllSprites() const
404{
405 for_each_sprite(
406 [this]( const ::cppcanvas::CustomSpriteSharedPtr& pSprite )
407 { return this->paint( pSprite->getContentCanvas() ); } );
408}
409
410void RehearseTimingsActivity::paint( cppcanvas::CanvasSharedPtr const & canvas ) const
411{
412 // build timer string:
413 const sal_Int32 nTimeSecs =
414 static_cast<sal_Int32>(maElapsedTime.getElapsedTime());
415 OUStringBuffer buf;
416 sal_Int32 n = nTimeSecs / 3600;
417 if (n < 10)
418 buf.append( '0' );
419 buf.append( n );
420 buf.append( ':' );
421 n = ((nTimeSecs % 3600) / 60);
422 if (n < 10)
423 buf.append( '0' );
424 buf.append( n );
425 buf.append( ':' );
426 n = (nTimeSecs % 60);
427 if (n < 10)
428 buf.append( '0' );
429 buf.append( n );
430 const OUString time = buf.makeStringAndClear();
431
432 // create the MetaFile:
433 GDIMetaFile metaFile;
434 ScopedVclPtrInstance< VirtualDevice > blackHole;
435 metaFile.Record( blackHole );
436 metaFile.SetPrefSize( Size( 1, 1 ) );
437 blackHole->EnableOutput(false);
438 blackHole->SetMapMode(MapMode(MapUnit::MapPixel));
439 blackHole->SetFont( maFont );
440 tools::Rectangle rect( 0,0,
441 maSpriteSizePixel.getX(),
442 maSpriteSizePixel.getY());
443 if (mbDrawPressed)
444 {
445 blackHole->SetTextColor( COL_BLACK );
446 blackHole->SetFillColor( COL_LIGHTGRAY );
447 blackHole->SetLineColor( COL_GRAY );
448 }
449 else
450 {
451 blackHole->SetTextColor( COL_BLACK );
452 blackHole->SetFillColor( COL_WHITE );
453 blackHole->SetLineColor( COL_GRAY );
454 }
455 blackHole->DrawRect( rect );
456 blackHole->GetTextBoundRect( rect, time );
457 blackHole->DrawText(
458 Point( (maSpriteSizePixel.getX() - rect.getWidth()) / 2,
459 mnYOffset ), time );
460
461 metaFile.Stop();
462 metaFile.WindStart();
463
464 cppcanvas::RendererSharedPtr renderer(
465 cppcanvas::VCLFactory::createRenderer(
466 canvas, metaFile, cppcanvas::Renderer::Parameters() ) );
467 const bool succ = renderer->draw();
468 OSL_ASSERT( succ )do { if (true && (!(succ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/slideshow/source/engine/rehearsetimingsactivity.cxx"
":" "468" ": "), "OSL_ASSERT: %s", "succ"); } } while (false
)
;
469}
470
471
472RehearseTimingsActivity::MouseHandler::MouseHandler( RehearseTimingsActivity& rta ) :
473 mrActivity(rta),
474 mbHasBeenClicked(false),
475 mbMouseStartedInArea(false)
476{}
477
478void RehearseTimingsActivity::MouseHandler::reset()
479{
480 mbHasBeenClicked = false;
481 mbMouseStartedInArea = false;
482}
483
484bool RehearseTimingsActivity::MouseHandler::isInArea(
485 awt::MouseEvent const & evt ) const
486{
487 return mrActivity.maSpriteRectangle.isInside(
488 basegfx::B2DPoint( evt.X, evt.Y ) );
489}
490
491void RehearseTimingsActivity::MouseHandler::updatePressedState(
492 const bool pressedState ) const
493{
494 if( pressedState != mrActivity.mbDrawPressed )
495 {
496 mrActivity.mbDrawPressed = pressedState;
497 mrActivity.paintAllSprites();
498
499 mrActivity.mrScreenUpdater.notifyUpdate();
500 }
501}
502
503// MouseEventHandler
504bool RehearseTimingsActivity::MouseHandler::handleMousePressed(
505 awt::MouseEvent const & evt )
506{
507 if( evt.Buttons == awt::MouseButton::LEFT && isInArea(evt) )
508 {
509 mbMouseStartedInArea = true;
510 updatePressedState(true);
511 return true; // consume event
512 }
513 return false;
514}
515
516bool RehearseTimingsActivity::MouseHandler::handleMouseReleased(
517 awt::MouseEvent const & evt )
518{
519 if( evt.Buttons == awt::MouseButton::LEFT && mbMouseStartedInArea )
520 {
521 mbHasBeenClicked = isInArea(evt); // fini if in
522 mbMouseStartedInArea = false;
523 updatePressedState(false);
524 if( !mbHasBeenClicked )
525 return true; // consume event, else next slide (manual advance)
526 }
527 return false;
528}
529
530bool RehearseTimingsActivity::MouseHandler::handleMouseDragged(
531 awt::MouseEvent const & evt )
532{
533 if( mbMouseStartedInArea )
534 updatePressedState( isInArea(evt) );
535 return false;
536}
537
538bool RehearseTimingsActivity::MouseHandler::handleMouseMoved(
539 awt::MouseEvent const & /*evt*/ )
540{
541 return false;
542}
543
544} // namespace presentation
545
546/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
8
Calling 'Reference::clear'
15
Returning; memory was released
205 if (aTmp.get()) {
16
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
7
Calling 'VclPtr::disposeAndClear'
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
3
Memory is allocated
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
)
9
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
10
Calling 'VclReferenceBase::release'
14
Returning; memory was released
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
17
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
11
Assuming the condition is true
12
Taking true branch
40 delete this;
13
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif