1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QSOCKETNOTIFIER_H
41 #define QSOCKETNOTIFIER_H
42 
43 #include <QtCore/qobject.h>
44 
45 QT_BEGIN_NAMESPACE
46 
47 class QSocketDescriptor;
48 class QSocketNotifierPrivate;
49 class Q_CORE_EXPORT QSocketNotifier : public QObject
50 {
51     Q_OBJECT
52     Q_DECLARE_PRIVATE(QSocketNotifier)
53 
54 public:
55     enum Type { Read, Write, Exception };
56 
57     QSocketNotifier(qintptr socket, Type, QObject *parent = nullptr);
58     ~QSocketNotifier();
59 
60     qintptr socket() const;
61     Type type() const;
62 
63     bool isEnabled() const;
64 
65 public Q_SLOTS:
66     void setEnabled(bool);
67 
68 Q_SIGNALS:
69 #if defined(Q_MOC_RUN)
70     // Add default arguments during Q_MOC_RUN which makes moc generate "signals" which takes less
71     // parameters, but we won't actually allow emitting without all 3. This lets users use the
72     // string-based connect without specifying QSocketNotifier::Type as one of the parameters.
73     void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent = Read,
74                    QPrivateSignal = {});
75 #else
76     void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal);
77 #endif
78 
79     // ### Qt7: consider removing it.
80     // The old signal is compiled internally, but hidden outside of this class.
81     // This means the PMF-based connect(..) will automatically, on recompile, pick up the new
82     // version while the old-style connect(..) can query the metaobject system for this version.
83 #if defined(Q_MOC_RUN) || defined(BUILDING_QSOCKETNOTIFIER) || defined(Q_QDOC)
84     void activated(int socket, QPrivateSignal);
85 #endif
86 
87 protected:
88     bool event(QEvent *) override;
89 
90 private:
91     Q_DISABLE_COPY(QSocketNotifier)
92 };
93 
94 class QSocketDescriptor
95 {
96 public:
97 #if defined(Q_OS_WIN) || defined(Q_QDOC)
98     using DescriptorType = Qt::HANDLE;
99 #define Q_DECL_CONSTEXPR_NOT_WIN
100 #else
101     using DescriptorType = int;
102 #define Q_DECL_CONSTEXPR_NOT_WIN Q_DECL_CONSTEXPR
103 #endif
104 
105     /* implicit */ Q_DECL_CONSTEXPR_NOT_WIN
sockfd(descriptor)106     QSocketDescriptor(DescriptorType descriptor = DescriptorType(-1)) noexcept : sockfd(descriptor)
107     {
108     }
109 
110 #if defined(Q_OS_WIN) || defined(Q_QDOC)
QSocketDescriptor(qintptr desc)111     /* implicit */ QSocketDescriptor(qintptr desc) noexcept : sockfd(DescriptorType(desc)) {}
qintptr()112     operator qintptr() const noexcept { return qintptr(sockfd); }
winHandle()113     Q_DECL_CONSTEXPR Qt::HANDLE winHandle() const noexcept { return sockfd; }
114 #endif
DescriptorType()115     Q_DECL_CONSTEXPR operator DescriptorType() const noexcept { return sockfd; }
116 
isValid()117     Q_DECL_CONSTEXPR_NOT_WIN bool isValid() const noexcept { return *this != QSocketDescriptor(); }
118 
119     friend Q_DECL_CONSTEXPR_NOT_WIN bool operator==(QSocketDescriptor lhs,
120                                                     QSocketDescriptor rhs) noexcept
121     {
122         return lhs.sockfd == rhs.sockfd;
123     }
124     friend Q_DECL_CONSTEXPR_NOT_WIN bool operator!=(QSocketDescriptor lhs,
125                                                     QSocketDescriptor rhs) noexcept
126     {
127         return lhs.sockfd != rhs.sockfd;
128     }
129 
130 #undef Q_DECL_CONSTEXPR_NOT_WIN
131 
132 private:
133     DescriptorType sockfd;
134 };
135 
136 QT_END_NAMESPACE
137 Q_DECLARE_METATYPE(QSocketNotifier::Type)
138 Q_DECLARE_METATYPE(QSocketDescriptor)
139 
140 #endif // QSOCKETNOTIFIER_H
141