49 setObjectName(QLatin1String(
"BSD Keyboard Handler"));
52 if (specification.startsWith(
"/dev/"))
53 device = QFile::encodeName(specification);
55 if (device.isEmpty()) {
56 device = QByteArrayLiteral(
"STDIN");
60 m_fd = QT_OPEN(device.constData(), O_RDONLY);
62 qErrnoWarning(errno,
"open(%s) failed", device.constData());
68 if (ioctl(m_fd, KDGKBMODE, &m_origKbdMode)) {
69 qErrnoWarning(errno,
"ioctl(%s, KDGKBMODE) failed", device.constData());
74 if (ioctl(m_fd, KDSKBMODE, K_CODE) < 0) {
75 qErrnoWarning(errno,
"ioctl(%s, KDSKBMODE) failed", device.constData());
81 if (tcgetattr(m_fd, &kbdtty) == 0) {
83 m_kbdOrigTty.reset(
new termios);
84 *m_kbdOrigTty = kbdtty;
86 kbdtty.c_iflag = IGNPAR | IGNBRK;
88 kbdtty.c_cflag = CREAD | CS8;
90 kbdtty.c_cc[VTIME] = 0;
91 kbdtty.c_cc[VMIN] = 0;
92 cfsetispeed(&kbdtty, 9600);
93 cfsetospeed(&kbdtty, 9600);
94 if (tcsetattr(m_fd, TCSANOW, &kbdtty) < 0) {
95 qErrnoWarning(errno,
"tcsetattr(%s) failed", device.constData());
105 qErrnoWarning(errno,
"tcgetattr(%s) failed", device.constData());
110 if (fcntl(m_fd, F_SETFL, O_NONBLOCK)) {
111 qErrnoWarning(errno,
"fcntl(%s, F_SETFL, O_NONBLOCK) failed", device.constData());
118 m_notifier.reset(
new QSocketNotifier(m_fd, QSocketNotifier::Read,
this));
119 connect(m_notifier.data(), &QSocketNotifier::activated,
this, &QBsdKeyboardHandler::readKeyboardData);
120 QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
121 QInputDeviceManager::DeviceTypeKeyboard, 1);
153 int bytesRead = qt_safe_read(m_fd, buffer,
sizeof(buffer));
156 qWarning(
"Got EOF from the input device.");
158 }
else if (bytesRead < 0) {
159 if (errno != EINTR && errno != EAGAIN)
160 qWarning(
"Could not read from input device: %s", strerror(errno));
164 for (
int i = 0; i < bytesRead; ++i) {
165 const quint16 code = buffer[i] & Bsd_KeyCodeMask;
166 const bool pressed = (buffer[i] & Bsd_KeyPressedMask) ?
false :
true;
168 processKeycode(code, pressed,
false);
174 Qt::KeyboardModifiers modifiers,
bool isPress,
177 const QString text = (unicode != 0xffff ) ? QString(unicode) : QString();
178 const QEvent::Type eventType = isPress ? QEvent::KeyPress : QEvent::KeyRelease;
180 QWindowSystemInterface::handleExtendedKeyEvent(0, eventType, qtcode, modifiers, nativecode, 0,
181 int(modifiers), text, autoRepeat);
186 const bool first_press = pressed && !autorepeat;
191 quint8 modifiers = m_modifiers;
194 for (
const QBsdKeyboardMap::Mapping &m : m_keymap) {
195 if (m.keycode == keycode) {
196 if (m.modifiers == 0)
199 quint8 testmods = m_modifiers;
200 if (m_capsLock && (m.flags & QBsdKeyboardMap::IsLetter))
201 testmods ^= QBsdKeyboardMap::ModShift;
202 if (m.modifiers == testmods)
210#ifdef QT_BSD_KEYBOARD_DEBUG
211 qWarning(
"Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d",
212 keycode, modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0);
218#ifdef QT_BSD_KEYBOARD_DEBUG
220 qWarning(
"Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, modifiers);
226 quint16 unicode = it->unicode;
227 quint32 qtcode = it->qtcode;
232 m_modifiers |= quint8(it->special);
234 m_modifiers &= ~quint8(it->special);
240 m_capsLock = !m_capsLock;
241 switchLed(LED_CAP, m_capsLock);
244 m_numLock = !m_numLock;
245 switchLed(LED_NUM, m_numLock);
248 m_scrollLock = !m_scrollLock;
249 switchLed(LED_SCR, m_scrollLock);
265 if ((it == map_plain && it != map_withmod) ||
266 (map_withmod && !(map_withmod->qtcode & modmask))) {
267 qtcode |= QBsdKeyboardHandler::toQtModifiers(modifiers);
270#ifdef QT_BSD_KEYBOARD_DEBUG
271 qWarning(
"Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask));
277 const int oldMask = (qtcode & modmask);
278 switch (qtcode & ~modmask) {
317 processKeyEvent(keycode, unicode, qtcode & ~modmask,
318 Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat);
344#ifdef QT_BSD_KEYBOARD_DEBUG
345 qWarning() <<
"Unload current keymap and restore built-in";
350 const size_t mappingSize =
sizeof(keymapDefault) /
sizeof(keymapDefault[0]);
351 m_keymap.resize(mappingSize);
352 std::copy_n( &keymapDefault[0], mappingSize, m_keymap.begin() );
358 m_scrollLock =
false;
362 if (ioctl(m_fd, KDGETLED, &leds) < 0) {
363 qWarning(
"Failed to query led states. Settings numlock & capslock off");
364 switchLed(LED_NUM,
false);
365 switchLed(LED_CAP,
false);
366 switchLed(LED_SCR,
false);
368 if ((leds & LED_CAP) > 0)
370 if ((leds & LED_NUM) > 0)
372 if ((leds & LED_SCR) > 0)
374#ifdef QT_BSD_KEYBOARD_DEBUG
375 qWarning(
"numlock=%d , capslock=%d, scrolllock=%d",m_numLock, m_capsLock, m_scrollLock);