File indexing completed on 2024-05-12 17:07:15

0001 /*
0002     SPDX-FileCopyrightText: 2010 Andriy Rysin <rysin@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <KConfigGroup>
0008 #include <KModifierKeyInfo>
0009 #include <KSharedConfig>
0010 
0011 #include <QDebug>
0012 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0013 #include <QX11Info>
0014 #else
0015 #include <QtGui/private/qtx11extras_p.h>
0016 #endif
0017 
0018 #include <math.h>
0019 
0020 #include "debug.h"
0021 #include "kcmmisc.h"
0022 #include "x11_helper.h"
0023 
0024 #include <X11/XKBlib.h>
0025 #include <X11/Xlib.h>
0026 #include <X11/keysym.h>
0027 
0028 // This code is taken from xset utility from XFree 4.3 (https://www.xfree86.org/)
0029 
0030 static void set_repeatrate(int delay, double rate)
0031 {
0032     if (!X11Helper::xkbSupported(nullptr)) {
0033         qCCritical(KCM_KEYBOARD) << "Failed to set keyboard repeat rate: xkb is not supported";
0034         return;
0035     }
0036 
0037     XkbDescPtr xkb = XkbAllocKeyboard();
0038     if (xkb) {
0039         Display *dpy = QX11Info::display();
0040         // int res =
0041         XkbGetControls(dpy, XkbRepeatKeysMask, xkb);
0042         xkb->ctrls->repeat_delay = delay;
0043         xkb->ctrls->repeat_interval = (int)floor(1000 / rate + 0.5);
0044         // res =
0045         XkbSetControls(dpy, XkbRepeatKeysMask, xkb);
0046         XkbFreeKeyboard(xkb, 0, true);
0047         return;
0048     }
0049 }
0050 
0051 static int set_repeat_mode(bool enabled)
0052 {
0053     XKeyboardState kbd;
0054     XKeyboardControl kbdc;
0055 
0056     XGetKeyboardControl(QX11Info::display(), &kbd);
0057 
0058     kbdc.auto_repeat_mode = (enabled ? AutoRepeatModeOn : AutoRepeatModeOff);
0059 
0060     return XChangeKeyboardControl(QX11Info::display(), KBAutoRepeatMode, &kbdc);
0061 }
0062 
0063 void init_keyboard_hardware()
0064 {
0065     auto inputConfig = KSharedConfig::openConfig(QStringLiteral("kcminputrc"));
0066     inputConfig->reparseConfiguration();
0067     KConfigGroup config(inputConfig, "Keyboard");
0068 
0069     QString keyRepeatStr = config.readEntry("KeyRepeat", "accent");
0070 
0071     if (keyRepeatStr == QLatin1String("accent") || keyRepeatStr == QLatin1String("repeat")) {
0072         int delay_ = config.readEntry("RepeatDelay", DEFAULT_REPEAT_DELAY);
0073         double rate_ = config.readEntry("RepeatRate", DEFAULT_REPEAT_RATE);
0074         set_repeatrate(delay_, rate_);
0075         set_repeat_mode(true);
0076     } else {
0077         set_repeat_mode(false);
0078     }
0079 
0080     TriState numlockState = TriStateHelper::getTriState(config.readEntry("NumLock", TriStateHelper::getInt(STATE_UNCHANGED)));
0081     if (numlockState != STATE_UNCHANGED) {
0082         KModifierKeyInfo keyInfo;
0083         keyInfo.setKeyLocked(Qt::Key_NumLock, numlockState == STATE_ON);
0084     }
0085     XFlush(QX11Info::display());
0086 }