Warning, file /frameworks/kwindowsystem/autotests/nettesthelper.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #ifndef NETTESTHELPER_H 0007 #define NETTESTHELPER_H 0008 0009 #include <QByteArray> 0010 #include <memory> 0011 #include <xcb/xcb.h> 0012 0013 #include "cptr_p.h" 0014 0015 namespace KXUtils 0016 { 0017 0018 /** 0019 * @brief Small helper class to fetch an intern atom through XCB. 0020 * 0021 * This class allows to request an intern atom and delay the retrieval of the reply 0022 * till it is needed. In case the reply is never retrieved the reply gets discarded 0023 * in the dtor. So there is no need to keep track manually about which atoms have been 0024 * retrieved. 0025 * 0026 * This class can be used as a drop-in replacement for everywhere where a xcb_atom_t is 0027 * needed as it implements the cast operator. The first time this operator is invoked it 0028 * will retrieve the reply. If the xcb request failed the value is @c XCB_ATOM_NONE, which 0029 * can be used to check whether the returned value is valid. 0030 * 0031 * This class has two modes of operations: a direct one which performs the request directly 0032 * during construction, and an indirect one which needs an explicit call to {@link fetch}. 0033 * 0034 * @code 0035 * Atom direct(QX11Info::connection(), QByteArrayLiteral("myAtomName")); 0036 * Atom indirect(QByteArrayLiteral("myAtomName")); 0037 * indirect.setConnection(QX11Info::connection()); 0038 * indirect.fetch(); 0039 * 0040 * if (direct == XCB_ATOM_NONE) { 0041 * qWarning() << "Request failed"; 0042 * } 0043 * if (indirect == XCB_ATOM_NONE) { 0044 * qWarning() << "Request failed"; 0045 * } 0046 * @endcode 0047 */ 0048 class Atom 0049 { 0050 public: 0051 explicit Atom(const QByteArray &name) 0052 : m_connection(nullptr) 0053 , m_retrieved(false) 0054 , m_atom(XCB_ATOM_NONE) 0055 , m_name(name) 0056 { 0057 m_cookie.sequence = 0; 0058 } 0059 explicit Atom(xcb_connection_t *c, const QByteArray &name, bool onlyIfExists = false) 0060 : m_connection(c) 0061 , m_retrieved(false) 0062 , m_cookie(xcb_intern_atom_unchecked(m_connection, onlyIfExists, name.length(), name.constData())) 0063 , m_atom(XCB_ATOM_NONE) 0064 , m_name(name) 0065 { 0066 } 0067 Atom() Q_DECL_EQ_DELETE; 0068 Atom(const Atom &) Q_DECL_EQ_DELETE; 0069 0070 ~Atom() 0071 { 0072 if (!m_retrieved && m_cookie.sequence) { 0073 xcb_discard_reply(m_connection, m_cookie.sequence); 0074 } 0075 } 0076 0077 void setConnection(xcb_connection_t *c) 0078 { 0079 m_connection = c; 0080 } 0081 0082 void fetch(bool onlyIfExists = false) 0083 { 0084 if (!m_connection) { 0085 // set connection first! 0086 return; 0087 } 0088 if (m_retrieved || m_cookie.sequence) { 0089 // already fetched, don't fetch again 0090 return; 0091 } 0092 m_cookie = xcb_intern_atom_unchecked(m_connection, onlyIfExists, m_name.length(), m_name.constData()); 0093 } 0094 0095 operator xcb_atom_t() const 0096 { 0097 (const_cast<Atom *>(this))->getReply(); 0098 return m_atom; 0099 } 0100 0101 const QByteArray &name() const 0102 { 0103 return m_name; 0104 } 0105 0106 private: 0107 void getReply() 0108 { 0109 if (m_retrieved || !m_cookie.sequence) { 0110 return; 0111 } 0112 UniqueCPointer<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(m_connection, m_cookie, nullptr)); 0113 if (reply) { 0114 m_atom = reply->atom; 0115 } 0116 m_retrieved = true; 0117 } 0118 xcb_connection_t *m_connection; 0119 bool m_retrieved; 0120 xcb_intern_atom_cookie_t m_cookie; 0121 xcb_atom_t m_atom; 0122 QByteArray m_name; 0123 }; 0124 0125 inline xcb_window_t rootWindow(xcb_connection_t *c, int screen) 0126 { 0127 xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(c)); 0128 for (xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(c)); it.rem; --screen, xcb_screen_next(&it)) { 0129 if (screen == 0) { 0130 return iter.data->root; 0131 } 0132 } 0133 return XCB_WINDOW_NONE; 0134 } 0135 0136 } 0137 0138 #endif