mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00

consider the mail references just as dead Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
227 lines
8.7 KiB
C++
227 lines
8.7 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2011, 2012 Albert Astals Cid <aacid@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 *
|
|
***************************************************************************/
|
|
|
|
#include "ktouchpadenabler_daemon.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include <KApplication>
|
|
#include <KDebug>
|
|
#include <KLocalizedString>
|
|
#include <KNotification>
|
|
#include <KPluginFactory>
|
|
|
|
#include <QWidget>
|
|
|
|
#include <X11/Xatom.h>
|
|
#include <X11/extensions/XInput2.h>
|
|
#include <X11/XF86keysym.h>
|
|
|
|
class TouchpadEnablerDaemonPrivate : public QWidget
|
|
{
|
|
public:
|
|
TouchpadEnablerDaemonPrivate();
|
|
~TouchpadEnablerDaemonPrivate();
|
|
|
|
bool initSuccessful() const;
|
|
|
|
bool x11Event(XEvent *event);
|
|
|
|
private:
|
|
enum TouchpadKey { ToggleKey = 0, OnKey = 1, OffKey = 2 };
|
|
static const int nKeys = OffKey + 1;
|
|
|
|
bool getEnabled(bool *currentValue) const;
|
|
void setEnabled(bool enabled) const;
|
|
|
|
Display *m_display;
|
|
KeyCode m_keyCode[nKeys];
|
|
int m_deviceId;
|
|
Atom m_enabledProperty;
|
|
};
|
|
|
|
TouchpadEnablerDaemonPrivate::TouchpadEnablerDaemonPrivate()
|
|
{
|
|
bool foundTouchpad = false;
|
|
bool foundMoreThanOneTouchpad = false;
|
|
|
|
for (int i = 0; i < nKeys; ++i) {
|
|
m_keyCode[i] = 0;
|
|
}
|
|
|
|
m_display = QX11Info::display();
|
|
if (!m_display) {
|
|
kWarning() << "Did not find a display to use. This should never happen, thus doing nothing";
|
|
return;
|
|
}
|
|
|
|
Atom synapticsProperty = XInternAtom (m_display, "Synaptics Off", False);
|
|
m_enabledProperty = XInternAtom (m_display, "Device Enabled", False);
|
|
|
|
if (synapticsProperty && m_enabledProperty) {
|
|
int nDevices;
|
|
XIDeviceInfo *devices = XIQueryDevice(m_display, XIAllDevices, &nDevices);
|
|
for (int i = 0; i < nDevices; ++i) {
|
|
Atom realtype;
|
|
int realformat;
|
|
unsigned long nitems, bytes_after;
|
|
unsigned char *data;
|
|
if ((XIGetProperty (m_display, devices[i].deviceid, synapticsProperty, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) {
|
|
XFree (data);
|
|
if ((XIGetProperty (m_display, devices[i].deviceid, m_enabledProperty, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) {
|
|
XFree (data);
|
|
if (foundTouchpad) {
|
|
foundMoreThanOneTouchpad = true;
|
|
} else {
|
|
m_deviceId = devices[i].deviceid;
|
|
foundTouchpad = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (devices) {
|
|
XIFreeDeviceInfo(devices);
|
|
}
|
|
} else {
|
|
kWarning() << "Could not get atoms for 'Synaptics Off' or 'Device Enabled'. This should never happen, thus doing nothing";
|
|
}
|
|
|
|
if (foundTouchpad) {
|
|
if (!foundMoreThanOneTouchpad) {
|
|
m_keyCode[ToggleKey] = XKeysymToKeycode(m_display, XF86XK_TouchpadToggle);
|
|
m_keyCode[OnKey] = XKeysymToKeycode(m_display, XF86XK_TouchpadOn);
|
|
m_keyCode[OffKey] = XKeysymToKeycode(m_display, XF86XK_TouchpadOff);
|
|
for (int i = 0; i < nKeys; ++i) {
|
|
if (m_keyCode[i] != 0) {
|
|
const int grabResult = XGrabKey(m_display, m_keyCode[i], AnyModifier, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync);
|
|
if (grabResult == BadAccess || grabResult == BadValue || grabResult == BadWindow) {
|
|
kDebug() << "Could not grab ktouchpadenabler key index" << i <<". You probably have some other program grabbig it";
|
|
m_keyCode[i] = 0;
|
|
} else {
|
|
bool currentlyEnabled;
|
|
if (getEnabled(¤tlyEnabled)) {
|
|
const bool newValue = ktouchpadenabler::Settings::self()->touchpadEnabled();
|
|
if (newValue != currentlyEnabled) {
|
|
setEnabled(newValue);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
kWarning() << "Could not match ktouchpadenabler key index" << i << "to a Keycode. This should never happen";
|
|
}
|
|
}
|
|
} else {
|
|
KNotification *notification = KNotification::event(KNotification::Warning, i18n("Touchpad status"), i18n("More than one touchpad detected. Touchpad Enabler Daemon does not handle this configuration"));
|
|
notification->sendEvent();
|
|
}
|
|
} else {
|
|
kDebug() << "Did not find a touchpad";
|
|
}
|
|
}
|
|
|
|
TouchpadEnablerDaemonPrivate::~TouchpadEnablerDaemonPrivate()
|
|
{
|
|
for (int i = 0; i < nKeys; ++i) {
|
|
if (m_keyCode[i] != 0) {
|
|
XUngrabKey(m_display, m_keyCode[i], 0 /* No modifiers */, QX11Info::appRootWindow());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TouchpadEnablerDaemonPrivate::initSuccessful() const {
|
|
for (int i = 0; i < nKeys; ++i) {
|
|
if (m_keyCode[i] == 0) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool TouchpadEnablerDaemonPrivate::x11Event(XEvent *event)
|
|
{
|
|
if (event->type == KeyPress) {
|
|
for (int i = 0; i < nKeys; ++i) {
|
|
if (event->xkey.keycode == m_keyCode[i]) {
|
|
bool currentlyEnabled;
|
|
if (getEnabled(¤tlyEnabled)) {
|
|
bool newValue;
|
|
switch (i) {
|
|
case ToggleKey: newValue = !currentlyEnabled; break;
|
|
case OnKey: newValue = true; break;
|
|
case OffKey: newValue = false; break;
|
|
}
|
|
if (newValue != currentlyEnabled) {
|
|
setEnabled(newValue);
|
|
|
|
KNotification *notification = KNotification::event(KNotification::Notification, i18n("Touchpad status"), newValue ? i18n("Touchpad enabled") : i18n("Touchpad disabled"));
|
|
notification->sendEvent();
|
|
|
|
ktouchpadenabler::Settings::self()->setTouchpadEnabled(newValue);
|
|
ktouchpadenabler::Settings::self()->writeConfig();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool TouchpadEnablerDaemonPrivate::getEnabled(bool *enabled) const
|
|
{
|
|
Atom realtype;
|
|
int realformat;
|
|
unsigned long nitems, bytes_after;
|
|
unsigned char *value;
|
|
if ((XIGetProperty(m_display, m_deviceId, m_enabledProperty, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &value) == Success) && (realtype != None)) {
|
|
*enabled = (*value == 1);
|
|
XFree(value);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void TouchpadEnablerDaemonPrivate::setEnabled(bool enabled) const
|
|
{
|
|
unsigned char newValue = enabled ? 1 : 0;
|
|
XIChangeProperty(m_display, m_deviceId, m_enabledProperty, XA_INTEGER, 8, PropModeReplace, &newValue, 1);
|
|
XFlush(m_display);
|
|
}
|
|
|
|
TouchpadEnablerDaemon::TouchpadEnablerDaemon(QObject *parent, const QList<QVariant>&)
|
|
: KDEDModule(parent)
|
|
{
|
|
d = new TouchpadEnablerDaemonPrivate();
|
|
|
|
if (d->initSuccessful()) {
|
|
kapp->installX11EventFilter(d);
|
|
} else {
|
|
delete d;
|
|
d = 0;
|
|
}
|
|
}
|
|
|
|
TouchpadEnablerDaemon::~TouchpadEnablerDaemon()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
K_PLUGIN_FACTORY(TouchpadEnablerFactory, registerPlugin<TouchpadEnablerDaemon>();)
|
|
K_EXPORT_PLUGIN(TouchpadEnablerFactory("ktouchpadenabler"))
|