File indexing completed on 2024-05-12 05:35:43

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