9
#include <kaudioplayer.h>
15
#include "kaccess.moc"
18
KAccessApp::KAccessApp(bool allowStyles, bool GUIenabled)
19
: KUniqueApplication(allowStyles, GUIenabled), _artsBellBlocked(false),
20
overlay(0), wm(0, KWinModule::INFO_DESKTOP)
22
// verify the Xlib has matching XKB extension
23
int major = XkbMajorVersion;
24
int minor = XkbMinorVersion;
25
if (!XkbLibraryVersion(&major, &minor))
27
kdError() << "Xlib XKB extension does not match" << endl;
30
kdDebug() << "Xlib XKB extension major=" << major << " minor=" << minor << endl;
32
// verify the X server has matching XKB extension
33
// if yes, the XKB extension is initialized
36
if (!XkbQueryExtension(qt_xdisplay(), &opcode_rtrn, &xkb_opcode, &error_rtrn,
39
kdError() << "X server has not matching XKB extension" << endl;
42
kdDebug() << "X server XKB extension major=" << major << " minor=" << minor << endl;
44
_activeWindow = wm.activeWindow();
45
connect(&wm, SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId)));
47
artsBellTimer = new QTimer( this );
48
connect( artsBellTimer, SIGNAL( timeout() ), SLOT( slotArtsBellTimeout() ));
51
int KAccessApp::newInstance()
53
KGlobal::config()->reparseConfiguration();
58
void KAccessApp::readSettings()
60
KConfig *config = KGlobal::config();
62
// bell ---------------------------------------------------------------
64
config->setGroup("Bell");
65
_systemBell = config->readBoolEntry("SystemBell", true);
66
_artsBell = config->readBoolEntry("ArtsBell", false);
67
_artsBellFile = config->readPathEntry("ArtsBellFile");
68
_visibleBell = config->readBoolEntry("VisibleBell", false);
69
_visibleBellInvert = config->readBoolEntry("VisibleBellInvert", false);
71
_visibleBellColor = config->readColorEntry("VisibleBellColor", &def);
72
_visibleBellPause = config->readNumEntry("VisibleBellPause", 500);
74
// select bell events if we need them
75
int state = (_artsBell || _visibleBell) ? XkbBellNotifyMask : 0;
76
XkbSelectEvents(qt_xdisplay(), XkbUseCoreKbd, XkbBellNotifyMask, state);
78
// deactivate system bell if not needed
80
XkbChangeEnabledControls(qt_xdisplay(), XkbUseCoreKbd, XkbAudibleBellMask, 0);
82
XkbChangeEnabledControls(qt_xdisplay(), XkbUseCoreKbd, XkbAudibleBellMask, XkbAudibleBellMask);
84
// keyboard -------------------------------------------------------------
86
config->setGroup("Keyboard");
89
XkbDescPtr xkb = XkbGetMap(qt_xdisplay(), 0, XkbUseCoreKbd);
92
if (XkbGetControls(qt_xdisplay(), XkbAllControlsMask, xkb) != Success)
96
if (config->readBoolEntry("StickyKeys", false))
98
if (config->readBoolEntry("StickyKeysLatch", true))
99
xkb->ctrls->ax_options |= XkbAX_LatchToLockMask;
101
xkb->ctrls->ax_options &= ~XkbAX_LatchToLockMask;
102
xkb->ctrls->enabled_ctrls |= XkbStickyKeysMask;
105
xkb->ctrls->enabled_ctrls &= ~XkbStickyKeysMask;
107
// turn off two-keys-disable sticky keys option
108
xkb->ctrls->ax_options &= ~XkbAX_TwoKeysMask;
111
xkb->ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask;
114
if (config->readBoolEntry("SlowKeys", false))
116
xkb->ctrls->slow_keys_delay = config->readNumEntry("SlowKeysDelay", 500);
117
xkb->ctrls->enabled_ctrls |= XkbSlowKeysMask;
120
xkb->ctrls->enabled_ctrls &= ~XkbSlowKeysMask;
123
if (config->readBoolEntry("BounceKeys", false))
125
xkb->ctrls->debounce_delay = config->readNumEntry("BounceKeysDelay", 500);
126
xkb->ctrls->enabled_ctrls |= XkbBounceKeysMask;
129
xkb->ctrls->enabled_ctrls &= ~XkbBounceKeysMask;
132
// mouse-by-keyboard ----------------------------------------------
134
config->setGroup("Mouse");
136
if (config->readBoolEntry("MouseKeys", false))
138
xkb->ctrls->mk_delay = config->readNumEntry("MKDelay", 160);
139
xkb->ctrls->mk_interval = config->readNumEntry("MKInterval", 5);
140
xkb->ctrls->mk_time_to_max = config->readNumEntry("MKTimeToMax", 1000);
141
xkb->ctrls->mk_max_speed = config->readNumEntry("MKMaxSpeed", 500);
142
xkb->ctrls->mk_curve = config->readNumEntry("MKCurve", 0);
143
xkb->ctrls->mk_dflt_btn = config->readNumEntry("MKDefaultButton", 0);
145
xkb->ctrls->enabled_ctrls |= XkbMouseKeysMask;
148
xkb->ctrls->enabled_ctrls &= ~XkbMouseKeysMask;
151
XkbSetControls(qt_xdisplay(), XkbControlsEnabledMask | XkbMouseKeysAccelMask | XkbStickyKeysMask, xkb);
153
// reset them after program exit
154
uint ctrls = XkbStickyKeysMask | XkbSlowKeysMask | XkbBounceKeysMask | XkbMouseKeysMask | XkbAudibleBellMask;
155
uint values = XkbAudibleBellMask;
156
XkbSetAutoResetControls(qt_xdisplay(), ctrls, &ctrls, &values);
163
bool KAccessApp::x11EventFilter(XEvent *event)
166
if (event->type == xkb_opcode)
168
XkbAnyEvent *ev = (XkbAnyEvent*) event;
170
if (ev->xkb_type == XkbBellNotify)
171
xkbBellNotify((XkbBellNotifyEvent*)event);
176
// process other events as usual
177
return KApplication::x11EventFilter(event);
181
void VisualBell::paintEvent(QPaintEvent *event)
183
QWidget::paintEvent(event);
184
QTimer::singleShot(_pause, this, SLOT(hide()));
188
void KAccessApp::activeWindowChanged(WId wid)
194
void KAccessApp::xkbBellNotify(XkbBellNotifyEvent *event)
196
// bail out if we should not really ring
197
if (event->event_only)
200
// flash the visible bell
203
// create overlay widget
205
overlay = new VisualBell(_visibleBellPause);
207
WId id = _activeWindow;
209
NETRect frame, window;
210
NETWinInfo net(qt_xdisplay(), id, desktop()->winId(), 0);
212
net.kdeGeometry(frame, window);
214
overlay->setGeometry(window.pos.x, window.pos.y, window.size.width, window.size.height);
216
if (_visibleBellInvert)
218
QPixmap screen = QPixmap::grabWindow(id, 0, 0, window.size.width, window.size.height);
219
QPixmap invert(window.size.width, window.size.height);
221
p.setRasterOp(QPainter::NotCopyROP);
222
p.drawPixmap(0, 0, screen);
223
overlay->setBackgroundPixmap(invert);
226
overlay->setBackgroundColor(_visibleBellColor);
228
// flash the overlay widget
234
// ask artsd to ring a nice bell
235
if (_artsBell && !_artsBellBlocked ) {
236
KAudioPlayer::play(_artsBellFile);
237
_artsBellBlocked = true;
238
artsBellTimer->start( 300, true );
242
void KAccessApp::slotArtsBellTimeout()
244
_artsBellBlocked = false;