Bug Summary

File:usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h
Warning:line 646, column 9
Potential leak of memory pointed to by 'callable'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dis_stream_dialog.cpp -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 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /builds/wireshark/wireshark/ui/qt/lua_debugger -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6/QtSvg -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_SVG_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-06-07-100346-3530-1 -x c++ /builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

/builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

1/* dis_stream_dialog.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <[email protected]>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "dis_stream_dialog.h"
11
12#include "dis_audio_stream.h"
13
14#include <QFile>
15#include <QFileDialog>
16#include <QHeaderView>
17#include <QMenu>
18#include <QMetaObject>
19#include <QMessageBox>
20#include <QFormLayout>
21#include <QSignalBlocker>
22#include <QTextStream>
23#include <QVBoxLayout>
24
25#include "epan/addr_resolv.h"
26
27#include "main_application.h"
28
29DisStreamDialog *DisStreamDialog::pinstance_ = nullptr;
30std::mutex DisStreamDialog::mutex_;
31
32enum {
33 dis_col_start_time = 0,
34 dis_col_end_time,
35 dis_col_src_addr,
36 dis_col_src_port,
37 dis_col_dst_addr,
38 dis_col_dst_port,
39 dis_col_radio,
40 dis_col_entity,
41 dis_col_signal_pkts,
42 dis_col_tx_pkts,
43 dis_col_lost,
44 dis_col_max_delta,
45 dis_col_mean_jitter,
46 dis_col_max_jitter,
47 dis_col_problem,
48 dis_col_count
49};
50
51static constexpr int disstream_ptr_role = Qt::UserRole + 100;
52
53bool
54DisStreamDialog::DisStreamTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
55{
56 int sort_col = treeWidget() ? treeWidget()->sortColumn() : 0;
57 QVariant lhs = data(sort_col, Qt::UserRole);
58 QVariant rhs = other.data(sort_col, Qt::UserRole);
59
60 if (lhs.isValid() && rhs.isValid()) {
61 if (lhs.metaType().id() == QMetaType::Double || rhs.metaType().id() == QMetaType::Double) {
62 return lhs.toDouble() < rhs.toDouble();
63 }
64
65 return lhs.toLongLong() < rhs.toLongLong();
66 }
67
68 return QTreeWidgetItem::operator<(other);
69}
70
71DisStreamDialog *
72DisStreamDialog::openDisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list)
73{
74 std::lock_guard<std::mutex> lock(mutex_);
75
76 if (!pinstance_) {
77 pinstance_ = new DisStreamDialog(parent, cf, packet_list);
78 }
79
80 return pinstance_;
81}
82
83DisStreamDialog::DisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) :
84 WiresharkDialog(parent, cf),
85 stream_tree_(new QTreeWidget(this)),
86 button_box_(new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this)),
87 filter_button_(nullptr),
88 play_button_(nullptr),
89 stop_button_(nullptr),
90 analyze_button_(nullptr),
91 need_redraw_(false),
92 packet_list_(packet_list)
93#ifdef QT_MULTIMEDIA_LIB1
94 , audio_stream_(new DisAudioStream(this))
95#endif
96{
97 QVBoxLayout *layout = new QVBoxLayout(this);
98 QFormLayout *summary_layout = new QFormLayout;
99
100 setWindowSubtitle(tr("DIS Streams"));
101
102 layout->addLayout(summary_layout);
103
104 stream_tree_->setRootIsDecorated(false);
105 stream_tree_->setAlternatingRowColors(true);
106 stream_tree_->setSortingEnabled(true);
107 stream_tree_->setSelectionMode(QAbstractItemView::SingleSelection);
108 stream_tree_->setUniformRowHeights(true);
109 stream_tree_->setContextMenuPolicy(Qt::ActionsContextMenu);
110 stream_tree_->setColumnCount(dis_col_count);
111 stream_tree_->setHeaderLabels(QStringList()
112 << tr("Start")
113 << tr("End")
114 << tr("Src Address")
115 << tr("Src Port")
116 << tr("Dst Address")
117 << tr("Dst Port")
118 << tr("Radio")
119 << tr("Entity")
120 << tr("Signal")
121 << tr("Tx")
122 << tr("Lost")
123 << tr("Max Delta (ms)")
124 << tr("Mean Jitter (ms)")
125 << tr("Max Jitter (ms)")
126 << tr("Pb"));
127 stream_tree_->header()->setSortIndicator(dis_col_start_time, Qt::AscendingOrder);
128 stream_tree_->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
129
130 layout->addWidget(stream_tree_);
131
132 filter_button_ = button_box_->addButton(tr("Prepare Filter"), QDialogButtonBox::ActionRole);
133 play_button_ = button_box_->addButton(tr("Play"), QDialogButtonBox::ActionRole);
134 stop_button_ = button_box_->addButton(tr("Stop"), QDialogButtonBox::ActionRole);
135 analyze_button_ = button_box_->addButton(tr("Analyze"), QDialogButtonBox::ActionRole);
136 layout->addWidget(button_box_);
137
138 connect(button_box_, &QDialogButtonBox::rejected, this, &DisStreamDialog::reject);
139 connect(filter_button_, &QPushButton::clicked, this, &DisStreamDialog::onPrepareFilter);
140 connect(analyze_button_, &QPushButton::clicked, this, &DisStreamDialog::onAnalyzeStream);
141#ifdef QT_MULTIMEDIA_LIB1
142 connect(play_button_, &QPushButton::clicked, this, &DisStreamDialog::onPlayStream);
143 connect(stop_button_, &QPushButton::clicked, this, &DisStreamDialog::onStopStream);
144 connect(audio_stream_, &DisAudioStream::playbackStateChanged,
145 this, &DisStreamDialog::onPlaybackStateChanged);
146#endif
147 connect(stream_tree_, &QTreeWidget::itemSelectionChanged, this, &DisStreamDialog::onStreamSelectionChanged);
148 connect(stream_tree_, &QTreeWidget::itemDoubleClicked, this, &DisStreamDialog::onStreamItemDoubleClicked);
149 connect(&cap_file_, &CaptureFile::captureEvent, this, &DisStreamDialog::onCaptureEvent);
150
151 if (packet_list_) {
152 connect(this, SIGNAL(goToPacket(int))qFlagLocation("2" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp"
":" "152")
, packet_list_, SLOT(goToPacket(int))qFlagLocation("1" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp"
":" "152")
);
153 }
154 connect(this, SIGNAL(updateFilter(QString, bool))qFlagLocation("2" "updateFilter(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp"
":" "154")
, &parent, SLOT(filterPackets(QString, bool))qFlagLocation("1" "filterPackets(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp"
":" "154")
);
155
156 memset(&tapinfo_, 0, sizeof(tapinfo_));
157 tapinfo_.mode = DISSTREAM_TAP_ANALYSE;
158 tapinfo_.tap_reset = tapReset;
159 tapinfo_.tap_draw = tapDraw;
160
161 register_tap_listener_disstream(&tapinfo_, NULL__null, NULL__null);
162
163 if (cap_file_.isValid()) {
164 cap_file_.delayedRetapPackets();
165 }
166
167 loadGeometry(parent.width() * 4 / 5, parent.height() * 2 / 3);
168 updateWidgets();
169}
170
171DisStreamDialog::~DisStreamDialog()
172{
173 std::lock_guard<std::mutex> lock(mutex_);
174
175#ifdef QT_MULTIMEDIA_LIB1
176 audio_stream_->stopPlayback();
177#endif
178
179 disstream_reset(&tapinfo_);
180 remove_tap_listener_disstream(&tapinfo_);
181 pinstance_ = nullptr;
182}
183
184void
185DisStreamDialog::captureFileClosing()
186{
187#ifdef QT_MULTIMEDIA_LIB1
188 audio_stream_->stopPlayback();
189#endif
190 remove_tap_listener_disstream(&tapinfo_);
191 disstream_reset(&tapinfo_);
192}
193
194void
195DisStreamDialog::captureFileClosed()
196{
197#ifdef QT_MULTIMEDIA_LIB1
198 audio_stream_->stopPlayback();
199#endif
200 stream_tree_->clear();
201}
202
203void
204DisStreamDialog::tapReset(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
205{
206 if (!pinstance_) {
207 return;
208 }
209
210 pinstance_->need_redraw_ = true;
211}
212
213void
214DisStreamDialog::tapDraw(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
215{
216 if (!pinstance_) {
1
Assuming 'pinstance_' is non-null
2
Taking false branch
217 return;
218 }
219
220 pinstance_->need_redraw_ = true;
221 QMetaObject::invokeMethod(pinstance_, [=]() { pinstance_->updateStreams(); }, Qt::QueuedConnection);
3
Calling 'QMetaObject::invokeMethod'
222}
223
224disstream_info_t *
225DisStreamDialog::selectedStream() const
226{
227 QTreeWidgetItem *current = stream_tree_->currentItem();
228 if (!current) {
229 return nullptr;
230 }
231
232 quintptr ptr = current->data(0, disstream_ptr_role).value<quintptr>();
233 return reinterpret_cast<disstream_info_t *>(ptr);
234}
235
236void
237DisStreamDialog::updateStreams()
238{
239 GList *list;
240 disstream_info_t *previous = selectedStream();
241 QTreeWidgetItem *item_to_select = nullptr;
242
243 if (!need_redraw_ || fileClosed()) {
244 updateWidgets();
245 return;
246 }
247
248 QSignalBlocker signal_blocker(stream_tree_);
249
250 stream_tree_->setSortingEnabled(false);
251 stream_tree_->clear();
252
253 list = g_list_first(tapinfo_.strinfo_list);
254 while (list) {
255 disstream_info_t *stream_info = (disstream_info_t *)list->data;
256 DisStreamTreeWidgetItem *item;
257 char *src_addr;
258 char *dst_addr;
259
260 item = new DisStreamTreeWidgetItem(stream_tree_);
261 item->setData(0, disstream_ptr_role, QVariant::fromValue((quintptr)stream_info));
262 if ((previous && previous == stream_info) || (!previous && !item_to_select)) {
263 item_to_select = item;
264 }
265
266 src_addr = address_to_display(NULL__null, &stream_info->id.src_addr);
267 dst_addr = address_to_display(NULL__null, &stream_info->id.dst_addr);
268
269 item->setText(dis_col_start_time, QString::number(nstime_to_sec(&stream_info->start_rel_time), 'f', 6));
270 item->setData(dis_col_start_time, Qt::UserRole, nstime_to_sec(&stream_info->start_rel_time));
271
272 item->setText(dis_col_end_time, QString::number(nstime_to_sec(&stream_info->stop_rel_time), 'f', 6));
273 item->setData(dis_col_end_time, Qt::UserRole, nstime_to_sec(&stream_info->stop_rel_time));
274
275 item->setText(dis_col_src_addr, src_addr);
276 item->setText(dis_col_src_port, QString::number(stream_info->id.src_port));
277 item->setData(dis_col_src_port, Qt::UserRole, (int)stream_info->id.src_port);
278
279 item->setText(dis_col_dst_addr, dst_addr);
280 item->setText(dis_col_dst_port, QString::number(stream_info->id.dst_port));
281 item->setData(dis_col_dst_port, Qt::UserRole, (int)stream_info->id.dst_port);
282
283 item->setText(dis_col_radio, QStringLiteral("0x%1")(QString(QtPrivate::qMakeStringPrivate(u"" "0x%1"))).arg(stream_info->id.radio_id, 4, 16, QChar('0')));
284 item->setData(dis_col_radio, Qt::UserRole, (int)stream_info->id.radio_id);
285
286 item->setText(dis_col_entity, QStringLiteral("%1/%2/%3")(QString(QtPrivate::qMakeStringPrivate(u"" "%1/%2/%3")))
287 .arg(stream_info->id.entity_id_site)
288 .arg(stream_info->id.entity_id_appl)
289 .arg(stream_info->id.entity_id_entity));
290
291 item->setText(dis_col_signal_pkts, QString::number(stream_info->signal_packet_count));
292 item->setData(dis_col_signal_pkts, Qt::UserRole, (int)stream_info->signal_packet_count);
293
294 item->setText(dis_col_tx_pkts, QString::number(stream_info->transmitter_packet_count));
295 item->setData(dis_col_tx_pkts, Qt::UserRole, (int)stream_info->transmitter_packet_count);
296
297 item->setText(dis_col_lost, QString::number(stream_info->estimated_lost_packets));
298 item->setData(dis_col_lost, Qt::UserRole, (int)stream_info->estimated_lost_packets);
299
300 item->setText(dis_col_max_delta, QString::number(stream_info->max_delta_ms, 'f', 3));
301 item->setData(dis_col_max_delta, Qt::UserRole, stream_info->max_delta_ms);
302
303 item->setText(dis_col_mean_jitter, QString::number(stream_info->mean_jitter_ms, 'f', 3));
304 item->setData(dis_col_mean_jitter, Qt::UserRole, stream_info->mean_jitter_ms);
305
306 item->setText(dis_col_max_jitter, QString::number(stream_info->max_jitter_ms, 'f', 3));
307 item->setData(dis_col_max_jitter, Qt::UserRole, stream_info->max_jitter_ms);
308
309 item->setText(dis_col_problem, stream_info->problem ? tr("X") : QString());
310 item->setTextAlignment(dis_col_problem, Qt::AlignCenter);
311
312 wmem_free(NULL__null, src_addr);
313 wmem_free(NULL__null, dst_addr);
314
315 list = g_list_next(list)((list) ? (((GList *)(list))->next) : __null);
316 }
317
318 stream_tree_->setSortingEnabled(true);
319 stream_tree_->sortByColumn(stream_tree_->header()->sortIndicatorSection(),
320 stream_tree_->header()->sortIndicatorOrder());
321 if (item_to_select) {
322 stream_tree_->setCurrentItem(item_to_select);
323 }
324
325 need_redraw_ = false;
326 updateWidgets();
327}
328
329void
330DisStreamDialog::updateWidgets()
331{
332 bool has_capture = cap_file_.isValid() && !fileClosed();
333 disstream_info_t *stream_info = selectedStream();
334 bool has_selection = stream_info != nullptr;
335 bool has_audio_data = has_selection && stream_info->signal_packets && stream_info->signal_packets->len > 0;
336
337 stream_tree_->setEnabled(has_capture);
338 filter_button_->setEnabled(has_capture && has_selection);
339 play_button_->setEnabled(has_capture && has_audio_data);
340 analyze_button_->setEnabled(has_capture && has_selection);
341#ifdef QT_MULTIMEDIA_LIB1
342 stop_button_->setEnabled(audio_stream_->isPlaying());
343#else
344 stop_button_->setEnabled(false);
345#endif
346}
347
348void
349DisStreamDialog::onStreamSelectionChanged()
350{
351#ifdef QT_MULTIMEDIA_LIB1
352 disstream_info_t *stream_info = selectedStream();
353
354 if (audio_stream_->currentStream() != nullptr &&
355 audio_stream_->currentStream() != stream_info &&
356 (audio_stream_->isPlaying() || audio_stream_->isPaused())) {
357 audio_stream_->stopPlayback();
358 }
359#endif
360 updateWidgets();
361}
362
363void
364DisStreamDialog::onStreamItemDoubleClicked(QTreeWidgetItem *item, int column _U___attribute__((unused)))
365{
366 quintptr ptr;
367 disstream_info_t *stream_info;
368
369 if (!item) {
370 return;
371 }
372
373 ptr = item->data(0, disstream_ptr_role).value<quintptr>();
374 stream_info = reinterpret_cast<disstream_info_t *>(ptr);
375 if (stream_info && stream_info->first_packet_num > 0) {
376 emit goToPacket((int)stream_info->first_packet_num);
377 }
378}
379
380void
381DisStreamDialog::onPrepareFilter()
382{
383 disstream_info_t *stream_info = selectedStream();
384 QString filter;
385
386 if (!stream_info) {
387 return;
388 }
389
390 filter = QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && "
"dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "
"dis.entity_id_application==%5 && dis.entity_id_entity==%6"
)))
391 "dis && udp.srcport==%1 && udp.dstport==%2 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && "
"dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "
"dis.entity_id_application==%5 && dis.entity_id_entity==%6"
)))
392 "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && "
"dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "
"dis.entity_id_application==%5 && dis.entity_id_entity==%6"
)))
393 "dis.entity_id_application==%5 && dis.entity_id_entity==%6")(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && "
"dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "
"dis.entity_id_application==%5 && dis.entity_id_entity==%6"
)))
394 .arg(stream_info->id.src_port)
395 .arg(stream_info->id.dst_port)
396 .arg(stream_info->id.radio_id)
397 .arg(stream_info->id.entity_id_site)
398 .arg(stream_info->id.entity_id_appl)
399 .arg(stream_info->id.entity_id_entity);
400
401 emit updateFilter(filter, true);
402}
403
404void
405DisStreamDialog::onAnalyzeStream()
406{
407 disstream_info_t *stream_info = selectedStream();
408 QWidget *parent_widget = qobject_cast<QWidget *>(parent());
409
410 if (!stream_info) {
411 return;
412 }
413
414 if (!parent_widget) {
415 parent_widget = this;
416 }
417
418 DisStreamAnalysisDialog *dialog = DisStreamAnalysisDialog::openDisStreamAnalysisDialog(
419 *parent_widget, cap_file_, packet_list_);
420 dialog->selectStream(stream_info);
421 dialog->show();
422 dialog->raise();
423 dialog->activateWindow();
424}
425
426#ifdef QT_MULTIMEDIA_LIB1
427void
428DisStreamDialog::onPlayStream()
429{
430 disstream_info_t *stream_info = selectedStream();
431 QString error_message;
432
433 if (!audio_stream_->playDisStream(stream_info, error_message)) {
434 QMessageBox::warning(this, tr("DIS Playback"), error_message);
435 return;
436 }
437 updateWidgets();
438}
439
440void
441DisStreamDialog::onStopStream()
442{
443 audio_stream_->stopPlayback();
444 updateWidgets();
445}
446
447void
448DisStreamDialog::onPlaybackStateChanged(QAudio::State state _U___attribute__((unused)))
449{
450 updateWidgets();
451}
452#endif
453
454void
455DisStreamDialog::onCaptureEvent(CaptureEvent e)
456{
457 if (e.captureContext() == CaptureEvent::Retap) {
458 need_redraw_ = true;
459 }
460
461 updateStreams();
462}

/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h

1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2019 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QOBJECTDEFS_H
6#define QOBJECTDEFS_H
7
8#if defined(__OBJC__) && !defined(__cplusplus201703L)
9# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
10#endif
11
12#include <QtCore/qnamespace.h>
13#include <QtCore/qobjectdefs_impl.h>
14#include <QtCore/qtcoreexports.h>
15#include <QtCore/qtmetamacros.h>
16
17QT_BEGIN_NAMESPACE
18
19class QByteArray;
20struct QArrayData;
21
22class QString;
23
24#ifndef QT_NO_META_MACROS
25// macro for onaming members
26#ifdef METHOD
27#undef METHOD
28#endif
29#ifdef SLOT
30#undef SLOT
31#endif
32#ifdef SIGNAL
33#undef SIGNAL
34#endif
35#endif // QT_NO_META_MACROS
36
37Q_CORE_EXPORT__attribute__((visibility("default"))) const char *qFlagLocation(const char *method);
38
39#ifndef QT_NO_META_MACROS
40# define QMETHOD_CODE0 0 // member type codes
41# define QSLOT_CODE1 1
42# define QSIGNAL_CODE2 2
43# define QT_PREFIX_CODE(code, a)"code" "a" QT_STRINGIFY(code)"code" #a
44# define QT_STRINGIFY_METHOD(a)"0" "a" QT_PREFIX_CODE(QMETHOD_CODE, a)"0" "a"
45# define QT_STRINGIFY_SLOT(a)"1" "a" QT_PREFIX_CODE(QSLOT_CODE, a)"1" "a"
46# define QT_STRINGIFY_SIGNAL(a)"2" "a" QT_PREFIX_CODE(QSIGNAL_CODE, a)"2" "a"
47# ifndef QT_NO_DEBUG
48# define QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "48"
"\0" __FILE__"/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" QT_STRINGIFY(__LINE__)"48"
49# ifndef QT_NO_KEYWORDS
50# define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "50")
qFlagLocation(QT_STRINGIFY_METHOD(a)"0" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "50"
)
51# endif
52# define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "52")
qFlagLocation(QT_STRINGIFY_SLOT(a)"1" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "52"
)
53# define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "53")
qFlagLocation(QT_STRINGIFY_SIGNAL(a)"2" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "53"
)
54# else
55# ifndef QT_NO_KEYWORDS
56# define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "56")
QT_STRINGIFY_METHOD(a)"0" "a"
57# endif
58# define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "58")
QT_STRINGIFY_SLOT(a)"1" "a"
59# define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
":" "59")
QT_STRINGIFY_SIGNAL(a)"2" "a"
60# endif
61#endif // QT_NO_META_MACROS
62
63#define Q_ARG(Type, data)QtPrivate::Invoke::argument<Type>("Type", data) QtPrivate::Invoke::argument<Type>(QT_STRINGIFY(Type)"Type", data)
64#define Q_RETURN_ARG(Type, data)QtPrivate::Invoke::returnArgument<Type>("Type", data) QtPrivate::Invoke::returnArgument<Type>(QT_STRINGIFY(Type)"Type", data)
65
66class QObject;
67class QMetaMethod;
68class QMetaEnum;
69class QMetaProperty;
70class QMetaClassInfo;
71
72namespace QtPrivate {
73class QMetaTypeInterface;
74template<typename T> constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType();
75}
76
77struct QMethodRawArguments
78{
79 void **arguments;
80};
81
82#if QT_VERSION((6<<16)|(10<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
83class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericArgument
84{
85public:
86 inline QGenericArgument(const char *aName = nullptr, const void *aData = nullptr)
87 : _data(aData), _name(aName) {}
88 inline void *data() const { return const_cast<void *>(_data); }
89 inline const char *name() const { return _name; }
90
91private:
92 const void *_data;
93 const char *_name;
94};
95
96class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericReturnArgument: public QGenericArgument
97{
98public:
99 inline QGenericReturnArgument(const char *aName = nullptr, void *aData = nullptr)
100 : QGenericArgument(aName, aData)
101 {}
102};
103
104template <class T>
105class QArgument: public QGenericArgument
106{
107public:
108 inline QArgument(const char *aName, const T &aData)
109 : QGenericArgument(aName, static_cast<const void *>(&aData))
110 {}
111};
112template <class T>
113class QArgument<T &>: public QGenericArgument
114{
115public:
116 inline QArgument(const char *aName, T &aData)
117 : QGenericArgument(aName, static_cast<const void *>(&aData))
118 {}
119};
120
121
122template <typename T>
123class QReturnArgument: public QGenericReturnArgument
124{
125public:
126 inline QReturnArgument(const char *aName, T &aData)
127 : QGenericReturnArgument(aName, static_cast<void *>(&aData))
128 {}
129};
130#endif
131
132struct QMetaMethodArgument
133{
134 const QtPrivate::QMetaTypeInterface *metaType;
135 const char *name;
136 const void *data;
137};
138
139struct QMetaMethodReturnArgument
140{
141 const QtPrivate::QMetaTypeInterface *metaType;
142 const char *name;
143 void *data;
144};
145
146template <typename T>
147struct QTemplatedMetaMethodReturnArgument : QMetaMethodReturnArgument
148{
149 using Type = T;
150};
151
152namespace QtPrivate {
153namespace Invoke {
154#if QT_VERSION((6<<16)|(10<<8)|(2)) <= QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
155template <typename... Args>
156using AreOldStyleArgs = std::disjunction<std::is_base_of<QGenericArgument, Args>...>;
157
158template <typename T, typename... Args> using IfNotOldStyleArgs =
159 std::enable_if_t<!AreOldStyleArgs<Args...>::value, T>;
160#else
161template <typename T, typename... Args> using IfNotOldStyleArgs = T;
162#endif
163
164template <typename T> inline QMetaMethodArgument argument(const char *name, const T &t)
165{
166 if constexpr ((std::is_lvalue_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>) ||
167 !std::is_reference_v<T>) {
168 return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
169 } else {
170 return { nullptr, name, std::addressof(t) };
171 }
172}
173
174template <typename T>
175inline QTemplatedMetaMethodReturnArgument<T> returnArgument(const char *name, T &t)
176{
177 return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
178}
179
180template <typename T> inline const char *typenameHelper(const T &)
181{
182 return nullptr;
183}
184template <typename T> inline const void *dataHelper(const T &t)
185{
186 return std::addressof(t);
187}
188template <typename T> inline const QMetaTypeInterface *metaTypeHelper(const T &)
189{
190 return qMetaTypeInterfaceForType<T>();
191}
192
193inline const char *typenameHelper(QMetaMethodArgument a)
194{ return a.name; }
195inline const void *dataHelper(QMetaMethodArgument a)
196{ return a.data; }
197inline const QMetaTypeInterface *metaTypeHelper(QMetaMethodArgument a)
198{ return a.metaType; }
199
200inline const char *typenameHelper(const char *) = delete;
201template <typename T> inline const void *dataHelper(const char *) = delete;
202inline const QMetaTypeInterface *metaTypeHelper(const char *) = delete;
203inline const char *typenameHelper(const char16_t *) = delete;
204template <typename T> inline const void *dataHelper(const char16_t *) = delete;
205inline const QMetaTypeInterface *metaTypeHelper(const char16_t *) = delete;
206
207} // namespace QtPrivate::Invoke
208
209template <typename... Args> inline auto invokeMethodHelper(QMetaMethodReturnArgument r, const Args &... arguments)
210{
211 std::array params = { const_cast<const void *>(r.data), Invoke::dataHelper(arguments)... };
212 std::array names = { r.name, Invoke::typenameHelper(arguments)... };
213 std::array types = { r.metaType, Invoke::metaTypeHelper(arguments)... };
214 static_assert(params.size() == types.size());
215 static_assert(params.size() == names.size());
216
217 struct R {
218 decltype(params) parameters;
219 decltype(names) typeNames;
220 decltype(types) metaTypes;
221 constexpr qsizetype parameterCount() const { return qsizetype(parameters.size()); }
222 };
223 return R { params, names, types };
224}
225} // namespace QtPrivate
226
227template <typename T> void qReturnArg(const T &&) = delete;
228template <typename T> inline QTemplatedMetaMethodReturnArgument<T> qReturnArg(T &data)
229{
230 return QtPrivate::Invoke::returnArgument(nullptr, data);
231}
232
233struct Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject
234{
235 class Connection;
236 const char *className() const;
237 const QMetaObject *superClass() const;
238
239 bool inherits(const QMetaObject *metaObject) const noexcept;
240 QObject *cast(QObject *obj) const
241 { return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); }
242 const QObject *cast(const QObject *obj) const;
243
244#if !defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
245 QString tr(const char *s, const char *c, int n = -1) const;
246#endif // QT_NO_TRANSLATION
247
248 QMetaType metaType() const;
249
250 int methodOffset() const;
251 int enumeratorOffset() const;
252 int propertyOffset() const;
253 int classInfoOffset() const;
254
255 int constructorCount() const;
256 int methodCount() const;
257 int enumeratorCount() const;
258 int propertyCount() const;
259 int classInfoCount() const;
260
261 int indexOfConstructor(const char *constructor) const;
262 int indexOfMethod(const char *method) const;
263 int indexOfSignal(const char *signal) const;
264 int indexOfSlot(const char *slot) const;
265 int indexOfEnumerator(const char *name) const;
266
267 int indexOfProperty(const char *name) const;
268 int indexOfClassInfo(const char *name) const;
269
270 QMetaMethod constructor(int index) const;
271 QMetaMethod method(int index) const;
272 QMetaEnum enumerator(int index) const;
273 QMetaProperty property(int index) const;
274 QMetaClassInfo classInfo(int index) const;
275 QMetaProperty userProperty() const;
276
277 static bool checkConnectArgs(const char *signal, const char *method);
278 static bool checkConnectArgs(const QMetaMethod &signal,
279 const QMetaMethod &method);
280 static QByteArray normalizedSignature(const char *method);
281 static QByteArray normalizedType(const char *type);
282
283 // internal index-based connect
284 static Connection connect(const QObject *sender, int signal_index,
285 const QObject *receiver, int method_index,
286 int type = 0, int *types = nullptr);
287 // internal index-based disconnect
288 static bool disconnect(const QObject *sender, int signal_index,
289 const QObject *receiver, int method_index);
290 static bool disconnectOne(const QObject *sender, int signal_index,
291 const QObject *receiver, int method_index);
292 // internal slot-name based connect
293 static void connectSlotsByName(QObject *o);
294
295#ifdef Q_QDOC
296 template<typename PointerToMemberFunction>
297 static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
298 template<typename Functor>
299 static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
300#else
301 template <typename Func>
302 static inline Connection
303 connect(const QObject *sender, const QMetaMethod &signal,
304 const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
305 Qt::ConnectionType type = Qt::AutoConnection);
306#endif // Q_QDOC
307
308 // internal index-based signal activation
309 static void activate(QObject *sender, int signal_index, void **argv);
310 static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
311 static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
312 template <typename Ret, typename... Args> static inline void
313 activate(QObject *sender, const QMetaObject *mo, int local_signal_index, Ret *ret, const Args &... args)
314 {
315 void *_a[] = {
316 const_cast<void *>(reinterpret_cast<const volatile void *>(ret)),
317 const_cast<void *>(reinterpret_cast<const volatile void *>(std::addressof(args)))...
318 };
319 activate(sender, mo, local_signal_index, _a);
320 }
321
322#if QT_VERSION((6<<16)|(10<<8)|(2)) <= QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
323 static bool invokeMethod(QObject *obj, const char *member,
324 Qt::ConnectionType,
325 QGenericReturnArgument ret,
326 QGenericArgument val0 = QGenericArgument(nullptr),
327 QGenericArgument val1 = QGenericArgument(),
328 QGenericArgument val2 = QGenericArgument(),
329 QGenericArgument val3 = QGenericArgument(),
330 QGenericArgument val4 = QGenericArgument(),
331 QGenericArgument val5 = QGenericArgument(),
332 QGenericArgument val6 = QGenericArgument(),
333 QGenericArgument val7 = QGenericArgument(),
334 QGenericArgument val8 = QGenericArgument(),
335 QGenericArgument val9 = QGenericArgument());
336
337 static inline bool invokeMethod(QObject *obj, const char *member,
338 QGenericReturnArgument ret,
339 QGenericArgument val0 = QGenericArgument(nullptr),
340 QGenericArgument val1 = QGenericArgument(),
341 QGenericArgument val2 = QGenericArgument(),
342 QGenericArgument val3 = QGenericArgument(),
343 QGenericArgument val4 = QGenericArgument(),
344 QGenericArgument val5 = QGenericArgument(),
345 QGenericArgument val6 = QGenericArgument(),
346 QGenericArgument val7 = QGenericArgument(),
347 QGenericArgument val8 = QGenericArgument(),
348 QGenericArgument val9 = QGenericArgument())
349 {
350 return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3,
351 val4, val5, val6, val7, val8, val9);
352 }
353
354 static inline bool invokeMethod(QObject *obj, const char *member,
355 Qt::ConnectionType type,
356 QGenericArgument val0,
357 QGenericArgument val1 = QGenericArgument(),
358 QGenericArgument val2 = QGenericArgument(),
359 QGenericArgument val3 = QGenericArgument(),
360 QGenericArgument val4 = QGenericArgument(),
361 QGenericArgument val5 = QGenericArgument(),
362 QGenericArgument val6 = QGenericArgument(),
363 QGenericArgument val7 = QGenericArgument(),
364 QGenericArgument val8 = QGenericArgument(),
365 QGenericArgument val9 = QGenericArgument())
366 {
367 return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
368 val3, val4, val5, val6, val7, val8, val9);
369 }
370
371 static inline bool invokeMethod(QObject *obj, const char *member,
372 QGenericArgument val0,
373 QGenericArgument val1 = QGenericArgument(),
374 QGenericArgument val2 = QGenericArgument(),
375 QGenericArgument val3 = QGenericArgument(),
376 QGenericArgument val4 = QGenericArgument(),
377 QGenericArgument val5 = QGenericArgument(),
378 QGenericArgument val6 = QGenericArgument(),
379 QGenericArgument val7 = QGenericArgument(),
380 QGenericArgument val8 = QGenericArgument(),
381 QGenericArgument val9 = QGenericArgument())
382 {
383 return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
384 val1, val2, val3, val4, val5, val6, val7, val8, val9);
385 }
386#endif // Qt < 7.0
387
388 template <typename ReturnArg, typename... Args> static
389#ifdef Q_QDOC
390 bool
391#else
392 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
393#endif
394 invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
395 QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments)
396 {
397 auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
398 return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
399 h.typeNames.data(), h.metaTypes.data());
400 }
401
402 template <typename... Args> static
403#ifdef Q_QDOC
404 bool
405#else
406 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
407#endif
408 invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
409 {
410 QTemplatedMetaMethodReturnArgument<void> r = {};
411 return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
412 }
413
414 template <typename ReturnArg, typename... Args> static
415#ifdef Q_QDOC
416 bool
417#else
418 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
419#endif
420 invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
421 Args &&... arguments)
422 {
423 return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
424 }
425
426 template <typename... Args> static
427#ifdef Q_QDOC
428 bool
429#else
430 QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
431#endif
432 invokeMethod(QObject *obj, const char *member, Args &&... arguments)
433 {
434 QTemplatedMetaMethodReturnArgument<void> r = {};
435 return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
436 }
437
438#ifdef Q_QDOC
439 template<typename Functor, typename FunctorReturnType>
440 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
441 template<typename Functor, typename FunctorReturnType>
442 static bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret);
443
444 template<typename Functor, typename FunctorReturnType, typename... Args>
445 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
446 template<typename Functor, typename FunctorReturnType, typename... Args>
447 static bool invokeMethod(QObject *context, Functor &&function, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
448 template<typename Functor, typename... Args>
449 static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, Args &&...arguments);
450 template<typename Functor, typename... Args>
451 static bool invokeMethod(QObject *context, Functor &&function, Args &&...arguments);
452#else
453 template <typename Func>
454 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
455 QtPrivate::Invoke::AreOldStyleArgs<Func>>,
456 bool>
457 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
458 Func &&function, Qt::ConnectionType type,
459 typename QtPrivate::Callable<Func>::ReturnType *ret)
460 {
461 using R = typename QtPrivate::Callable<Func>::ReturnType;
462 const auto getReturnArg = [ret]() -> QTemplatedMetaMethodReturnArgument<R> {
463 if constexpr (std::is_void_v<R>)
464 return {};
465 else
466 return ret ? qReturnArg(*ret) : QTemplatedMetaMethodReturnArgument<R>{};
467 };
468 return invokeMethod(object, std::forward<Func>(function), type, getReturnArg());
469 }
470 template <typename Func>
471 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
472 QtPrivate::Invoke::AreOldStyleArgs<Func>>,
473 bool>
474 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
475 Func &&function, typename QtPrivate::Callable<Func>::ReturnType *ret)
476 {
477 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret);
478 }
479
480 template <typename Func, typename... Args>
481 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
482 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
483 bool>
484 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
485 Func &&function, Qt::ConnectionType type,
486 QTemplatedMetaMethodReturnArgument<
487 typename QtPrivate::Callable<Func, Args...>::ReturnType>
488 ret,
489 Args &&...args)
490 {
491 return invokeMethodCallableHelper(object, std::forward<Func>(function), type, ret,
5
Calling 'QMetaObject::invokeMethodCallableHelper'
492 std::forward<Args>(args)...);
493 }
494
495 template <typename Func, typename... Args>
496 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
497 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
498 bool>
499 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
500 Func &&function, Qt::ConnectionType type, Args &&...args)
501 {
502 using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
503 QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
504 nullptr };
505 return invokeMethod(object, std::forward<Func>(function), type, r,
4
Calling 'QMetaObject::invokeMethod'
506 std::forward<Args>(args)...);
507 }
508
509 template <typename Func, typename... Args>
510 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
511 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
512 bool>
513 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
514 Func &&function,
515 QTemplatedMetaMethodReturnArgument<
516 typename QtPrivate::Callable<Func, Args...>::ReturnType>
517 ret,
518 Args &&...args)
519 {
520 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret,
521 std::forward<Args>(args)...);
522 }
523
524 template <typename Func, typename... Args>
525 static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
526 QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
527 bool>
528 invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
529 Func &&function, Args &&...args)
530 {
531 using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
532 QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
533 nullptr };
534 return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, r,
535 std::forward<Args>(args)...);
536 }
537
538#endif
539
540#if QT_VERSION((6<<16)|(10<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
541 QObject *newInstance(QGenericArgument val0,
542 QGenericArgument val1 = QGenericArgument(),
543 QGenericArgument val2 = QGenericArgument(),
544 QGenericArgument val3 = QGenericArgument(),
545 QGenericArgument val4 = QGenericArgument(),
546 QGenericArgument val5 = QGenericArgument(),
547 QGenericArgument val6 = QGenericArgument(),
548 QGenericArgument val7 = QGenericArgument(),
549 QGenericArgument val8 = QGenericArgument(),
550 QGenericArgument val9 = QGenericArgument()) const;
551#endif
552
553 template <typename... Args>
554#ifdef Q_QDOC
555 QObject *
556#else
557 QtPrivate::Invoke::IfNotOldStyleArgs<QObject *, Args...>
558#endif
559 newInstance(Args &&... arguments) const
560 {
561 auto h = QtPrivate::invokeMethodHelper(QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
562 return newInstanceImpl(this, h.parameterCount(), h.parameters.data(),
563 h.typeNames.data(), h.metaTypes.data());
564 }
565
566 enum Call {
567 InvokeMetaMethod,
568 ReadProperty,
569 WriteProperty,
570 ResetProperty,
571 CreateInstance,
572 IndexOfMethod,
573 RegisterPropertyMetaType,
574 RegisterMethodArgumentMetaType,
575 BindableProperty,
576 CustomCall,
577 ConstructInPlace,
578 };
579
580 int static_metacall(Call, int, void **) const;
581 static int metacall(QObject *, Call, int, void **);
582
583 template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject()
584 {
585 return &MO;
586 }
587
588 struct SuperData {
589 using Getter = const QMetaObject *(*)();
590 const QMetaObject *direct;
591 SuperData() = default;
592 constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
593 constexpr SuperData(const QMetaObject *mo) : direct(mo) {}
594
595 constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
596
597#ifdef QT_NO_DATA_RELOCATION
598 Getter indirect = nullptr;
599 constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
600 constexpr operator const QMetaObject *() const
601 { return indirect ? indirect() : direct; }
602 template <const QMetaObject &MO> static constexpr SuperData link()
603 { return SuperData(QMetaObject::staticMetaObject<MO>); }
604#else
605 constexpr SuperData(Getter g) : direct(g()) {}
606 constexpr operator const QMetaObject *() const
607 { return direct; }
608 template <const QMetaObject &MO> static constexpr SuperData link()
609 { return SuperData(QMetaObject::staticMetaObject<MO>()); }
610#endif
611 };
612
613 struct Data { // private data
614 SuperData superdata;
615 const uint *stringdata;
616 const uint *data;
617 typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
618 StaticMetacallFunction static_metacall;
619 const SuperData *relatedMetaObjects;
620 const QtPrivate::QMetaTypeInterface *const *metaTypes;
621 void *extradata; //reserved for future use
622 } d;
623
624private:
625 // Just need to have this here with a separate name so the other inline
626 // functions can call this without any ambiguity
627 template <typename Func, typename... Args>
628 static bool
629 invokeMethodCallableHelper(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
630 Func &&function, Qt::ConnectionType type, const QMetaMethodReturnArgument &ret,
631 Args &&...args)
632 {
633 using Callable = QtPrivate::Callable<Func, Args...>;
634 using ExpectedArguments = typename Callable::Arguments;
635 static_assert(sizeof...(Args) <= ExpectedArguments::size, "Too many arguments");
636 using ActualArguments = QtPrivate::List<Args...>;
637 static_assert(QtPrivate::CheckCompatibleArguments<ActualArguments,
638 ExpectedArguments>::value,
639 "Incompatible arguments");
640
641 auto h = QtPrivate::invokeMethodHelper(ret, std::forward<Args>(args)...);
642
643 // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
644 auto callable = new QtPrivate::QCallableObject<std::decay_t<Func>, ActualArguments,
6
Memory is allocated
645 typename Callable::ReturnType>(std::forward<Func>(function));
646 return invokeMethodImpl(object, callable, type, h.parameterCount(), h.parameters.data(),
7
Potential leak of memory pointed to by 'callable'
647 h.typeNames.data(), h.metaTypes.data());
648 // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
649 }
650
651 static bool invokeMethodImpl(QObject *object, const char *member, Qt::ConnectionType type,
652 qsizetype parameterCount, const void *const *parameters, const char *const *names,
653 const QtPrivate::QMetaTypeInterface * const *metaTypes);
654 static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj,
655 Qt::ConnectionType type, qsizetype parameterCount,
656 const void *const *params, const char *const *names,
657 const QtPrivate::QMetaTypeInterface *const *metaTypes);
658#if QT_CORE_REMOVED_SINCE(6, 7)0
659 static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret);
660#endif
661 static QObject *newInstanceImpl(const QMetaObject *mobj, qsizetype parameterCount,
662 const void **parameters, const char **typeNames,
663 const QtPrivate::QMetaTypeInterface **metaTypes);
664
665 static QMetaObject::Connection connectImpl(const QObject *sender, const QMetaMethod& signal,
666 const QObject *receiver, void **slotPtr,
667 QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type);
668
669 friend class QTimer;
670 friend class QChronoTimer;
671};
672
673class Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject::Connection {
674 void *d_ptr; //QObjectPrivate::Connection*
675 explicit Connection(void *data) : d_ptr(data) { }
676 friend class QObject;
677 friend class QObjectPrivate;
678 friend struct QMetaObject;
679 bool isConnected_helper() const;
680public:
681 ~Connection();
682 Connection();
683 Connection(const Connection &other);
684 Connection &operator=(const Connection &other);
685#ifdef Q_QDOC
686 operator bool() const;
687#else
688 // still using the restricted bool trick here, in order to support
689 // code using copy-init (e.g. `bool ok = connect(...)`)
690 typedef void *Connection::*RestrictedBool;
691 operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
692#endif
693
694 Connection(Connection &&other) noexcept : d_ptr(std::exchange(other.d_ptr, nullptr)) {}
695 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)Connection &operator=(Connection &&other) noexcept
{ swap(other); return *this; }
696 void swap(Connection &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); }
697};
698
699template <typename Func>
700QMetaObject::Connection
701 QMetaObject::connect(const QObject *sender, const QMetaMethod &signal,
702 const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
703 Qt::ConnectionType type)
704{
705 using Slot = std::decay_t<Func>;
706 using FunctionSlotType = QtPrivate::FunctionPointer<Slot>;
707 void **pSlot = nullptr;
708 QtPrivate::QSlotObjectBase *slotObject;
709 if constexpr (FunctionSlotType::ArgumentCount != -1) {
710 slotObject = new QtPrivate::QCallableObject<Slot, typename FunctionSlotType::Arguments, typename FunctionSlotType::ReturnType>(std::forward<Func>(slot));
711 if constexpr (FunctionSlotType::IsPointerToMemberFunction) {
712 pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
713 } else {
714 Q_ASSERT_X((type & Qt::UniqueConnection) == 0, "",(((type & Qt::UniqueConnection) == 0) ? static_cast<void
>(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to "
"a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
, 716))
715 "QObject::connect: Unique connection requires the slot to be a pointer to "(((type & Qt::UniqueConnection) == 0) ? static_cast<void
>(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to "
"a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
, 716))
716 "a member function of a QObject subclass.")(((type & Qt::UniqueConnection) == 0) ? static_cast<void
>(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to "
"a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h"
, 716))
;
717 }
718 } else {
719 using FunctorSlotType = QtPrivate::FunctionPointer<decltype(&Slot::operator())>;
720 slotObject = new QtPrivate::QCallableObject<Slot, typename FunctorSlotType::Arguments, typename FunctorSlotType::ReturnType>(std::forward<Func>(slot));
721 }
722 return QMetaObject::connectImpl(sender, signal, context, pSlot, slotObject, type);
723}
724
725inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
726{
727 lhs.swap(rhs);
728}
729
730inline const QMetaObject *QMetaObject::superClass() const
731{ return d.superdata; }
732
733namespace QtPrivate {
734 // Trait that tells if a QObject has a Q_OBJECT macro
735 template <typename Object> struct HasQ_OBJECT_Macro {
736 template <typename T>
737 static char test(int (T::*)(QMetaObject::Call, int, void **));
738 static int test(int (Object::*)(QMetaObject::Call, int, void **));
739 enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
740 };
741
742 template <class TgtType, class SrcType>
743 inline TgtType qobject_cast_helper(SrcType *object)
744 {
745 using ObjType = std::remove_cv_t<std::remove_pointer_t<TgtType>> ;
746 static_assert(std::is_pointer_v<TgtType>,
747 "qobject_cast requires to cast towards a pointer type");
748 static_assert(HasQ_OBJECT_Macro<ObjType>::Value,
749 "qobject_cast requires the type to have a Q_OBJECT macro");
750
751 if constexpr (std::is_final_v<ObjType>) {
752 if (object && object->metaObject() == &ObjType::staticMetaObject)
753 return static_cast<TgtType>(object);
754 return nullptr;
755 } else {
756 return static_cast<TgtType>(ObjType::staticMetaObject.cast(object));
757 }
758 }
759}
760
761QT_END_NAMESPACE
762
763#endif // QOBJECTDEFS_H