1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QSOCKETNOTIFIER_H |
5 | #define QSOCKETNOTIFIER_H |
6 | |
7 | #include <QtCore/qobject.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | class QSocketDescriptor; |
12 | class QSocketNotifierPrivate; |
13 | class Q_CORE_EXPORT QSocketNotifier : public QObject |
14 | { |
15 | Q_OBJECT |
16 | Q_DECLARE_PRIVATE(QSocketNotifier) |
17 | |
18 | public: |
19 | enum Type { Read, Write, Exception }; |
20 | |
21 | explicit QSocketNotifier(Type, QObject *parent = nullptr); |
22 | QSocketNotifier(qintptr socket, Type, QObject *parent = nullptr); |
23 | ~QSocketNotifier(); |
24 | |
25 | void setSocket(qintptr socket); |
26 | qintptr socket() const; |
27 | Type type() const; |
28 | |
29 | bool isValid() const; |
30 | bool isEnabled() const; |
31 | |
32 | public Q_SLOTS: |
33 | void setEnabled(bool); |
34 | |
35 | Q_SIGNALS: |
36 | #if defined(Q_MOC_RUN) |
37 | // Add default arguments during Q_MOC_RUN which makes moc generate "signals" which takes less |
38 | // parameters, but we won't actually allow emitting without all 3. This lets users use the |
39 | // string-based connect without specifying QSocketNotifier::Type as one of the parameters. |
40 | void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent = Read, |
41 | QPrivateSignal = {}); |
42 | #else |
43 | void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal); |
44 | #endif |
45 | |
46 | // ### Qt7: consider removing it. |
47 | // The old signal is compiled internally, but hidden outside of this class. |
48 | // This means the PMF-based connect(..) will automatically, on recompile, pick up the new |
49 | // version while the old-style connect(..) can query the metaobject system for this version. |
50 | #if defined(Q_MOC_RUN) || defined(BUILDING_QSOCKETNOTIFIER) || defined(Q_QDOC) |
51 | QT_MOC_COMPAT void activated(int socket, QPrivateSignal); |
52 | #endif |
53 | |
54 | protected: |
55 | bool event(QEvent *) override; |
56 | |
57 | private: |
58 | Q_DISABLE_COPY(QSocketNotifier) |
59 | }; |
60 | |
61 | class QSocketDescriptor |
62 | { |
63 | public: |
64 | #if defined(Q_OS_WIN) || defined(Q_QDOC) |
65 | using DescriptorType = Qt::HANDLE; |
66 | #define Q_DECL_CONSTEXPR_NOT_WIN |
67 | #else |
68 | using DescriptorType = int; |
69 | #define Q_DECL_CONSTEXPR_NOT_WIN Q_DECL_CONSTEXPR |
70 | #endif |
71 | |
72 | Q_DECL_CONSTEXPR_NOT_WIN Q_IMPLICIT |
73 | QSocketDescriptor(DescriptorType descriptor = DescriptorType(-1)) noexcept : sockfd(descriptor) |
74 | { |
75 | } |
76 | |
77 | #if defined(Q_OS_WIN) || defined(Q_QDOC) |
78 | Q_IMPLICIT QSocketDescriptor(qintptr desc) noexcept : sockfd(DescriptorType(desc)) {} |
79 | Q_IMPLICIT operator qintptr() const noexcept { return qintptr(sockfd); } |
80 | Q_DECL_CONSTEXPR Qt::HANDLE winHandle() const noexcept { return sockfd; } |
81 | #endif |
82 | Q_DECL_CONSTEXPR operator DescriptorType() const noexcept { return sockfd; } |
83 | |
84 | Q_DECL_CONSTEXPR_NOT_WIN bool isValid() const noexcept { return *this != QSocketDescriptor(); } |
85 | |
86 | friend Q_DECL_CONSTEXPR_NOT_WIN bool operator==(QSocketDescriptor lhs, |
87 | QSocketDescriptor rhs) noexcept |
88 | { |
89 | return lhs.sockfd == rhs.sockfd; |
90 | } |
91 | friend Q_DECL_CONSTEXPR_NOT_WIN bool operator!=(QSocketDescriptor lhs, |
92 | QSocketDescriptor rhs) noexcept |
93 | { |
94 | return lhs.sockfd != rhs.sockfd; |
95 | } |
96 | |
97 | #undef Q_DECL_CONSTEXPR_NOT_WIN |
98 | |
99 | private: |
100 | DescriptorType sockfd; |
101 | }; |
102 | |
103 | QT_END_NAMESPACE |
104 | |
105 | QT_DECL_METATYPE_EXTERN_TAGGED(QSocketNotifier::Type, QSocketNotifier_Type, Q_CORE_EXPORT) |
106 | QT_DECL_METATYPE_EXTERN(QSocketDescriptor, Q_CORE_EXPORT) |
107 | |
108 | #endif // QSOCKETNOTIFIER_H |
109 | |