Changeset View
Changeset View
Standalone View
Standalone View
kcms/input/mouse.cpp
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | |||||
60 | #include <kstandarddirs.h> | 60 | #include <kstandarddirs.h> | ||
61 | #include <kaboutdata.h> | 61 | #include <kaboutdata.h> | ||
62 | #include <KPluginFactory> | 62 | #include <KPluginFactory> | ||
63 | #include <KPluginLoader> | 63 | #include <KPluginLoader> | ||
64 | 64 | | |||
65 | #include <config-workspace.h> | 65 | #include <config-workspace.h> | ||
66 | 66 | | |||
67 | #include "mouse.h" | 67 | #include "mouse.h" | ||
68 | #include "mousebackend.h" | ||||
69 | #include "mousesettings.h" | ||||
68 | 70 | | |||
69 | #include <X11/X.h> | | |||
70 | #include <X11/Xlib.h> | | |||
71 | #include <X11/Xatom.h> | | |||
72 | #include <X11/extensions/XInput2.h> | | |||
73 | #include <X11/Xutil.h> | | |||
74 | #include <kglobalsettings.h> | 71 | #include <kglobalsettings.h> | ||
75 | #include <QX11Info> | | |||
76 | #include <evdev-properties.h> | | |||
77 | 72 | | |||
78 | #undef Below | 73 | #undef Below | ||
79 | 74 | | |||
80 | #include "../migrationlib/kdelibs4config.h" | 75 | #include "../migrationlib/kdelibs4config.h" | ||
81 | 76 | | |||
82 | K_PLUGIN_FACTORY(MouseConfigFactory, | 77 | K_PLUGIN_FACTORY(MouseConfigFactory, | ||
83 | registerPlugin<MouseConfig>(); // mouse | 78 | registerPlugin<MouseConfig>(); // mouse | ||
84 | ) | 79 | ) | ||
85 | K_EXPORT_PLUGIN(MouseConfigFactory("kcminput")) | | |||
86 | 80 | | |||
87 | MouseConfig::MouseConfig(QWidget *parent, const QVariantList &args) | 81 | MouseConfig::MouseConfig(QWidget *parent, const QVariantList &args) | ||
88 | : KCModule(parent, args) | 82 | : KCModule(parent, args), | ||
83 | backend(MouseBackend::implementation()) | ||||
romangg: Break into two lines. | |||||
89 | { | 84 | { | ||
90 | setupUi(this); | 85 | setupUi(this); | ||
91 | 86 | | |||
92 | handedGroup->setId(rightHanded, 0); | 87 | handedGroup->setId(rightHanded, static_cast<int>(MouseHanded::Right)); | ||
93 | handedGroup->setId(leftHanded, 1); | 88 | handedGroup->setId(leftHanded, static_cast<int>(MouseHanded::Left)); | ||
94 | 89 | | |||
95 | connect(handedGroup, SIGNAL(buttonClicked(int)), this, SLOT(changed())); | 90 | connect(handedGroup, SIGNAL(buttonClicked(int)), this, SLOT(changed())); | ||
96 | connect(handedGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotHandedChanged(int))); | 91 | connect(handedGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotHandedChanged(int))); | ||
97 | connect(doubleClick, SIGNAL(clicked()), SLOT(changed())); | 92 | connect(doubleClick, SIGNAL(clicked()), SLOT(changed())); | ||
98 | connect(singleClick, SIGNAL(clicked()), this, SLOT(changed())); | | |||
99 | 93 | | |||
100 | // Only allow setting reversing scroll polarity if we have scroll buttons | 94 | connect(singleClick, SIGNAL(clicked()), this, SLOT(changed())); | ||
101 | unsigned char map[20]; | | |||
102 | if (QX11Info::isPlatformX11() && XGetPointerMapping(QX11Info::display(), map, 20) >= 5) | | |||
103 | { | | |||
104 | cbScrollPolarity->setEnabled(true); | | |||
105 | cbScrollPolarity->show(); | | |||
106 | } | | |||
107 | else | | |||
108 | { | | |||
109 | cbScrollPolarity->setEnabled(false); | | |||
110 | cbScrollPolarity->hide(); | | |||
111 | } | | |||
112 | connect(cbScrollPolarity, SIGNAL(clicked()), this, SLOT(changed())); | 95 | connect(cbScrollPolarity, SIGNAL(clicked()), this, SLOT(changed())); | ||
113 | connect(cbScrollPolarity, SIGNAL(clicked()), this, SLOT(slotScrollPolarityChanged())); | 96 | connect(cbScrollPolarity, SIGNAL(clicked()), this, SLOT(slotScrollPolarityChanged())); | ||
114 | 97 | | |||
115 | connect(accel, SIGNAL(valueChanged(double)), this, SLOT(changed())); | 98 | connect(accel, SIGNAL(valueChanged(double)), this, SLOT(changed())); | ||
116 | connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(changed())); | 99 | connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(changed())); | ||
117 | connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(slotThreshChanged(int))); | 100 | connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(slotThreshChanged(int))); | ||
118 | slotThreshChanged(thresh->value()); | 101 | slotThreshChanged(thresh->value()); | ||
119 | 102 | | |||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Line(s) | |||||
187 | } | 170 | } | ||
188 | 171 | | |||
189 | void MouseConfig::setThreshold(int val) | 172 | void MouseConfig::setThreshold(int val) | ||
190 | { | 173 | { | ||
191 | thresh->setValue(val); | 174 | thresh->setValue(val); | ||
192 | } | 175 | } | ||
193 | 176 | | |||
194 | 177 | | |||
195 | int MouseConfig::getHandedness() | 178 | MouseHanded MouseConfig::getHandedness() | ||
196 | { | 179 | { | ||
197 | if (rightHanded->isChecked()) | 180 | if (rightHanded->isChecked()) | ||
198 | return RIGHT_HANDED; | 181 | return MouseHanded::Right; | ||
199 | else | 182 | else | ||
200 | return LEFT_HANDED; | 183 | return MouseHanded::Left; | ||
201 | } | 184 | } | ||
202 | 185 | | |||
203 | void MouseConfig::setHandedness(int val) | 186 | void MouseConfig::setHandedness(MouseHanded val) | ||
204 | { | 187 | { | ||
205 | rightHanded->setChecked(false); | 188 | rightHanded->setChecked(false); | ||
206 | leftHanded->setChecked(false); | 189 | leftHanded->setChecked(false); | ||
207 | if (val == RIGHT_HANDED) { | 190 | if (val == MouseHanded::Right) { | ||
208 | rightHanded->setChecked(true); | 191 | rightHanded->setChecked(true); | ||
209 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); | 192 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); | ||
210 | } | 193 | } | ||
211 | else { | 194 | else { | ||
212 | leftHanded->setChecked(true); | 195 | leftHanded->setChecked(true); | ||
213 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); | 196 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); | ||
214 | } | 197 | } | ||
215 | settings->m_handedNeedsApply = true; | 198 | settings->handedNeedsApply = true; | ||
216 | } | 199 | } | ||
217 | 200 | | |||
218 | void MouseConfig::load() | 201 | void MouseConfig::load() | ||
219 | { | 202 | { | ||
220 | KConfig config("kcminputrc"); | 203 | KConfig config("kcminputrc"); | ||
221 | settings->load(&config); | 204 | settings->load(&config, backend); | ||
205 | | ||||
206 | // settings->load will trigger backend->load so information will be avaialbe | ||||
207 | // here. | ||||
208 | // Only allow setting reversing scroll polarity if we have scroll buttons | ||||
209 | if (backend) { | ||||
210 | if (backend->supportScrollPolarity()) | ||||
211 | { | ||||
212 | cbScrollPolarity->setEnabled(true); | ||||
213 | cbScrollPolarity->show(); | ||||
214 | } | ||||
215 | else | ||||
216 | { | ||||
217 | cbScrollPolarity->setEnabled(false); | ||||
218 | cbScrollPolarity->hide(); | ||||
219 | } | ||||
220 | } | ||||
222 | 221 | | |||
223 | rightHanded->setEnabled(settings->handedEnabled); | 222 | rightHanded->setEnabled(settings->handedEnabled); | ||
224 | leftHanded->setEnabled(settings->handedEnabled); | 223 | leftHanded->setEnabled(settings->handedEnabled); | ||
225 | if (cbScrollPolarity->isEnabled()) | 224 | if (cbScrollPolarity->isEnabled()) | ||
226 | cbScrollPolarity->setEnabled(settings->handedEnabled); | 225 | cbScrollPolarity->setEnabled(settings->handedEnabled); | ||
227 | cbScrollPolarity->setChecked(settings->reverseScrollPolarity); | 226 | cbScrollPolarity->setChecked(settings->reverseScrollPolarity); | ||
228 | 227 | | |||
229 | setAccel(settings->accelRate); | 228 | setAccel(settings->accelRate); | ||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | 271 | { | |||
276 | 275 | | |||
277 | settings->doubleClickInterval = doubleClickInterval->value(); | 276 | settings->doubleClickInterval = doubleClickInterval->value(); | ||
278 | settings->dragStartTime = dragStartTime->value(); | 277 | settings->dragStartTime = dragStartTime->value(); | ||
279 | settings->dragStartDist = dragStartDist->value(); | 278 | settings->dragStartDist = dragStartDist->value(); | ||
280 | settings->wheelScrollLines = wheelScrollLines->value(); | 279 | settings->wheelScrollLines = wheelScrollLines->value(); | ||
281 | settings->singleClick = !doubleClick->isChecked(); | 280 | settings->singleClick = !doubleClick->isChecked(); | ||
282 | settings->reverseScrollPolarity = cbScrollPolarity->isChecked(); | 281 | settings->reverseScrollPolarity = cbScrollPolarity->isChecked(); | ||
283 | 282 | | |||
284 | settings->apply(); | 283 | settings->apply(backend); | ||
285 | KConfig config("kcminputrc"); | 284 | KConfig config("kcminputrc"); | ||
286 | settings->save(&config); | 285 | settings->save(&config); | ||
287 | 286 | | |||
288 | KConfig ac("kaccessrc"); | 287 | KConfig ac("kaccessrc"); | ||
289 | 288 | | |||
290 | KConfigGroup group = ac.group("Mouse"); | 289 | KConfigGroup group = ac.group("Mouse"); | ||
291 | 290 | | |||
292 | int interval = mk_interval->value(); | 291 | int interval = mk_interval->value(); | ||
Show All 12 Lines | |||||
305 | 304 | | |||
306 | emit changed(false); | 305 | emit changed(false); | ||
307 | } | 306 | } | ||
308 | 307 | | |||
309 | void MouseConfig::defaults() | 308 | void MouseConfig::defaults() | ||
310 | { | 309 | { | ||
311 | setThreshold(2); | 310 | setThreshold(2); | ||
312 | setAccel(2); | 311 | setAccel(2); | ||
313 | setHandedness(RIGHT_HANDED); | 312 | setHandedness(MouseHanded::Right); | ||
314 | cbScrollPolarity->setChecked(false); | 313 | cbScrollPolarity->setChecked(false); | ||
315 | doubleClickInterval->setValue(400); | 314 | doubleClickInterval->setValue(400); | ||
316 | dragStartTime->setValue(500); | 315 | dragStartTime->setValue(500); | ||
317 | dragStartDist->setValue(4); | 316 | dragStartDist->setValue(4); | ||
318 | wheelScrollLines->setValue(3); | 317 | wheelScrollLines->setValue(3); | ||
319 | doubleClick->setChecked(!KDE_DEFAULT_SINGLECLICK); | 318 | doubleClick->setChecked(!KDE_DEFAULT_SINGLECLICK); | ||
320 | singleClick->setChecked(KDE_DEFAULT_SINGLECLICK); | 319 | singleClick->setChecked(KDE_DEFAULT_SINGLECLICK); | ||
321 | 320 | | |||
322 | mouseKeys->setChecked(false); | 321 | mouseKeys->setChecked(false); | ||
323 | mk_delay->setValue(160); | 322 | mk_delay->setValue(160); | ||
324 | mk_interval->setValue(5); | 323 | mk_interval->setValue(5); | ||
325 | mk_time_to_max->setValue(5000); | 324 | mk_time_to_max->setValue(5000); | ||
326 | mk_max_speed->setValue(1000); | 325 | mk_max_speed->setValue(1000); | ||
327 | mk_curve->setValue(0); | 326 | mk_curve->setValue(0); | ||
328 | 327 | | |||
329 | checkAccess(); | 328 | checkAccess(); | ||
330 | changed(); | 329 | changed(); | ||
331 | } | 330 | } | ||
332 | 331 | | |||
333 | /** No descriptions */ | 332 | /** No descriptions */ | ||
334 | void MouseConfig::slotHandedChanged(int val) | 333 | void MouseConfig::slotHandedChanged(int val) | ||
335 | { | 334 | { | ||
336 | if (val==RIGHT_HANDED) | 335 | if (val == static_cast<int>(MouseHanded::Right)) | ||
337 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); | 336 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); | ||
338 | else | 337 | else | ||
339 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); | 338 | mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); | ||
340 | settings->m_handedNeedsApply = true; | 339 | settings->handedNeedsApply = true; | ||
341 | } | | |||
342 | | ||||
343 | void MouseSettings::load(KConfig *config, Display *dpy) | | |||
344 | { | | |||
345 | // TODO: what's a good threshold default value | | |||
346 | int threshold = 0; | | |||
347 | int h = RIGHT_HANDED; | | |||
348 | double accel = 1.0; | | |||
349 | if (QX11Info::isPlatformX11()) { | | |||
350 | int accel_num, accel_den; | | |||
351 | | ||||
352 | XGetPointerControl(dpy, &accel_num, &accel_den, &threshold); | | |||
353 | accel = float(accel_num) / float(accel_den); | | |||
354 | | ||||
355 | // get settings from X server | | |||
356 | unsigned char map[20]; | | |||
357 | num_buttons = XGetPointerMapping(dpy, map, 20); | | |||
358 | | ||||
359 | handedEnabled = true; | | |||
360 | | ||||
361 | // ## keep this in sync with KGlobalSettings::mouseSettings | | |||
362 | if (num_buttons == 1) | | |||
363 | { | | |||
364 | /* disable button remapping */ | | |||
365 | handedEnabled = false; | | |||
366 | } | | |||
367 | else if (num_buttons == 2) | | |||
368 | { | | |||
369 | if ((int)map[0] == 1 && (int)map[1] == 2) | | |||
370 | h = RIGHT_HANDED; | | |||
371 | else if ((int)map[0] == 2 && (int)map[1] == 1) | | |||
372 | h = LEFT_HANDED; | | |||
373 | else | | |||
374 | /* custom button setup: disable button remapping */ | | |||
375 | handedEnabled = false; | | |||
376 | } | | |||
377 | else | | |||
378 | { | | |||
379 | middle_button = (int)map[1]; | | |||
380 | if ((int)map[0] == 1 && (int)map[2] == 3) | | |||
381 | h = RIGHT_HANDED; | | |||
382 | else if ((int)map[0] == 3 && (int)map[2] == 1) | | |||
383 | h = LEFT_HANDED; | | |||
384 | else | | |||
385 | { | | |||
386 | /* custom button setup: disable button remapping */ | | |||
387 | handedEnabled = false; | | |||
388 | } | | |||
389 | } | | |||
390 | } else { | | |||
391 | // other platforms | | |||
392 | handedEnabled = true; | | |||
393 | } | | |||
394 | | ||||
395 | KConfigGroup group = config->group("Mouse"); | | |||
396 | double a = group.readEntry("Acceleration", -1.0); | | |||
397 | if (a == -1) | | |||
398 | accelRate = accel; | | |||
399 | else | | |||
400 | accelRate = a; | | |||
401 | | ||||
402 | int t = group.readEntry("Threshold", -1); | | |||
403 | if (t == -1) | | |||
404 | thresholdMove = threshold; | | |||
405 | else | | |||
406 | thresholdMove = t; | | |||
407 | | ||||
408 | QString key = group.readEntry("MouseButtonMapping"); | | |||
409 | if (key == "RightHanded") | | |||
410 | handed = RIGHT_HANDED; | | |||
411 | else if (key == "LeftHanded") | | |||
412 | handed = LEFT_HANDED; | | |||
413 | #ifdef __GNUC__ | | |||
414 | #warning was key == NULL how was this working? is key.isNull() what the coder meant? | | |||
415 | #endif | | |||
416 | else if (key.isNull()) | | |||
417 | handed = h; | | |||
418 | reverseScrollPolarity = group.readEntry("ReverseScrollPolarity", false); | | |||
419 | m_handedNeedsApply = false; | | |||
420 | | ||||
421 | // SC/DC/AutoSelect/ChangeCursor | | |||
422 | group = config->group("KDE"); | | |||
423 | doubleClickInterval = group.readEntry("DoubleClickInterval", 400); | | |||
424 | dragStartTime = group.readEntry("StartDragTime", 500); | | |||
425 | dragStartDist = group.readEntry("StartDragDist", 4); | | |||
426 | wheelScrollLines = group.readEntry("WheelScrollLines", 3); | | |||
427 | | ||||
428 | singleClick = group.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK); | | |||
429 | } | 340 | } | ||
430 | 341 | | |||
431 | void MouseConfig::slotThreshChanged(int value) | 342 | void MouseConfig::slotThreshChanged(int value) | ||
432 | { | 343 | { | ||
433 | thresh->setSuffix(i18np(" pixel", " pixels", value)); | 344 | thresh->setSuffix(i18np(" pixel", " pixels", value)); | ||
434 | } | 345 | } | ||
435 | 346 | | |||
436 | void MouseConfig::slotDragStartDistChanged(int value) | 347 | void MouseConfig::slotDragStartDistChanged(int value) | ||
437 | { | 348 | { | ||
438 | dragStartDist->setSuffix(i18np(" pixel", " pixels", value)); | 349 | dragStartDist->setSuffix(i18np(" pixel", " pixels", value)); | ||
439 | } | 350 | } | ||
440 | 351 | | |||
441 | void MouseConfig::slotWheelScrollLinesChanged(int value) | 352 | void MouseConfig::slotWheelScrollLinesChanged(int value) | ||
442 | { | 353 | { | ||
443 | wheelScrollLines->setSuffix(i18np(" line", " lines", value)); | 354 | wheelScrollLines->setSuffix(i18np(" line", " lines", value)); | ||
444 | } | 355 | } | ||
445 | 356 | | |||
446 | void MouseSettings::apply(bool force) | | |||
447 | { | | |||
448 | if (!QX11Info::isPlatformX11()) { | | |||
449 | return; | | |||
450 | } | | |||
451 | XChangePointerControl(QX11Info::display(), | | |||
452 | true, true, int(qRound(accelRate*10)), 10, thresholdMove); | | |||
453 | | ||||
454 | // 256 might seems extreme, but X has already been known to return 32, | | |||
455 | // and we don't want to truncate things. Xlib limits the table to 256 bytes, | | |||
456 | // so it's a good upper bound.. | | |||
457 | unsigned char map[256]; | | |||
458 | num_buttons = XGetPointerMapping(QX11Info::display(), map, 256); | | |||
459 | | ||||
460 | int remap=(num_buttons>=1); | | |||
461 | if (handedEnabled && (m_handedNeedsApply || force)) { | | |||
462 | if (num_buttons == 1) | | |||
463 | { | | |||
464 | map[0] = (unsigned char) 1; | | |||
465 | } | | |||
466 | else if (num_buttons == 2) | | |||
467 | { | | |||
468 | if (handed == RIGHT_HANDED) | | |||
469 | { | | |||
470 | map[0] = (unsigned char) 1; | | |||
471 | map[1] = (unsigned char) 3; | | |||
472 | } | | |||
473 | else | | |||
474 | { | | |||
475 | map[0] = (unsigned char) 3; | | |||
476 | map[1] = (unsigned char) 1; | | |||
477 | } | | |||
478 | } | | |||
479 | else // 3 buttons and more | | |||
480 | { | | |||
481 | if (handed == RIGHT_HANDED) | | |||
482 | { | | |||
483 | map[0] = (unsigned char) 1; | | |||
484 | map[1] = (unsigned char) middle_button; | | |||
485 | map[2] = (unsigned char) 3; | | |||
486 | } | | |||
487 | else | | |||
488 | { | | |||
489 | map[0] = (unsigned char) 3; | | |||
490 | map[1] = (unsigned char) middle_button; | | |||
491 | map[2] = (unsigned char) 1; | | |||
492 | } | | |||
493 | } | | |||
494 | | ||||
495 | int retval; | | |||
496 | if (remap) { | | |||
497 | while ((retval=XSetPointerMapping(QX11Info::display(), map, | | |||
498 | num_buttons)) == MappingBusy) | | |||
499 | /* keep trying until the pointer is free */ | | |||
500 | { }; | | |||
501 | } | | |||
502 | | ||||
503 | // apply reverseScrollPolarity | | |||
504 | Display *dpy = QX11Info::display(); | | |||
505 | Atom prop_wheel_emulation = XInternAtom(dpy, EVDEV_PROP_WHEEL, True); | | |||
506 | Atom prop_scroll_distance = XInternAtom(dpy, EVDEV_PROP_SCROLL_DISTANCE, True); | | |||
507 | Atom prop_wheel_emulation_axes = XInternAtom(dpy, EVDEV_PROP_WHEEL_AXES, True); | | |||
508 | int ndevices_return; | | |||
509 | XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices_return); | | |||
510 | if (!info) { | | |||
511 | return; | | |||
512 | } | | |||
513 | for (int i = 0; i < ndevices_return; ++i) { | | |||
514 | if ((info + i)->use == XISlavePointer) { | | |||
515 | int deviceid = (info + i)->deviceid; | | |||
516 | Status status; | | |||
517 | Atom type_return; | | |||
518 | int format_return; | | |||
519 | unsigned long num_items_return; | | |||
520 | unsigned long bytes_after_return; | | |||
521 | | ||||
522 | unsigned char *data = nullptr; | | |||
523 | unsigned char *data2 = nullptr; | | |||
524 | //data returned is an 1 byte boolean | | |||
525 | status = XIGetProperty(dpy, deviceid, prop_wheel_emulation, 0, 1, | | |||
526 | False, XA_INTEGER, &type_return, &format_return, | | |||
527 | &num_items_return, &bytes_after_return, &data); | | |||
528 | if (status != Success) { | | |||
529 | continue; | | |||
530 | } | | |||
531 | | ||||
532 | // pointer device without wheel emulation | | |||
533 | if (type_return != XA_INTEGER || data == NULL || *data == False) { | | |||
534 | status = XIGetProperty(dpy, deviceid, prop_scroll_distance, 0, 3, | | |||
535 | False, XA_INTEGER, &type_return, &format_return, | | |||
536 | &num_items_return, &bytes_after_return, &data2); | | |||
537 | // negate scroll distance | | |||
538 | if (status == Success && type_return == XA_INTEGER && | | |||
539 | format_return == 32 && num_items_return == 3) { | | |||
540 | int32_t *vals = (int32_t*)data2; | | |||
541 | for (unsigned long i=0; i<num_items_return; ++i) { | | |||
542 | int32_t val = *(vals+i); | | |||
543 | *(vals+i) = (int32_t) (reverseScrollPolarity ? -abs(val) : abs(val)); | | |||
544 | } | | |||
545 | XIChangeProperty(dpy, deviceid, prop_scroll_distance, XA_INTEGER, | | |||
546 | 32, XIPropModeReplace, data2, 3); | | |||
547 | } | | |||
548 | } else { // wheel emulation used, reverse wheel axes | | |||
549 | status = XIGetProperty(dpy, deviceid, prop_wheel_emulation_axes, 0, 4, | | |||
550 | False, XA_INTEGER, &type_return, &format_return, | | |||
551 | &num_items_return, &bytes_after_return, &data2); | | |||
552 | if (status == Success && type_return == XA_INTEGER && | | |||
553 | format_return == 8 && num_items_return == 4) { | | |||
554 | // when scroll direction is not reversed, | | |||
555 | // up button id should be smaller than down button id, | | |||
556 | // up/left are odd elements, down/right are even elements | | |||
557 | for (int i=0; i<2; ++i) { | | |||
558 | unsigned char odd = *(data2 + i*2); | | |||
559 | unsigned char even = *(data2 + i*2+1); | | |||
560 | unsigned char max_elem = std::max(odd, even); | | |||
561 | unsigned char min_elem = std::min(odd, even); | | |||
562 | *(data2 + i * 2) = reverseScrollPolarity ? max_elem : min_elem; | | |||
563 | *(data2 + i * 2 + 1) = reverseScrollPolarity ? min_elem : max_elem; | | |||
564 | } | | |||
565 | XIChangeProperty(dpy, deviceid, prop_wheel_emulation_axes, XA_INTEGER, | | |||
566 | 8, XIPropModeReplace, data2, 4); | | |||
567 | } | | |||
568 | } | | |||
569 | | ||||
570 | if (data != NULL) { XFree(data); } | | |||
571 | if (data2 != NULL) { XFree(data2); } | | |||
572 | } | | |||
573 | } | | |||
574 | XIFreeDeviceInfo(info); | | |||
575 | m_handedNeedsApply = false; | | |||
576 | } | | |||
577 | } | | |||
578 | | ||||
579 | void MouseSettings::save(KConfig *config) | | |||
580 | { | | |||
581 | KSharedConfig::Ptr kcminputProfile = KSharedConfig::openConfig("kcminputrc"); | | |||
582 | KConfigGroup kcminputGroup(kcminputProfile, "Mouse"); | | |||
583 | kcminputGroup.writeEntry("Acceleration",accelRate); | | |||
584 | kcminputGroup.writeEntry("Threshold",thresholdMove); | | |||
585 | if (handed == RIGHT_HANDED) | | |||
586 | kcminputGroup.writeEntry("MouseButtonMapping",QString("RightHanded")); | | |||
587 | else | | |||
588 | kcminputGroup.writeEntry("MouseButtonMapping",QString("LeftHanded")); | | |||
589 | kcminputGroup.writeEntry("ReverseScrollPolarity", reverseScrollPolarity); | | |||
590 | kcminputGroup.sync(); | | |||
591 | | ||||
592 | KSharedConfig::Ptr profile = KSharedConfig::openConfig("kdeglobals"); | | |||
593 | KConfigGroup group(profile, "KDE"); | | |||
594 | group.writeEntry("DoubleClickInterval", doubleClickInterval, KConfig::Persistent); | | |||
595 | group.writeEntry("StartDragTime", dragStartTime, KConfig::Persistent); | | |||
596 | group.writeEntry("StartDragDist", dragStartDist, KConfig::Persistent); | | |||
597 | group.writeEntry("WheelScrollLines", wheelScrollLines, KConfig::Persistent); | | |||
598 | group.writeEntry("SingleClick", singleClick, KConfig::Persistent); | | |||
599 | | ||||
600 | group.sync(); | | |||
601 | config->sync(); | | |||
602 | | ||||
603 | Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("Mouse"), "kcminputrc"); | | |||
604 | Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("KDE"), "kdeglobals"); | | |||
605 | | ||||
606 | KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_MOUSE); | | |||
607 | } | | |||
608 | | ||||
609 | void MouseConfig::slotScrollPolarityChanged() | 357 | void MouseConfig::slotScrollPolarityChanged() | ||
610 | { | 358 | { | ||
611 | settings->m_handedNeedsApply = true; | 359 | settings->handedNeedsApply = true; | ||
612 | } | 360 | } | ||
613 | 361 | | |||
614 | #include "mouse.moc" | 362 | #include "mouse.moc" |
Break into two lines.