diff --git a/kcms/keyboard/x11_helper.h b/kcms/keyboard/x11_helper.h index 5006a4a67..e6708e399 100644 --- a/kcms/keyboard/x11_helper.h +++ b/kcms/keyboard/x11_helper.h @@ -1,205 +1,212 @@ /* * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef X11_HELPER_H_ #define X11_HELPER_H_ #include #include #include #include #include #include #define explicit explicit_is_keyword_in_cpp #include #include #undef explicit namespace { typedef union { /* All XKB events share these fields. */ struct { uint8_t response_type; uint8_t xkbType; uint16_t sequence; xcb_timestamp_t time; uint8_t deviceID; } any; xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify; xcb_xkb_map_notify_event_t map_notify; xcb_xkb_state_notify_event_t state_notify; } _xkb_event; } class XEventNotifier : public QObject, public QAbstractNativeEventFilter { Q_OBJECT Q_SIGNALS: void layoutChanged(); void layoutMapChanged(); public: XEventNotifier(); ~XEventNotifier() override {} virtual void start(); virtual void stop(); protected: // bool x11Event(XEvent * e); virtual bool processOtherEvents(xcb_generic_event_t* e); virtual bool processXkbEvents(xcb_generic_event_t* e); bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; private: int registerForXkbEvents(Display* display); bool isXkbEvent(xcb_generic_event_t* event); bool isGroupSwitchEvent(_xkb_event* event); bool isLayoutSwitchEvent(_xkb_event* event); int xkbOpcode; }; struct XkbConfig { QString keyboardModel; QStringList layouts; QStringList variants; QStringList options; bool isValid() { return ! layouts.empty(); } }; struct LayoutUnit { static const int MAX_LABEL_LENGTH; //TODO: move these to private? QString layout; QString variant; LayoutUnit() {} explicit LayoutUnit(const QString& fullLayoutName); LayoutUnit(const QString& layout_, const QString& variant_) { layout = layout_; variant = variant_; } - /*explicit*/ LayoutUnit(const LayoutUnit& layoutUnit) { - layout = layoutUnit.layout; - variant = layoutUnit.variant; - displayName = layoutUnit.displayName; - shortcut = layoutUnit.shortcut; - } + /*explicit*/ LayoutUnit(const LayoutUnit& other) { + operator=(other); + } + + LayoutUnit &operator=(const LayoutUnit &other) { + if (this != &other) { + layout = other.layout; + variant = other.variant; + displayName = other.displayName; + shortcut = other.shortcut; + } + return *this; + } QString getRawDisplayName() const { return displayName; } QString getDisplayName() const { return !displayName.isEmpty() ? displayName : layout; } void setDisplayName(const QString& name) { displayName = name; } void setShortcut(const QKeySequence& shortcut) { this->shortcut = shortcut; } QKeySequence getShortcut() const { return shortcut; } bool isEmpty() const { return layout.isEmpty(); } bool isValid() const { return ! isEmpty(); } bool operator==(const LayoutUnit& layoutItem) const { return layout==layoutItem.layout && variant==layoutItem.variant; } bool operator!=(const LayoutUnit& layoutItem) const { return ! (*this == layoutItem); } QString toString() const; private: QString displayName; QKeySequence shortcut; }; struct LayoutSet { QList layouts; LayoutUnit currentLayout; LayoutSet() {} LayoutSet(const LayoutSet& currentLayouts) { this->layouts = currentLayouts.layouts; this->currentLayout = currentLayouts.currentLayout; } bool isValid() const { return currentLayout.isValid() && layouts.contains(currentLayout); } bool operator == (const LayoutSet& currentLayouts) const { return this->layouts == currentLayouts.layouts && this->currentLayout == currentLayouts.currentLayout; } LayoutSet& operator = (const LayoutSet& currentLayouts) { this->layouts = currentLayouts.layouts; this->currentLayout = currentLayouts.currentLayout; return *this; } QString toString() const { QString str(currentLayout.toString()); str += QLatin1String(": "); foreach(const LayoutUnit& layoutUnit, layouts) { str += layoutUnit.toString() + " "; } return str; } static QString toString(const QList& layoutUnits) { QString str; foreach(const LayoutUnit& layoutUnit, layoutUnits) { str += layoutUnit.toString() + ","; } return str; } }; class X11Helper { public: static const int MAX_GROUP_COUNT; static const int ARTIFICIAL_GROUP_LIMIT_COUNT; static const char LEFT_VARIANT_STR[]; static const char RIGHT_VARIANT_STR[]; static bool xkbSupported(int* xkbOpcode); static void switchToNextLayout(); static void scrollLayouts(int delta); static bool isDefaultLayout(); static bool setDefaultLayout(); static bool setLayout(const LayoutUnit& layout); static LayoutUnit getCurrentLayout(); static LayoutSet getCurrentLayouts(); static QList getLayoutsList(); static QStringList getLayoutsListAsString(const QList& layoutsList); enum FetchType { ALL, LAYOUTS_ONLY, MODEL_ONLY }; static bool getGroupNames(Display* dpy, XkbConfig* xkbConfig, FetchType fetchType); private: static unsigned int getGroup(); static bool setGroup(unsigned int group); }; #endif /* X11_HELPER_H_ */