7#include <qplatformdefs.h>
10#include <QSocketNotifier>
12#include <QCoreApplication>
13#include <QLoggingCategory>
14#include <qpa/qwindowsysteminterface.h>
15#include <private/qcore_unix_p.h>
17#include <QtGui/private/qguiapplication_p.h>
18#include <QtGui/private/qinputdevicemanager_p.h>
21#include <dev/evdev/input.h>
23#include <linux/input.h>
26#ifndef input_event_sec
27#define input_event_sec time.tv_sec
30#ifndef input_event_usec
31#define input_event_usec time.tv_usec
42#include "qevdevkeyboard_defaultmap_p.h"
53 m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
54 m_langLock(0), m_no_zap(disableZap), m_do_compose(enableCompose),
55 m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
57 qCDebug(qLcEvdevKey) <<
"Create keyboard handler with for device" <<
device;
61 memset(m_locks, 0,
sizeof(m_locks));
78 const QString &defaultKeymapFile)
80 qCDebug(qLcEvdevKey,
"Try to create keyboard handler for \"%ls\" \"%ls\"",
83 QString keymapFile = defaultKeymapFile;
84 int repeatDelay = 400;
86 bool disableZap =
false;
87 bool enableCompose =
false;
92 if (
arg.startsWith(
"keymap="_L1))
93 keymapFile =
arg.mid(7).toString();
94 else if (
arg ==
"disable-zap"_L1)
96 else if (
arg ==
"enable-compose"_L1)
98 else if (
arg.startsWith(
"repeat-delay="_L1))
99 repeatDelay =
arg.mid(13).toInt();
100 else if (
arg.startsWith(
"repeat-rate="_L1))
101 repeatRate =
arg.mid(12).toInt();
102 else if (
arg.startsWith(
"grab="_L1))
103 grab =
arg.mid(5).toInt();
110 qCDebug(qLcEvdevKey,
"Keyboard device could not be opened as read-write, trying read-only");
114 ::ioctl(
fd.get(), EVIOCGRAB, grab);
115 if (repeatDelay > 0 && repeatRate > 0) {
116 int kbdrep[2] = { repeatDelay, repeatRate };
117 ::ioctl(
fd.get(), EVIOCSREP, kbdrep);
127void QEvdevKeyboardHandler::switchLed(
int led,
bool state)
129 qCDebug(qLcEvdevKey,
"switchLed %d %d", led,
int(
state));
132 ::gettimeofday(&tv, 0);
133 struct ::input_event led_ie;
134 led_ie.input_event_sec = tv.tv_sec;
135 led_ie.input_event_usec = tv.tv_usec;
136 led_ie.type = EV_LED;
138 led_ie.value =
state;
145 struct ::input_event
buffer[32];
152 qWarning(
"evdevkeyboard: Got EOF from the input device");
155 if (errno != EINTR && errno != EAGAIN) {
156 qErrnoWarning(
"evdevkeyboard: Could not read from input device");
159 if (errno == ENODEV) {
168 if (
n %
sizeof(
buffer[0]) == 0)
175 for (
int i = 0;
i <
n; ++
i) {
208void QEvdevKeyboardHandler::processKeyEvent(
int nativecode,
int unicode,
int qtcode,
209 Qt::KeyboardModifiers
modifiers,
bool isPress,
bool autoRepeat)
226 bool first_press = pressed && !autorepeat;
234 for (
int i = 0;
i < m_keymap_size && !(map_plain && map_withmod); ++
i) {
236 if (
m->keycode == keycode) {
237 if (
m->modifiers == 0)
240 quint8 testmods = m_modifiers;
245 if (
m->modifiers == testmods)
253 qCDebug(qLcEvdevKeyMap,
"Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d | plain=%d, withmod=%d, size=%d",
254 keycode,
modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0,
255 int(map_plain ? map_plain - m_keymap : -1),
256 int(map_withmod ? map_withmod - m_keymap : -1),
263 qCDebug(qLcEvdevKeyMap,
"Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode,
modifiers);
291 switch (
it->special) {
325 if (first_press && m_composing == 1 && m_dead_unicode == unicode) {
328 }
else if (first_press && unicode != 0xffff) {
329 m_dead_unicode = unicode;
344 if ((
it == map_plain &&
it != map_withmod) ||
345 (map_withmod && !(map_withmod->
qtcode & modmask))) {
351 if (unicode != 0xffff) {
354 for ( ; idx < m_keycompose_size; ++idx) {
355 if (m_keycompose[idx].
first == unicode)
358 if (idx < m_keycompose_size) {
360 m_dead_unicode = unicode;
373 if (unicode != 0xffff) {
376 for ( ; idx < m_keycompose_size; ++idx) {
377 if (m_keycompose[idx].
first == m_dead_unicode && m_keycompose[idx].second == unicode)
380 if (idx < m_keycompose_size) {
382 if (composed != 0xffff) {
390 unicode = m_dead_unicode;
398 Qt::KeyboardModifiers qtmods = Qt::KeyboardModifiers(qtcode & modmask);
403 qCDebug(qLcEvdevKeyMap,
"Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode,
int(qtmods));
455 processKeyEvent(keycode, unicode, qtcode, qtmods, pressed, autorepeat);
463 qCDebug(qLcEvdevKey,
"Unload current keymap and restore built-in");
465 if (m_keymap && m_keymap != s_keymap_default)
467 if (m_keycompose && m_keycompose != s_keycompose_default)
468 delete [] m_keycompose;
470 m_keymap = s_keymap_default;
471 m_keymap_size =
sizeof(s_keymap_default) /
sizeof(s_keymap_default[0]);
472 m_keycompose = s_keycompose_default;
473 m_keycompose_size =
sizeof(s_keycompose_default) /
sizeof(s_keycompose_default[0]);
477 memset(m_locks, 0,
sizeof(m_locks));
479 m_dead_unicode = 0xffff;
483 memset(ledbits, 0,
sizeof(ledbits));
484 if (::ioctl(m_fd.
get(), EVIOCGLED(
sizeof(ledbits)), ledbits) < 0) {
485 qWarning(
"evdevkeyboard: Failed to query led states");
486 switchLed(LED_NUML,
false);
487 switchLed(LED_CAPSL,
false);
488 switchLed(LED_SCROLLL,
false);
491 if ((ledbits[0]&0x02) > 0)
494 if ((ledbits[0]&0x01) > 0)
497 if ((ledbits[0]&0x04) > 0)
499 qCDebug(qLcEvdevKey,
"numlock=%d , capslock=%d, scrolllock=%d", m_locks[1], m_locks[0], m_locks[2]);
524 quint32 qmap_magic, qmap_version, qmap_keymap_size, qmap_keycompose_size;
528 ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size;
538 for (
quint32 i = 0;
i < qmap_keymap_size; ++
i)
539 ds >> qmap_keymap[
i];
540 for (
quint32 i = 0;
i < qmap_keycompose_size; ++
i)
541 ds >> qmap_keycompose[
i];
544 delete [] qmap_keymap;
545 delete [] qmap_keycompose;
554 m_keymap = qmap_keymap;
555 m_keymap_size = qmap_keymap_size;
556 m_keycompose = qmap_keycompose;
557 m_keycompose_size = qmap_keycompose_size;
IOBluetoothDevice * device
\inmodule QtCore\reentrant
Status status() const
Returns the status of the data stream.
QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile)
static std::unique_ptr< QEvdevKeyboardHandler > create(const QString &device, const QString &specification, const QString &defaultKeymapFile=QString())
KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat)
bool loadKeymap(const QString &file)
static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
static QInputDeviceManager * inputDeviceManager()
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
static QOutputMapping * get()
void activated(QSocketDescriptor socket, QSocketNotifier::Type activationEvent, QPrivateSignal)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static bool handleExtendedKeyEvent(QWindow *window, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
EGLImageKHR int int EGLuint64KHR * modifiers
QSet< QString >::iterator it
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
static qint64 qt_safe_write(int fd, const void *data, qint64 len)
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static int qt_safe_close(int fd)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLenum GLenum GLenum input
#define qUtf16Printable(string)