1 /*
2     Copyright (C) 2013-2014  Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 
19 
20 #include "keyboardconfig.h"
21 #include <string.h>
22 #include <math.h>
23 #include <stdlib.h>
24 #include <LXQt/Settings>
25 #include <QDir>
26 #include <QFile>
27 #include <QStringBuilder>
28 
29 // FIXME: how to support XCB or Wayland?
30 #include <QX11Info>
31 #include <X11/Xlib.h>
32 #include <X11/XKBlib.h>
33 
34 #ifdef Q_WS_X11
35 extern void qt_x11_apply_settings_in_all_apps();
36 #endif
37 
KeyboardConfig(LXQt::Settings * _settings,QSettings * _qtSettings,QWidget * parent)38 KeyboardConfig::KeyboardConfig(LXQt::Settings* _settings, QSettings* _qtSettings, QWidget* parent):
39   QWidget(parent),
40   settings(_settings),
41   qtSettings(_qtSettings),
42   delay(500),
43   oldDelay(500),
44   interval(30),
45   oldInterval(30),
46   flashTime(1000),
47   oldFlashTime(1000),
48   beep(true),
49   oldBeep(true),
50   numlock(false),
51   oldNumlock(false) {
52 
53   ui.setupUi(this);
54 
55   /* read the config flie */
56   loadSettings();
57   initControls();
58 
59   // set_range_stops(ui.keyboardDelay, 10);
60   connect(ui.keyboardDelay, &QAbstractSlider::valueChanged, this, &KeyboardConfig::settingsChanged);
61   // set_range_stops(ui.keyboardInterval, 10);
62   connect(ui.keyboardInterval, &QAbstractSlider::valueChanged, this, &KeyboardConfig::settingsChanged);
63   connect(ui.keyboardBeep, &QAbstractButton::clicked, this, &KeyboardConfig::settingsChanged);
64   connect(ui.cursorFlashTime, QOverload<int>::of(&QSpinBox::valueChanged), this, &KeyboardConfig::settingsChanged);
65   connect(ui.keyboardNumLock, &QAbstractButton::clicked, this, &KeyboardConfig::settingsChanged);
66 }
67 
~KeyboardConfig()68 KeyboardConfig::~KeyboardConfig() {
69 
70 }
71 
initControls()72 void KeyboardConfig::initControls() {
73   ui.keyboardDelay->blockSignals(true);
74   ui.keyboardDelay->setValue(delay);
75   ui.keyboardDelay->blockSignals(false);
76 
77   ui.keyboardInterval->blockSignals(true);
78   ui.keyboardInterval->setValue(interval);
79   ui.keyboardInterval->blockSignals(false);
80 
81   ui.keyboardBeep->setChecked(beep);
82   ui.keyboardNumLock->setChecked(numlock);
83 
84   ui.cursorFlashTime->blockSignals(true);
85   ui.cursorFlashTime->setValue(flashTime);
86   ui.cursorFlashTime->blockSignals(false);
87 }
88 
applyConfig()89 void KeyboardConfig::applyConfig()
90 {
91   bool acceptSetting = false;
92   bool applyX11 = false;
93 
94   /* apply keyboard values */
95   if(delay != ui.keyboardDelay->value() || interval != ui.keyboardInterval->value())
96   {
97     delay = ui.keyboardDelay->value();
98     interval = ui.keyboardInterval->value();
99     XkbSetAutoRepeatRate(QX11Info::display(), XkbUseCoreKbd, delay, interval);
100     acceptSetting = true;
101   }
102 
103   if(beep != ui.keyboardBeep->isChecked())
104   {
105     beep = ui.keyboardBeep->isChecked();
106     XKeyboardControl values;
107     values.bell_percent = beep ? -1 : 0;
108     XChangeKeyboardControl(QX11Info::display(), KBBellPercent, &values);
109     acceptSetting = true;
110   }
111 
112   if(flashTime != ui.cursorFlashTime->value())
113   {
114     flashTime = ui.cursorFlashTime->value();
115     acceptSetting = applyX11 = true;
116   }
117 
118   if(numlock != ui.keyboardNumLock->isChecked())
119   {
120     numlock = ui.keyboardNumLock->isChecked();
121     acceptSetting = true;
122   }
123 
124   if(acceptSetting)
125     accept();
126 
127 #ifdef Q_WS_X11
128   if(applyX11)
129   {
130     qtSettings->sync();
131     qt_x11_apply_settings_in_all_apps();
132   }
133 #endif
134 }
135 
loadSettings()136 void KeyboardConfig::loadSettings() {
137   settings->beginGroup(QStringLiteral("Keyboard"));
138   oldDelay = delay = settings->value(QStringLiteral("delay"), 500).toInt();
139   oldInterval = interval = settings->value(QStringLiteral("interval"), 30).toInt();
140   oldBeep = beep = settings->value(QStringLiteral("beep"), true).toBool();
141   oldNumlock = numlock = settings->value(QStringLiteral("numlock"), false).toBool();
142   settings->endGroup();
143 
144   qtSettings->beginGroup(QLatin1String("Qt"));
145   oldFlashTime = flashTime = qtSettings->value(QLatin1String("cursorFlashTime"), 1000).toInt();
146   qtSettings->endGroup();
147 }
148 
accept()149 void KeyboardConfig::accept() {
150   settings->beginGroup(QStringLiteral("Keyboard"));
151   settings->setValue(QStringLiteral("delay"), delay);
152   settings->setValue(QStringLiteral("interval"), interval);
153   settings->setValue(QStringLiteral("beep"), beep);
154   settings->setValue(QStringLiteral("numlock"), numlock);
155   settings->endGroup();
156 
157   qtSettings->beginGroup(QLatin1String("Qt"));
158   qtSettings->setValue(QLatin1String("cursorFlashTime"), flashTime);
159   qtSettings->endGroup();
160 }
161 
reset()162 void KeyboardConfig::reset() {
163   /* restore to original settings */
164   /* keyboard */
165   delay = oldDelay;
166   interval = oldInterval;
167   beep = oldBeep;
168   numlock = oldNumlock;
169   flashTime = oldFlashTime;
170   XkbSetAutoRepeatRate(QX11Info::display(), XkbUseCoreKbd, delay, interval);
171   /* FIXME: beep? */
172 
173   initControls();
174   accept();
175 }
176