[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [plasma-desktop] kcms/keyboard: Resurrect event handling in keyboard module
From:       Andriy Rysin <arysin () gmail ! com>
Date:       2014-04-02 17:41:00
Message-ID: E1WVP9o-0008EQ-Vs () scm ! kde ! org
[Download RAW message or body]

Git commit c0f52dc020623ae32d85b490ef4e7981703b5495 by Andriy Rysin.
Committed on 02/04/2014 at 17:39.
Pushed by rysin into branch 'master'.

Resurrect event handling in keyboard module

M  +1    -1    kcms/keyboard/CMakeLists.txt
M  +0    -8    kcms/keyboard/keyboard_daemon.cpp
M  +0    -6    kcms/keyboard/layout_widget.cpp
M  +51   -31   kcms/keyboard/x11_helper.cpp
M  +86   -11   kcms/keyboard/x11_helper.h
M  +6    -4    kcms/keyboard/xinput_helper.cpp
M  +4    -2    kcms/keyboard/xinput_helper.h

http://commits.kde.org/plasma-desktop/c0f52dc020623ae32d85b490ef4e7981703b5495

diff --git a/kcms/keyboard/CMakeLists.txt b/kcms/keyboard/CMakeLists.txt
index 73492b4..de382c5 100644
--- a/kcms/keyboard/CMakeLists.txt
+++ b/kcms/keyboard/CMakeLists.txt
@@ -17,7 +17,7 @@ set( kded_keyboard_SRCS
     layout_memory.cpp
     layout_memory_persister.cpp
     x11_helper.cpp
-#     xinput_helper.cpp
+    xinput_helper.cpp
     xkb_helper.cpp
     keyboard_config.cpp
     keyboard_hardware.cpp
diff --git a/kcms/keyboard/keyboard_daemon.cpp b/kcms/keyboard/keyboard_daemon.cpp
index 825cca4..62243e9 100644
--- a/kcms/keyboard/keyboard_daemon.cpp
+++ b/kcms/keyboard/keyboard_daemon.cpp
@@ -31,9 +31,7 @@
 #include <klocalizedstring.h>
 
 #include "x11_helper.h"
-#if 0
 #include "xinput_helper.h"
-#endif
 #include "xkb_helper.h"
 #include "keyboard_dbus.h"
 #include "xkb_rules.h"
@@ -159,8 +157,6 @@ void KeyboardDaemon::unregisterShortcut()
 
 void KeyboardDaemon::registerListeners()
 {
-#warning XInputEventNotifier needs porting to QAbstractNativeEventFilter
-#if 0
 	if( xEventNotifier == NULL ) {
 		xEventNotifier = new XInputEventNotifier();
 	}
@@ -169,13 +165,10 @@ void KeyboardDaemon::registerListeners()
 	connect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutMapChanged()));
 	connect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
 	xEventNotifier->start();
-#endif
 }
 
 void KeyboardDaemon::unregisterListeners()
 {
-#warning XInputEventNotifier needs porting to QAbstractNativeEventFilter
-#if 0
 	if( xEventNotifier != NULL ) {
 		xEventNotifier->stop();
 		disconnect(xEventNotifier, SIGNAL(newPointerDevice()), this, SLOT(configureMouse()));
@@ -183,7 +176,6 @@ void KeyboardDaemon::unregisterListeners()
 		disconnect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
 		disconnect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutMapChanged()));
 	}
-#endif
 }
 
 void KeyboardDaemon::globalSettingsChanged(int category)
diff --git a/kcms/keyboard/layout_widget.cpp b/kcms/keyboard/layout_widget.cpp
index 231c39c..e67b2d7 100644
--- a/kcms/keyboard/layout_widget.cpp
+++ b/kcms/keyboard/layout_widget.cpp
@@ -68,23 +68,17 @@ LayoutWidget::~LayoutWidget()
 
 void LayoutWidget::init()
 {
-#warning XEventNotifier needs porting to QAbstractNativeEventFilter
-#if 0
 	connect(widget, SIGNAL(clicked(bool)), this, SLOT(toggleLayout()));
 	connect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
 	connect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged()));
 	xEventNotifier->start();
-#endif
 }
 
 void LayoutWidget::destroy()
 {
-#warning XEventNotifier needs porting to QAbstractNativeEventFilter
-#if 0
 	xEventNotifier->stop();
 	disconnect(xEventNotifier, SIGNAL(layoutMapChanged()), this, SLOT(layoutChanged()));
 	disconnect(xEventNotifier, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
-#endif
 }
 
 void LayoutWidget::toggleLayout()
diff --git a/kcms/keyboard/x11_helper.cpp b/kcms/keyboard/x11_helper.cpp
index 84f5592..de9f768 100644
--- a/kcms/keyboard/x11_helper.cpp
+++ b/kcms/keyboard/x11_helper.cpp
@@ -18,16 +18,18 @@
 
 #include "x11_helper.h"
 
-#include <kapplication.h>
 #include <kdebug.h>
 
 #include <QX11Info>
+#include <QCoreApplication>
 
 #include <X11/X.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/XKBlib.h>
 #include <X11/extensions/XKBrules.h>
+#include <xcb/xcb.h>
+//#include <xcb/xkb.h>
 #include <fixx11h.h>
 
 
@@ -280,86 +282,105 @@ bool X11Helper::getGroupNames(Display* display, XkbConfig* xkbConfig, FetchType
 	return true;
 }
 
-#if 0
-XEventNotifier::XEventNotifier(QWidget* parent):
-		QWidget(parent),
+XEventNotifier::XEventNotifier():
 		xkbOpcode(-1)
 {
-	if( KApplication::kApplication() == NULL ) {
+	if( QCoreApplication::instance() == NULL ) {
 		kWarning() << "Layout Widget won't work properly without KApplication instance";
 	}
 }
 
 void XEventNotifier::start()
 {
-	if( KApplication::kApplication() != NULL && X11Helper::xkbSupported(&xkbOpcode) ) {
+	kDebug() << "qCoreApp" << QCoreApplication::instance();
+	if( QCoreApplication::instance() != NULL && X11Helper::xkbSupported(&xkbOpcode) ) {
 		registerForXkbEvents(QX11Info::display());
 
 		// start the event loop
-		KApplication::kApplication()->installX11EventFilter(this);
+		QCoreApplication::instance()->installNativeEventFilter(this);
 	}
 }
 
 void XEventNotifier::stop()
 {
-	if( KApplication::kApplication() != NULL ) {
+	if( QCoreApplication::instance() != NULL ) {
 		//TODO: unregister
 	//    XEventNotifier::unregisterForXkbEvents(QX11Info::display());
 
 		// stop the event loop
-		KApplication::kApplication()->removeX11EventFilter(this);
+		QCoreApplication::instance()->removeNativeEventFilter(this);
 	}
 }
 
-bool XEventNotifier::isXkbEvent(XEvent* event)
+
+bool XEventNotifier::isXkbEvent(xcb_generic_event_t* event)
 {
-	return event->type == xkbOpcode;
+//	kDebug() << "event response type:" << (event->response_type & ~0x80) << xkbOpcode << \
((event->response_type & ~0x80) == xkbOpcode + XkbEventCode); +    return (event->response_type & ~0x80) \
== xkbOpcode + XkbEventCode;  }
 
-bool XEventNotifier::processOtherEvents(XEvent* /*event*/)
+bool XEventNotifier::processOtherEvents(xcb_generic_event_t* /*event*/)
 {
 	return true;
 }
 
-bool XEventNotifier::processXkbEvents(XEvent* event)
+bool XEventNotifier::processXkbEvents(xcb_generic_event_t* event)
 {
-	if( XEventNotifier::isGroupSwitchEvent(event) ) {
+	_xkb_event *xkbevt = reinterpret_cast<_xkb_event *>(event);
+	if( XEventNotifier::isGroupSwitchEvent(xkbevt) ) {
+//		kDebug() << "group switch event";
 		emit(layoutChanged());
 	}
-	else if( XEventNotifier::isLayoutSwitchEvent(event) ) {
+	else if( XEventNotifier::isLayoutSwitchEvent(xkbevt) ) {
+//		kDebug() << "layout switch event";
 		emit(layoutMapChanged());
 	}
 	return true;
 }
 
-bool XEventNotifier::x11Event(XEvent * event)
+bool XEventNotifier::nativeEventFilter(const QByteArray &eventType, void *message, long *)
 {
-	//    qApp->x11ProcessEvent ( event );
-	if( isXkbEvent(event) ) {
-		processXkbEvents(event);
-	}
-	else {
-		processOtherEvents(event);
-	}
-	return QWidget::x11Event(event);
+//	kDebug() << "event type:" << eventType;
+    if (eventType == "xcb_generic_event_t") {
+        xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
+        if( isXkbEvent(ev) ) {
+    		processXkbEvents(ev);
+    	}
+    	else {
+    		processOtherEvents(ev);
+    	}
+    }
+    return false;
 }
 
-bool XEventNotifier::isGroupSwitchEvent(XEvent* event)
+//bool XEventNotifier::x11Event(XEvent * event)
+//{
+//	//    qApp->x11ProcessEvent ( event );
+//	if( isXkbEvent(event) ) {
+//		processXkbEvents(event);
+//	}
+//	else {
+//		processOtherEvents(event);
+//	}
+//	return QWidget::x11Event(event);
+//}
+
+bool XEventNotifier::isGroupSwitchEvent(_xkb_event* xkbEvent)
 {
-    XkbEvent *xkbEvent = (XkbEvent*) event;
+//    XkbEvent *xkbEvent = (XkbEvent*) event;
 #define GROUP_CHANGE_MASK \
     ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask )
 
-    return xkbEvent->any.xkb_type == XkbStateNotify && (xkbEvent->state.changed & GROUP_CHANGE_MASK);
+    return xkbEvent->any.xkbType == XkbStateNotify && (xkbEvent->state_notify.changed & \
GROUP_CHANGE_MASK);  }
 
-bool XEventNotifier::isLayoutSwitchEvent(XEvent* event)
+bool XEventNotifier::isLayoutSwitchEvent(_xkb_event* xkbEvent)
 {
-    XkbEvent *xkbEvent = (XkbEvent*) event;
+//    XkbEvent *xkbEvent = (XkbEvent*) event;
 
     return //( (xkbEvent->any.xkb_type == XkbMapNotify) && (xkbEvent->map.changed & XkbKeySymsMask) ) ||
 /*    	  || ( (xkbEvent->any.xkb_type == XkbNamesNotify) && (xkbEvent->names.changed & \
                XkbGroupNamesMask) || )*/
-    	   (xkbEvent->any.xkb_type == XkbNewKeyboardNotify);
+    	   (xkbEvent->any.xkbType == XkbNewKeyboardNotify);
 }
 
 int XEventNotifier::registerForXkbEvents(Display* display)
@@ -371,7 +392,6 @@ int XEventNotifier::registerForXkbEvents(Display* display)
     }
     return true;
 }
-#endif
 
 
 static const char* LAYOUT_VARIANT_SEPARATOR_PREFIX = "(";
diff --git a/kcms/keyboard/x11_helper.h b/kcms/keyboard/x11_helper.h
index b393e5e..719b13f 100644
--- a/kcms/keyboard/x11_helper.h
+++ b/kcms/keyboard/x11_helper.h
@@ -25,10 +25,85 @@
 #include <QStringList>
 #include <QWidget>
 #include <QX11Info>
+#include <QAbstractNativeEventFilter>
 
-#warning XEventNotifier needs porting to QAbstractNativeEventFilter
-#if 0
-class XEventNotifier : public QWidget {
+#include <xcb/xcb.h>
+//#include <xcb/xkb.h>
+
+//union _xkb_event;
+//class xcb_generic_event_t;
+
+// TODO: remove this when we can include xcb/xkb.h
+namespace
+{
+typedef struct _xcb_xkb_map_notify_event_t {
+    uint8_t         response_type;
+    uint8_t         xkbType;
+    uint16_t        sequence;
+    xcb_timestamp_t time;
+    uint8_t         deviceID;
+    uint8_t         ptrBtnActions;
+    uint16_t        changed;
+    xcb_keycode_t   minKeyCode;
+    xcb_keycode_t   maxKeyCode;
+    uint8_t         firstType;
+    uint8_t         nTypes;
+    xcb_keycode_t   firstKeySym;
+    uint8_t         nKeySyms;
+    xcb_keycode_t   firstKeyAct;
+    uint8_t         nKeyActs;
+    xcb_keycode_t   firstKeyBehavior;
+    uint8_t         nKeyBehavior;
+    xcb_keycode_t   firstKeyExplicit;
+    uint8_t         nKeyExplicit;
+    xcb_keycode_t   firstModMapKey;
+    uint8_t         nModMapKeys;
+    xcb_keycode_t   firstVModMapKey;
+    uint8_t         nVModMapKeys;
+    uint16_t        virtualMods;
+    uint8_t         pad0[2];
+} _xcb_xkb_map_notify_event_t;
+typedef struct _xcb_xkb_state_notify_event_t {
+    uint8_t         response_type;
+    uint8_t         xkbType;
+    uint16_t        sequence;
+    xcb_timestamp_t time;
+    uint8_t         deviceID;
+    uint8_t         mods;
+    uint8_t         baseMods;
+    uint8_t         latchedMods;
+    uint8_t         lockedMods;
+    uint8_t         group;
+    int16_t         baseGroup;
+    int16_t         latchedGroup;
+    uint8_t         lockedGroup;
+    uint8_t         compatState;
+    uint8_t         grabMods;
+    uint8_t         compatGrabMods;
+    uint8_t         lookupMods;
+    uint8_t         compatLoockupMods;
+    uint16_t        ptrBtnState;
+    uint16_t        changed;
+    xcb_keycode_t   keycode;
+    uint8_t         eventType;
+    uint8_t         requestMajor;
+    uint8_t         requestMinor;
+} _xcb_xkb_state_notify_event_t;
+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_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:
@@ -36,26 +111,26 @@ Q_SIGNALS:
 	void layoutMapChanged();
 
 public:
-	XEventNotifier(QWidget* parent=NULL);
+	XEventNotifier();
 	virtual ~XEventNotifier() {}
 
 	virtual void start();
 	virtual void stop();
 
 protected:
-    bool x11Event(XEvent * e);
-    virtual bool processOtherEvents(XEvent* e);
-    virtual bool processXkbEvents(XEvent* e);
+//    bool x11Event(XEvent * e);
+    virtual bool processOtherEvents(xcb_generic_event_t* e);
+    virtual bool processXkbEvents(xcb_generic_event_t* e);
+    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
 
 private:
 	int registerForXkbEvents(Display* display);
-	bool isXkbEvent(XEvent* event);
-	bool isGroupSwitchEvent(XEvent* event);
-	bool isLayoutSwitchEvent(XEvent* event);
+	bool isXkbEvent(xcb_generic_event_t* event);
+	bool isGroupSwitchEvent(_xkb_event* event);
+	bool isLayoutSwitchEvent(_xkb_event* event);
 
 	int xkbOpcode;
 };
-#endif
 
 struct XkbConfig {
 	QString keyboardModel;
diff --git a/kcms/keyboard/xinput_helper.cpp b/kcms/keyboard/xinput_helper.cpp
index b138855..ada7d66 100644
--- a/kcms/keyboard/xinput_helper.cpp
+++ b/kcms/keyboard/xinput_helper.cpp
@@ -42,7 +42,7 @@ static int DEVICE_KEYBOARD = 1;
 static int DEVICE_POINTER = 2;
 
 XInputEventNotifier::XInputEventNotifier(QWidget* parent):
-	XEventNotifier(parent),
+	XEventNotifier(), //TODO: destruct properly?
 	xinputEventType(-1)
 {
 }
@@ -65,7 +65,7 @@ void XInputEventNotifier::stop()
 	}
 }
 
-bool XInputEventNotifier::processOtherEvents(XEvent* event)
+bool XInputEventNotifier::processOtherEvents(xcb_generic_event_t* event)
 {
 	int newDeviceType = getNewDeviceEventType(event);
 	if( newDeviceType == DEVICE_KEYBOARD ) {
@@ -95,10 +95,11 @@ static bool isRealKeyboard(const char* deviceName)
 		&& strstr(deviceName, "WMI hotkeys") == NULL;
 }
 
-int XInputEventNotifier::getNewDeviceEventType(XEvent* event)
+int XInputEventNotifier::getNewDeviceEventType(xcb_generic_event_t* event)
 {
 	int newDeviceType = DEVICE_NONE;
 
+#if 0
 	if( xinputEventType != -1 && event->type == xinputEventType ) {
 		XDevicePresenceNotifyEvent *xdpne = (XDevicePresenceNotifyEvent*) event;
 		if( xdpne->devchange == DeviceEnabled ) {
@@ -127,6 +128,7 @@ int XInputEventNotifier::getNewDeviceEventType(XEvent* event)
 			}
 		}
 	}
+#endif
 	return newDeviceType;
 }
 
@@ -154,7 +156,7 @@ int XInputEventNotifier::registerForNewDeviceEvent(Display* /*display*/)
 	return -1;
 }
 
-int XInputEventNotifier::getNewDeviceEventType(XEvent* /*event*/)
+int XInputEventNotifier::getNewDeviceEventType(xcb_generic_event_t* /*event*/)
 {
 	return DEVICE_NONE;
 }
diff --git a/kcms/keyboard/xinput_helper.h b/kcms/keyboard/xinput_helper.h
index 92f1eb6..343d7ed 100644
--- a/kcms/keyboard/xinput_helper.h
+++ b/kcms/keyboard/xinput_helper.h
@@ -22,6 +22,8 @@
 
 #include "x11_helper.h"
 
+#include <X11/Xlib.h>
+#include <fixx11h.h>
 
 class XInputEventNotifier: public XEventNotifier {
 	Q_OBJECT
@@ -39,10 +41,10 @@ Q_SIGNALS:
 	void newPointerDevice();
 
 protected:
-	bool processOtherEvents(XEvent* event);
+	bool processOtherEvents(xcb_generic_event_t* event);
 
 private:
-	int getNewDeviceEventType(XEvent* event);
+	int getNewDeviceEventType(xcb_generic_event_t* event);
 
 	int xinputEventType;
 };


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic