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 gtk3atkutil.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 -isystem /usr/include/gtk-3.0 -isystem /usr/include/pango-1.0 -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/harfbuzz -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/fribidi -isystem /usr/include/libxml2 -isystem /usr/include/cairo -isystem /usr/include/pixman-1 -isystem /usr/include/gdk-pixbuf-2.0 -isystem /usr/include/gio-unix-2.0 -isystem /usr/include/atk-1.0 -isystem /usr/include/at-spi2-atk/2.0 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/at-spi-2.0 -isystem /usr/include/gtk-3.0/unix-print -isystem /usr/include/gstreamer-1.0 -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/orc-0.4 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -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 VCLPLUG_GTK_IMPLEMENTATION -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -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/vcl/inc -I /home/maarten/src/libreoffice/core/vcl/unx -I /home/maarten/src/libreoffice/core/vcl/unx/gtk3 -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 -Wno-deprecated-declarations -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/vcl/unx/gtk3/a11y/gtk3atkutil.cxx

/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.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#ifdef AIX
21#define _LINUX_SOURCE_COMPAT
22#include <sys/timer.h>
23#undef _LINUX_SOURCE_COMPAT
24#endif
25
26#include <com/sun/star/accessibility/XAccessibleContext.hpp>
27#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
28#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
29#include <com/sun/star/accessibility/AccessibleEventId.hpp>
30#include <com/sun/star/accessibility/AccessibleStateType.hpp>
31#include <com/sun/star/accessibility/XAccessibleText.hpp>
32#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33#include <cppuhelper/implbase.hxx>
34#include <cppuhelper/weakref.hxx>
35#include <sal/log.hxx>
36
37#include <vcl/svapp.hxx>
38#include <vcl/window.hxx>
39#include <vcl/menu.hxx>
40#include <vcl/toolbox.hxx>
41
42#include <unx/gtk/gtkdata.hxx>
43#include "atkwrapper.hxx"
44#include "atkutil.hxx"
45
46#include <cassert>
47#include <set>
48
49using namespace ::com::sun::star;
50
51namespace
52{
53 struct theNextFocusObject :
54 public rtl::Static< uno::WeakReference< accessibility::XAccessible >, theNextFocusObject>
55 {
56 };
57}
58
59static guint focus_notify_handler = 0;
60
61/*****************************************************************************/
62
63extern "C" {
64
65static gboolean
66atk_wrapper_focus_idle_handler (gpointer data)
67{
68 SolarMutexGuard aGuard;
69
70 focus_notify_handler = 0;
71
72 uno::Reference< accessibility::XAccessible > xAccessible = theNextFocusObject::get();
73 if( xAccessible.get() == static_cast < accessibility::XAccessible * > (data) )
74 {
75 AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : nullptr;
76 // Gail does not notify focus changes to NULL, so do we ..
77 if( atk_obj )
78 {
79 SAL_WNODEPRECATED_DECLARATIONS_PUSHGCC diagnostic push GCC diagnostic ignored "-Wdeprecated-declarations"
80 atk_focus_tracker_notify(atk_obj);
81 SAL_WNODEPRECATED_DECLARATIONS_POPGCC diagnostic pop
82 // #i93269#
83 // emit text_caret_moved event for <XAccessibleText> object,
84 // if cursor is inside the <XAccessibleText> object.
85 // also emit state-changed:focused event under the same condition.
86 {
87 AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj)((((AtkObjectWrapper*) g_type_check_instance_cast ((GTypeInstance
*) ((atk_obj)), (atk_object_wrapper_get_type())))))
;
88 if( wrapper_obj && !wrapper_obj->mpText.is() )
89 {
90 wrapper_obj->mpText.set(wrapper_obj->mpContext, css::uno::UNO_QUERY);
91 if ( wrapper_obj->mpText.is() )
92 {
93 gint caretPos = -1;
94
95 try {
96 caretPos = wrapper_obj->mpText->getCaretPosition();
97 }
98 catch(const uno::Exception&) {
99 g_warning( "Exception in getCaretPosition()" );
100 }
101
102 if ( caretPos != -1 )
103 {
104 atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, true );
105 g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos );
106 }
107 }
108 }
109 }
110 g_object_unref(atk_obj);
111 }
112 }
113
114 return false;
115}
116
117} // extern "C"
118
119/*****************************************************************************/
120
121static void
122atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible )
123{
124 if( focus_notify_handler )
125 g_source_remove(focus_notify_handler);
126
127 theNextFocusObject::get() = xAccessible;
128
129 focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get());
130}
131
132/*****************************************************************************/
133
134class DocumentFocusListener :
135 public ::cppu::WeakImplHelper< accessibility::XAccessibleEventListener >
136{
137
138 std::set< uno::Reference< uno::XInterface > > m_aRefList;
139
140public:
141 /// @throws lang::IndexOutOfBoundsException
142 /// @throws uno::RuntimeException
143 void attachRecursive(
144 const uno::Reference< accessibility::XAccessible >& xAccessible
145 );
146
147 /// @throws lang::IndexOutOfBoundsException
148 /// @throws uno::RuntimeException
149 void attachRecursive(
150 const uno::Reference< accessibility::XAccessible >& xAccessible,
151 const uno::Reference< accessibility::XAccessibleContext >& xContext
152 );
153
154 /// @throws lang::IndexOutOfBoundsException
155 /// @throws uno::RuntimeException
156 void attachRecursive(
157 const uno::Reference< accessibility::XAccessible >& xAccessible,
158 const uno::Reference< accessibility::XAccessibleContext >& xContext,
159 const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
160 );
161
162 /// @throws lang::IndexOutOfBoundsException
163 /// @throws uno::RuntimeException
164 void detachRecursive(
165 const uno::Reference< accessibility::XAccessible >& xAccessible
166 );
167
168 /// @throws lang::IndexOutOfBoundsException
169 /// @throws uno::RuntimeException
170 void detachRecursive(
171 const uno::Reference< accessibility::XAccessibleContext >& xContext
172 );
173
174 /// @throws lang::IndexOutOfBoundsException
175 /// @throws uno::RuntimeException
176 void detachRecursive(
177 const uno::Reference< accessibility::XAccessibleContext >& xContext,
178 const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
179 );
180
181 /// @throws lang::IndexOutOfBoundsException
182 /// @throws uno::RuntimeException
183 static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent );
184
185 // XEventListener
186 virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
187
188 // XAccessibleEventListener
189 virtual void SAL_CALL notifyEvent( const accessibility::AccessibleEventObject& aEvent ) override;
190};
191
192/*****************************************************************************/
193
194void DocumentFocusListener::disposing( const lang::EventObject& aEvent )
195{
196
197 // Unref the object here, but do not remove as listener since the object
198 // might no longer be in a state that safely allows this.
199 if( aEvent.Source.is() )
200 m_aRefList.erase(aEvent.Source);
201
202}
203
204/*****************************************************************************/
205
206void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent )
207{
208 try {
209 switch( aEvent.EventId )
210 {
211 case accessibility::AccessibleEventId::STATE_CHANGED:
212 {
213 sal_Int16 nState = accessibility::AccessibleStateType::INVALID;
214 aEvent.NewValue >>= nState;
215
216 if( accessibility::AccessibleStateType::FOCUSED == nState )
217 atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) );
218
219 break;
220 }
221
222 case accessibility::AccessibleEventId::CHILD:
223 {
224 uno::Reference< accessibility::XAccessible > xChild;
225 if( (aEvent.OldValue >>= xChild) && xChild.is() )
226 detachRecursive(xChild);
227
228 if( (aEvent.NewValue >>= xChild) && xChild.is() )
229 attachRecursive(xChild);
230
231 break;
232 }
233
234 case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN:
235 SAL_INFO("vcl.a11y", "Invalidate all children called")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "vcl.a11y")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Invalidate all children called"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.a11y"
), ("/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
":" "235" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Invalidate all children called"), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Invalidate all children called"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.a11y"), ("/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
":" "235" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Invalidate all children called") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.a11y"), ("/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
":" "235" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Invalidate all children called"), 0);
} else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Invalidate all children called"; ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.a11y"), ("/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
":" "235" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
236 break;
237
238 default:
239 break;
240 }
241 }
242 catch( const lang::IndexOutOfBoundsException& )
243 {
244 g_warning("Focused object has invalid index in parent");
245 }
246}
247
248/*****************************************************************************/
249
250uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent )
251{
252 uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY);
253
254 if( xAccessible.is() )
255 return xAccessible;
256
257 uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY);
258
259 if( xContext.is() )
260 {
261 uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() );
262 if( xParent.is() )
263 {
264 uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
265 if( xParentContext.is() )
266 {
267 return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
268 }
269 }
270 }
271
272 return uno::Reference< accessibility::XAccessible >();
273}
274
275/*****************************************************************************/
276
277void DocumentFocusListener::attachRecursive(
278 const uno::Reference< accessibility::XAccessible >& xAccessible
279)
280{
281 uno::Reference< accessibility::XAccessibleContext > xContext =
282 xAccessible->getAccessibleContext();
283
284 if( xContext.is() )
285 attachRecursive(xAccessible, xContext);
286}
287
288/*****************************************************************************/
289
290void DocumentFocusListener::attachRecursive(
291 const uno::Reference< accessibility::XAccessible >& xAccessible,
292 const uno::Reference< accessibility::XAccessibleContext >& xContext
293)
294{
295 uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
296 xContext->getAccessibleStateSet();
297
298 if( xStateSet.is() )
299 attachRecursive(xAccessible, xContext, xStateSet);
300}
301
302/*****************************************************************************/
303
304void DocumentFocusListener::attachRecursive(
305 const uno::Reference< accessibility::XAccessible >& xAccessible,
306 const uno::Reference< accessibility::XAccessibleContext >& xContext,
307 const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
308)
309{
310 if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) )
311 atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
312
313 uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY);
314
315 if (!xBroadcaster.is())
316 return;
317
318 // If not already done, add the broadcaster to the list and attach as listener.
319 const uno::Reference< uno::XInterface >& xInterface = xBroadcaster;
320 if( !m_aRefList.insert(xInterface).second )
321 return;
322
323 xBroadcaster->addAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
324
325 if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
326 {
327 sal_Int32 n, nmax = xContext->getAccessibleChildCount();
328 for( n = 0; n < nmax; n++ )
329 {
330 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
331
332 if( xChild.is() )
333 attachRecursive(xChild);
334 }
335 }
336}
337
338/*****************************************************************************/
339
340void DocumentFocusListener::detachRecursive(
341 const uno::Reference< accessibility::XAccessible >& xAccessible
342)
343{
344 uno::Reference< accessibility::XAccessibleContext > xContext =
345 xAccessible->getAccessibleContext();
346
347 if( xContext.is() )
348 detachRecursive(xContext);
349}
350
351/*****************************************************************************/
352
353void DocumentFocusListener::detachRecursive(
354 const uno::Reference< accessibility::XAccessibleContext >& xContext
355)
356{
357 uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
358 xContext->getAccessibleStateSet();
359
360 if( xStateSet.is() )
361 detachRecursive(xContext, xStateSet);
362}
363
364/*****************************************************************************/
365
366void DocumentFocusListener::detachRecursive(
367 const uno::Reference< accessibility::XAccessibleContext >& xContext,
368 const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
369)
370{
371 uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY);
372
373 if( !xBroadcaster.is() || 0 >= m_aRefList.erase(xBroadcaster) )
374 return;
375
376 xBroadcaster->removeAccessibleEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
377
378 if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
379 {
380 sal_Int32 n, nmax = xContext->getAccessibleChildCount();
381 for( n = 0; n < nmax; n++ )
382 {
383 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
384
385 if( xChild.is() )
386 detachRecursive(xChild);
387 }
388 }
389}
390
391/*****************************************************************************/
392
393/*
394 * page tabs in gtk are widgets, so we need to simulate focus events for those
395 */
396
397static void handle_tabpage_activated(vcl::Window *pWindow)
398{
399 uno::Reference< accessibility::XAccessible > xAccessible =
400 pWindow->GetAccessible();
401
402 if( ! xAccessible.is() )
403 return;
404
405 uno::Reference< accessibility::XAccessibleSelection > xSelection(
406 xAccessible->getAccessibleContext(), uno::UNO_QUERY);
407
408 if( xSelection.is() )
409 atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) );
410}
411
412/*****************************************************************************/
413
414/*
415 * toolbar items in gtk are widgets, so we need to simulate focus events for those
416 */
417
418static void notify_toolbox_item_focus(ToolBox *pToolBox)
419{
420 uno::Reference< accessibility::XAccessible > xAccessible =
421 pToolBox->GetAccessible();
422
423 if( ! xAccessible.is() )
424 return;
425
426 uno::Reference< accessibility::XAccessibleContext > xContext =
427 xAccessible->getAccessibleContext();
428
429 if( ! xContext.is() )
430 return;
431
432 ToolBox::ImplToolItems::size_type nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
433 if( nPos != ToolBox::ITEM_NOTFOUND )
434 atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
435 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32
436}
437
438static void handle_toolbox_highlight(vcl::Window *pWindow)
439{
440 ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
441
442 // Make sure either the toolbox or its parent toolbox has the focus
443 if ( ! pToolBox->HasFocus() )
444 {
445 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
446 if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() )
447 return;
448 }
449
450 notify_toolbox_item_focus(pToolBox);
451}
452
453static void handle_toolbox_highlightoff(vcl::Window const *pWindow)
454{
455 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pWindow->GetParent() );
456
457 // Notify when leaving sub toolboxes
458 if( pToolBoxParent && pToolBoxParent->HasFocus() )
459 notify_toolbox_item_focus( pToolBoxParent );
460}
461
462/*****************************************************************************/
463
464static void create_wrapper_for_child(
465 const uno::Reference< accessibility::XAccessibleContext >& xContext,
466 sal_Int32 index)
467{
468 if( xContext.is() )
469 {
470 uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index));
471 if( xChild.is() )
472 {
473 // create the wrapper object - it will survive the unref unless it is a transient object
474 g_object_unref( atk_object_wrapper_ref( xChild ) );
475 }
476 }
477}
478
479/*****************************************************************************/
480
481static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent)
482{
483 vcl::Window* pWindow = pEvent->GetWindow();
484 sal_Int32 index = static_cast<sal_Int32>(reinterpret_cast<sal_IntPtr>(pEvent->GetData()));
485
486 if( pWindow && pWindow->IsReallyVisible() )
487 {
488 uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
489 if( xAccessible.is() )
490 {
491 create_wrapper_for_child(xAccessible->getAccessibleContext(), index);
492 }
493 }
494}
495
496/*****************************************************************************/
497
498namespace {
499
500struct WindowList {
501 ~WindowList() { assert(list.empty())(static_cast <bool> (list.empty()) ? void (0) : __assert_fail
("list.empty()", "/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
, 501, __extension__ __PRETTY_FUNCTION__))
; };
502 // needs to be empty already on DeInitVCL, but at least check it's empty
503 // on exit
504
505 std::set< VclPtr<vcl::Window> > list;
506};
507
508WindowList g_aWindowList;
509
510}
511
512DocumentFocusListener & GtkSalData::GetDocumentFocusListener()
513{
514 if (!m_pDocumentFocusListener)
515 {
516 m_pDocumentFocusListener = new DocumentFocusListener;
517 m_xDocumentFocusListener.set(m_pDocumentFocusListener);
518 }
519 return *m_pDocumentFocusListener;
520}
521
522static void handle_get_focus(::VclWindowEvent const * pEvent)
523{
524 GtkSalData *const pSalData(GetGtkSalData());
525 assert(pSalData)(static_cast <bool> (pSalData) ? void (0) : __assert_fail
("pSalData", "/home/maarten/src/libreoffice/core/vcl/unx/gtk3/a11y/gtk3atkutil.cxx"
, 525, __extension__ __PRETTY_FUNCTION__))
;
526
527 DocumentFocusListener & rDocumentFocusListener(pSalData->GetDocumentFocusListener());
528
529 vcl::Window *pWindow = pEvent->GetWindow();
530
531 // The menu bar is handled through VclEventId::MenuHighlightED
532 if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WindowType::MENUBARWINDOW )
533 return;
534
535 // ToolBoxes are handled through VclEventId::ToolboxHighlight
536 if( pWindow->GetType() == WindowType::TOOLBOX )
537 return;
538
539 if( pWindow->GetType() == WindowType::TABCONTROL )
540 {
541 handle_tabpage_activated( pWindow );
542 return;
543 }
544
545 uno::Reference< accessibility::XAccessible > xAccessible =
546 pWindow->GetAccessible();
547
548 if( ! xAccessible.is() )
549 return;
550
551 uno::Reference< accessibility::XAccessibleContext > xContext =
552 xAccessible->getAccessibleContext();
553
554 if( ! xContext.is() )
555 return;
556
557 uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
558 xContext->getAccessibleStateSet();
559
560 if( ! xStateSet.is() )
561 return;
562
563/* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we
564 * need to add listeners to the children instead of re-using the tabpage stuff
565 */
566 if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) &&
567 ( pWindow->GetType() != WindowType::TREELISTBOX ) )
568 {
569 atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
570 }
571 else
572 {
573 if( g_aWindowList.list.insert(pWindow).second )
574 {
575 try
576 {
577 rDocumentFocusListener.attachRecursive(xAccessible, xContext, xStateSet);
578 }
579 catch (const uno::Exception&)
580 {
581 g_warning( "Exception caught processing focus events" );
582 }
583 }
584 }
585}
586
587/*****************************************************************************/
588
589static void handle_menu_highlighted(::VclMenuEvent const * pEvent)
590{
591 try
592 {
593 Menu* pMenu = pEvent->GetMenu();
594 sal_uInt16 nPos = pEvent->GetItemPos();
595
596 if( pMenu && nPos != 0xFFFF)
597 {
598 uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() );
599
600 if( xAccessible.is() )
601 {
602 uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() );
603
604 if( xContext.is() )
605 atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
606 }
607 }
608 }
609 catch (const uno::Exception&)
610 {
611 g_warning( "Exception caught processing menu highlight events" );
612 }
613}
614
615/*****************************************************************************/
616
617static void WindowEventHandler(void *, VclSimpleEvent& rEvent)
618{
619 try
620 {
621 switch (rEvent.GetId())
1
Control jumps to 'case ObjectDying:' at line 659
622 {
623 case VclEventId::WindowShow:
624 break;
625 case VclEventId::WindowHide:
626 break;
627 case VclEventId::WindowClose:
628 break;
629 case VclEventId::WindowGetFocus:
630 handle_get_focus(static_cast< ::VclWindowEvent const * >(&rEvent));
631 break;
632 case VclEventId::WindowLoseFocus:
633 break;
634 case VclEventId::WindowMinimize:
635 break;
636 case VclEventId::WindowNormalize:
637 break;
638 case VclEventId::WindowKeyInput:
639 case VclEventId::WindowKeyUp:
640 case VclEventId::WindowCommand:
641 case VclEventId::WindowMouseMove:
642 break;
643
644 case VclEventId::MenuHighlight:
645 if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(&rEvent))
646 {
647 handle_menu_highlighted(pMenuEvent);
648 }
649 break;
650
651 case VclEventId::ToolboxHighlight:
652 handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow());
653 break;
654
655 case VclEventId::ToolboxButtonStateChanged:
656 handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(&rEvent));
657 break;
658
659 case VclEventId::ObjectDying:
660 g_aWindowList.list.erase( static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow() );
2
Calling constructor for 'VclPtr<vcl::Window>'
7
Returning from constructor for 'VclPtr<vcl::Window>'
8
Calling implicit destructor for 'VclPtr<vcl::Window>'
9
Calling '~Reference'
16
Returning from '~Reference'
17
Returning from destructor for 'VclPtr<vcl::Window>'
661 [[fallthrough]];
662 case VclEventId::ToolboxHighlightOff:
663 handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow());
18
Calling 'VclWindowEvent::GetWindow'
664 break;
665
666 case VclEventId::TabpageActivate:
667 handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(&rEvent)->GetWindow());
668 break;
669
670 case VclEventId::ComboboxSetText:
671 // This looks quite strange to me. Stumbled over this when fixing #i104290#.
672 // This kicked in when leaving the combobox in the toolbar, after that the events worked.
673 // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore.
674 // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general.
675 // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
676 break;
677
678 default:
679 break;
680 }
681 }
682 catch (const lang::IndexOutOfBoundsException&)
683 {
684 g_warning("Focused object has invalid index in parent");
685 }
686}
687
688static Link<VclSimpleEvent&,void> g_aEventListenerLink( nullptr, WindowEventHandler );
689
690/*****************************************************************************/
691
692void ooo_atk_util_ensure_event_listener()
693{
694 static bool bInited;
695 if (!bInited)
696 {
697 Application::AddEventListener( g_aEventListenerLink );
698 bInited = true;
699 }
700}
701
702/* 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)
3
Calling constructor for 'Reference<vcl::Window>'
6
Returning from constructor for 'Reference<vcl::Window>'
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();
20
Calling 'Reference::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 ;-)
205 if (aTmp.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();
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 )
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)
4
Assuming field 'm_pBody' is non-null
5
Taking true branch
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
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
)
10
Taking true branch
113 m_pBody->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
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)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
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;
21
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)
12
Assuming the condition is true
13
Taking true branch
40 delete this;
14
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

/home/maarten/src/libreoffice/core/include/vcl/vclevent.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_VCLEVENT_HXX
21#define INCLUDED_VCL_VCLEVENT_HXX
22
23#include <vcl/dllapi.h>
24#include <vcl/vclptr.hxx>
25
26class Menu;
27
28namespace com::sun::star::accessibility {
29 class XAccessible;
30}
31
32namespace vcl
33{
34 class Window;
35}
36
37enum class VclEventId
38{
39 NONE,
40 ApplicationDataChanged, // pData = DataChangedEvent*
41 ButtonClick,
42 CheckboxToggle,
43 ComboboxDeselect,
44 ComboboxDoubleClick,
45 ComboboxItemAdded, // pData = itempos
46 ComboboxItemRemoved, // pData = itempos, -1=All
47 ComboboxSelect,
48 ComboboxSetText,
49 ControlGetFocus,
50 ControlLoseFocus,
51 DropdownClose,
52 DropdownOpen,
53 DropdownPreOpen,
54 DropdownSelect,
55 EditCaretChanged,
56 EditModify,
57 EditSelectionChanged,
58 ExtTextInput,
59 EndExtTextInput,
60 ItemCollapsed,
61 ItemExpanded,
62 ListboxDoubleClick,
63 ListboxFocus,
64 ListboxItemAdded, // pData = itempos
65 ListboxItemRemoved, // pData = itempos, -1=All
66 ListboxScrolled,
67 ListboxSelect,
68 ListboxTreeFocus,
69 ListboxTreeSelect,
70 MenuAccessibleNameChanged,
71 MenuActivate,
72 MenuDeactivate,
73 MenuDehighlight,
74 MenuDisable,
75 MenuEnable,
76 MenuHide,
77 MenuHighlight,
78 MenuInsertItem,
79 MenuItemChecked,
80 MenuItemTextChanged,
81 MenuItemUnchecked,
82 MenuRemoveItem,
83 MenuSelect,
84 MenuShow,
85 MenuSubmenuActivate,
86 MenuSubmenuChanged,
87 MenuSubmenuDeactivate,
88 ObjectDying,
89 PushbuttonToggle,
90 RadiobuttonToggle,
91 RoadmapItemSelected,
92 ScrollbarEndScroll,
93 ScrollbarScroll,
94 SpinbuttonDown,
95 SpinbuttonUp,
96 SpinfieldDown,
97 SpinfieldFirst,
98 SpinfieldLast,
99 SpinfieldUp,
100 StatusbarAllItemsRemoved,
101 StatusbarDrawItem, // pData = itemid
102 StatusbarHideItem, // pData = itemid
103 StatusbarItemAdded, // pData = itemid
104 StatusbarItemRemoved, // pData = itemid
105 StatusbarNameChanged, // pData = itemid
106 StatusbarShowItem, // pData = itemid
107 TabbarPageActivated, // pData = pageid
108 TabbarPageDeactivated, // pData = pageid
109 TabbarPageInserted, // pData = pageid
110 TabbarPageMoved, // pData = Pair( pagepos_old, pagepos_new )
111 TabbarPageRemoved, // pData = pageid
112 TabbarPageSelected, // pData = pageid
113 TabbarPageTextChanged, // pData = pageid
114 TableRowSelect,
115 TabpageActivate, // pData = pageid
116 TabpageDeactivate, // pData = pageid
117 TabpageInserted, // pData = pageid
118 TabpagePageTextChanged, // pData = pageid
119 TabpageRemoved, // pData = pageid
120 TabpageRemovedAll,
121 ToolboxActivate,
122 ToolboxAllItemsChanged,
123 ToolboxButtonStateChanged, // pData = itempos
124 ToolboxClick,
125 ToolboxDeactivate,
126 ToolboxDoubleClick,
127 ToolboxFormatChanged, // request new layout
128 ToolboxHighlight,
129 ToolboxHighlightOff, // pData = itempos
130 ToolboxItemAdded, // pData = itempos
131 ToolboxItemDisabled, // pData = itempos
132 ToolboxItemEnabled, // pData = itempos
133 ToolboxItemRemoved, // pData = itempos
134 ToolboxItemTextChanged, // pData = itempos
135 ToolboxItemUpdated,
136 ToolboxItemWindowChanged,
137 ToolboxSelect,
138 WindowActivate,
139 WindowChildDestroyed, // pData = vcl::Window*
140 WindowClose,
141 WindowCommand, // pData = CommandEvent*
142 WindowDataChanged, // pData = DataChangedEvent*
143 WindowDeactivate, // pData = vcl::Window* = pPrevActiveWindow
144 WindowDisabled,
145 WindowDocking,
146 WindowEnabled,
147 WindowEndDocking, // pData = EndDockingData
148 WindowEndPopupMode, // pData = EndPopupModeData
149 WindowFrameTitleChanged,// pData = OUString* = oldTitle
150 WindowGetFocus,
151 WindowHide,
152 WindowKeyInput, // pData = KeyEvent*
153 WindowKeyUp, // pData = KeyEvent*
154 WindowLoseFocus,
155 WindowMenubarAdded, // pData = pMenuBar
156 WindowMenubarRemoved, // pData = pMenuBar
157 WindowMinimize,
158 WindowMouseButtonDown, // pData = MouseEvent*
159 WindowMouseButtonUp, // pData = MouseEvent*
160 WindowMouseMove, // pData = MouseEvent*
161 WindowMove,
162 WindowNormalize,
163 WindowPaint, // pData = Rectangle*
164 WindowPrepareToggleFloating, // pData = bool
165 WindowResize,
166 WindowShow,
167 WindowStartDocking, // pData = DockingData
168 WindowToggleFloating,
169 WindowGestureEvent,
170};
171
172class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclSimpleEvent
173{
174private:
175 VclEventId nId;
176
177 VclSimpleEvent(VclSimpleEvent const &) = delete;
178 VclSimpleEvent& operator =(VclSimpleEvent const &) = delete;
179
180public:
181 VclSimpleEvent( VclEventId n ) { nId = n; }
182 virtual ~VclSimpleEvent() {}
183
184 VclEventId GetId() const { return nId; }
185};
186
187class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclWindowEvent final : public VclSimpleEvent
188{
189private:
190 VclPtr<vcl::Window> pWindow;
191 void* pData;
192
193public:
194 VclWindowEvent( vcl::Window* pWin, VclEventId n, void* pDat );
195 virtual ~VclWindowEvent() override;
196
197 vcl::Window* GetWindow() const { return pWindow; }
19
Calling 'VclPtr::operator vcl::Window *'
198 void* GetData() const { return pData; }
199};
200
201class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclMenuEvent final : public VclSimpleEvent
202{
203private:
204 VclPtr<Menu> pMenu;
205 sal_uInt16 mnPos;
206
207 VclMenuEvent(VclMenuEvent const &) = delete;
208 VclMenuEvent& operator =(VclMenuEvent const &) = delete;
209
210public:
211 VclMenuEvent( Menu* pM, VclEventId n, sal_uInt16 nPos );
212 virtual ~VclMenuEvent() override;
213
214 Menu* GetMenu() const;
215 sal_uInt16 GetItemPos() const { return mnPos; }
216};
217
218#endif // INCLUDED_VCL_VCLEVENT_HXX
219
220/* vim:set shiftwidth=4 softtabstop=4 expandtab: */