Warning, file /education/ktouch/src/x11_helper.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: 2010 Andriy Rysin (rysin@kde.org) 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 0008 #ifndef X11_HELPER_H_ 0009 #define X11_HELPER_H_ 0010 0011 #include <QKeySequence> 0012 #include <QString> 0013 #include <QStringList> 0014 #include <QWidget> 0015 #include <QX11Info> 0016 #include <QAbstractNativeEventFilter> 0017 0018 #include <xcb/xcb.h> 0019 0020 namespace 0021 { 0022 typedef struct _xcb_xkb_map_notify_event_t { 0023 uint8_t response_type; 0024 uint8_t xkbType; 0025 uint16_t sequence; 0026 xcb_timestamp_t time; 0027 uint8_t deviceID; 0028 uint8_t ptrBtnActions; 0029 uint16_t changed; 0030 xcb_keycode_t minKeyCode; 0031 xcb_keycode_t maxKeyCode; 0032 uint8_t firstType; 0033 uint8_t nTypes; 0034 xcb_keycode_t firstKeySym; 0035 uint8_t nKeySyms; 0036 xcb_keycode_t firstKeyAct; 0037 uint8_t nKeyActs; 0038 xcb_keycode_t firstKeyBehavior; 0039 uint8_t nKeyBehavior; 0040 xcb_keycode_t firstKeyExplicit; 0041 uint8_t nKeyExplicit; 0042 xcb_keycode_t firstModMapKey; 0043 uint8_t nModMapKeys; 0044 xcb_keycode_t firstVModMapKey; 0045 uint8_t nVModMapKeys; 0046 uint16_t virtualMods; 0047 uint8_t pad0[2]; 0048 } _xcb_xkb_map_notify_event_t; 0049 typedef struct _xcb_xkb_state_notify_event_t { 0050 uint8_t response_type; 0051 uint8_t xkbType; 0052 uint16_t sequence; 0053 xcb_timestamp_t time; 0054 uint8_t deviceID; 0055 uint8_t mods; 0056 uint8_t baseMods; 0057 uint8_t latchedMods; 0058 uint8_t lockedMods; 0059 uint8_t group; 0060 int16_t baseGroup; 0061 int16_t latchedGroup; 0062 uint8_t lockedGroup; 0063 uint8_t compatState; 0064 uint8_t grabMods; 0065 uint8_t compatGrabMods; 0066 uint8_t lookupMods; 0067 uint8_t compatLoockupMods; 0068 uint16_t ptrBtnState; 0069 uint16_t changed; 0070 xcb_keycode_t keycode; 0071 uint8_t eventType; 0072 uint8_t requestMajor; 0073 uint8_t requestMinor; 0074 } _xcb_xkb_state_notify_event_t; 0075 typedef union { 0076 /* All XKB events share these fields. */ 0077 struct { 0078 uint8_t response_type; 0079 uint8_t xkbType; 0080 uint16_t sequence; 0081 xcb_timestamp_t time; 0082 uint8_t deviceID; 0083 } any; 0084 _xcb_xkb_map_notify_event_t map_notify; 0085 _xcb_xkb_state_notify_event_t state_notify; 0086 } _xkb_event; 0087 } 0088 0089 class XEventNotifier : public QObject, public QAbstractNativeEventFilter { 0090 Q_OBJECT 0091 0092 Q_SIGNALS: 0093 void layoutChanged(); 0094 void layoutMapChanged(); 0095 0096 public: 0097 XEventNotifier(); 0098 ~XEventNotifier() override {} 0099 0100 virtual void start(); 0101 virtual void stop(); 0102 0103 protected: 0104 // bool x11Event(XEvent * e); 0105 virtual bool processOtherEvents(xcb_generic_event_t* e); 0106 virtual bool processXkbEvents(xcb_generic_event_t* e); 0107 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0108 bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; 0109 #else 0110 bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; 0111 #endif 0112 0113 private: 0114 int registerForXkbEvents(Display* display); 0115 bool isXkbEvent(xcb_generic_event_t* event); 0116 bool isGroupSwitchEvent(_xkb_event* event); 0117 bool isLayoutSwitchEvent(_xkb_event* event); 0118 0119 int xkbOpcode; 0120 }; 0121 0122 struct XkbConfig { 0123 QString keyboardModel; 0124 QStringList layouts; 0125 QStringList variants; 0126 QStringList options; 0127 0128 bool isValid() { return ! layouts.empty(); } 0129 }; 0130 0131 0132 struct LayoutUnit { 0133 static const int MAX_LABEL_LENGTH; 0134 0135 //TODO: move these to private? 0136 QString layout; 0137 QString variant; 0138 0139 LayoutUnit() {} 0140 explicit LayoutUnit(const QString& fullLayoutName); 0141 LayoutUnit(const QString& layout_, const QString& variant_) { 0142 layout = layout_; 0143 variant = variant_; 0144 } 0145 0146 QString getRawDisplayName() const { return displayName; } 0147 QString getDisplayName() const { return !displayName.isEmpty() ? displayName : layout; } 0148 void setDisplayName(const QString& name) { displayName = name; } 0149 0150 void setShortcut(const QKeySequence& shortcut) { this->shortcut = shortcut; } 0151 QKeySequence getShortcut() const { return shortcut; } 0152 0153 bool isEmpty() const { return layout.isEmpty(); } 0154 bool isValid() const { return ! isEmpty(); } 0155 bool operator==(const LayoutUnit& layoutItem) const { 0156 return layout==layoutItem.layout && variant==layoutItem.variant; 0157 } 0158 bool operator!=(const LayoutUnit& layoutItem) const { 0159 return ! (*this == layoutItem); 0160 } 0161 QString toString() const; 0162 0163 private: 0164 QString displayName; 0165 QKeySequence shortcut; 0166 }; 0167 0168 struct LayoutSet { 0169 QList<LayoutUnit> layouts; 0170 LayoutUnit currentLayout; 0171 0172 LayoutSet() {} 0173 0174 LayoutSet(const LayoutSet& currentLayouts) { 0175 this->layouts = currentLayouts.layouts; 0176 this->currentLayout = currentLayouts.currentLayout; 0177 } 0178 0179 bool isValid() const { 0180 return currentLayout.isValid() && layouts.contains(currentLayout); 0181 } 0182 0183 bool operator == (const LayoutSet& currentLayouts) const { 0184 return this->layouts == currentLayouts.layouts 0185 && this->currentLayout == currentLayouts.currentLayout; 0186 } 0187 0188 LayoutSet& operator = (const LayoutSet& currentLayouts) { 0189 this->layouts = currentLayouts.layouts; 0190 this->currentLayout = currentLayouts.currentLayout; 0191 return *this; 0192 } 0193 0194 QString toString() const { 0195 QString str(currentLayout.toString()); 0196 str += QLatin1String(": "); 0197 foreach(const LayoutUnit& layoutUnit, layouts) { 0198 str += layoutUnit.toString() + QLatin1Char(' '); 0199 } 0200 return str; 0201 } 0202 0203 static QString toString(const QList<LayoutUnit>& layoutUnits) { 0204 QString str; 0205 foreach(const LayoutUnit& layoutUnit, layoutUnits) { 0206 str += layoutUnit.toString() + QLatin1Char(','); 0207 } 0208 return str; 0209 } 0210 }; 0211 0212 class X11Helper 0213 { 0214 public: 0215 static const int MAX_GROUP_COUNT; 0216 static const int ARTIFICIAL_GROUP_LIMIT_COUNT; 0217 0218 static const char LEFT_VARIANT_STR[]; 0219 static const char RIGHT_VARIANT_STR[]; 0220 0221 static bool xkbSupported(int* xkbOpcode); 0222 0223 static void switchToNextLayout(); 0224 static void scrollLayouts(int delta); 0225 static bool isDefaultLayout(); 0226 static bool setDefaultLayout(); 0227 static bool setLayout(const LayoutUnit& layout); 0228 static LayoutUnit getCurrentLayout(); 0229 static LayoutSet getCurrentLayouts(); 0230 static QList<LayoutUnit> getLayoutsList(); 0231 static QStringList getLayoutsListAsString(const QList<LayoutUnit>& layoutsList); 0232 0233 enum FetchType { ALL, LAYOUTS_ONLY, MODEL_ONLY }; 0234 static bool getGroupNames(Display* dpy, XkbConfig* xkbConfig, FetchType fetchType); 0235 0236 private: 0237 static unsigned int getGroup(); 0238 static bool setGroup(unsigned int group); 0239 }; 0240 0241 #endif /* X11_HELPER_H_ */