bool Tohkbd::checkKeypadPresence() { bool __prev_keypadPresence = keypadIsPresent; if (!vddEnabled) { /* keyboard is being connected to base */ /* TODO: how to detect keyboard is removed ??? */ printf("Presence detected, turning power on\n"); QThread::msleep(150); setVddState(true); QThread::msleep(150); tca8424->reset(); QThread::msleep(150); } if (!tca8424->testComms()) { printf("keypad not present, turning power off\n"); setVddState(false); if (keypadIsPresent) { keyboardConnectedNotification(false); presenceTimer->stop(); handleKeyReleased(); } keypadIsPresent = false; } else { if (!keypadIsPresent) { keyboardConnectedNotification(true); tca8424->setLeds((keymap->ctrlPressed ? LED_SYMLOCK_ON : LED_SYMLOCK_OFF) | ((capsLockSeq == 3) ? LED_CAPSLOCK_ON : LED_CAPSLOCK_OFF)); presenceTimer->start(); checkEEPROM(); } keypadIsPresent = true; } if (__prev_keypadPresence != keypadIsPresent) { emit keyboardConnectedChanged(keypadIsPresent); emitKeypadSlideEvent(keypadIsPresent); vkbLayoutIsTohkbd = keypadIsPresent; changeActiveLayout(); if (forceLandscapeOrientation) changeOrientationLock(); } return keypadIsPresent; }
/* Key press handler. Called from keymap->process() if actual key was pressed */ void Tohkbd::handleKeyPressed(QList< QPair<int, int> > keyCode) { bool processAllKeys = true; presenceTimer->start(); if (!displayIsOn && !slideEventEmitted) { emitKeypadSlideEvent(true); /* slideEventEmitted is used to limit events to just one * emitted once when key pressed while display is off * it is reset when display turns on. */ slideEventEmitted = true; } if ((capsLockSeq == 1 || capsLockSeq == 2)) /* Abort caps-lock if other key pressed */ capsLockSeq = 0; checkDoWeNeedBacklight(); /* alt+TAB is the task-switcher */ if (keymap->altPressed && keyCode.at(0).first == KEY_TAB) { if (!taskSwitcherVisible) { /* show taskswitcher and advance one app */ taskSwitcherVisible = true; tohkbd2user->call(QDBus::AutoDetect, "nextAppTaskSwitcher"); tohkbd2user->call(QDBus::AutoDetect, "showTaskSwitcher"); } else { /* Toggle to next app */ tohkbd2user->call(QDBus::AutoDetect, "nextAppTaskSwitcher"); } /* Don't process further */ keyIsPressed = true; return; } /* Alt-p takes a screenshot */ if (keymap->altPressed && keyCode.at(0).first == KEY_P) { screenShot(); /* Don't process further */ keyIsPressed = true; return; } /* if F1...F12 key is pressed then launch detached process */ if (FKEYS.contains(keyCode.at(0).first)) { QString cmd = applicationShortcuts[keyCode.at(0).first]; if (!cmd.isEmpty()) { printf("Requesting user daemon to start %s\n", qPrintable(cmd)); QList<QVariant> args; args.append(cmd); tohkbd2user->callWithArgumentList(QDBus::AutoDetect, "launchApplication", args); /* Don't process further */ keyIsPressed = true; return; } } if (processAllKeys) { for (int i=0; i<keyCode.count(); i++) { /* Some of the keys require shift pressed to get correct symbol */ if (keyCode.at(i).second & FORCE_COMPOSE) uinputif->sendUinputKeyPress(KEY_COMPOSE, 1); if ((keyCode.at(i).second & FORCE_RIGHTALT)) uinputif->sendUinputKeyPress(KEY_RIGHTALT, 1); if ((keyCode.at(i).second & FORCE_SHIFT) || keymap->shiftPressed) uinputif->sendUinputKeyPress(KEY_LEFTSHIFT, 1); if ((keyCode.at(i).second & FORCE_ALT) || keymap->altPressed) uinputif->sendUinputKeyPress(KEY_LEFTALT, 1); if ((keyCode.at(i).second & FORCE_CTRL) || keymap->ctrlPressed) uinputif->sendUinputKeyPress(KEY_LEFTCTRL, 1); /* Mimic key pressing */ uinputif->sendUinputKeyPress(keyCode.at(i).first, 1); QThread::msleep(KEYREPEAT_RATE); uinputif->sendUinputKeyPress(keyCode.at(i).first, 0); if ((keyCode.at(i).second & FORCE_CTRL) || keymap->ctrlPressed) uinputif->sendUinputKeyPress(KEY_LEFTCTRL, 0); if ((keyCode.at(i).second & FORCE_ALT) || keymap->altPressed) uinputif->sendUinputKeyPress(KEY_LEFTALT, 0); if ((keyCode.at(i).second & FORCE_SHIFT) || keymap->shiftPressed) uinputif->sendUinputKeyPress(KEY_LEFTSHIFT, 0); if ((keyCode.at(i).second & FORCE_RIGHTALT)) uinputif->sendUinputKeyPress(KEY_RIGHTALT, 0); if (keyCode.at(i).second & FORCE_COMPOSE) uinputif->sendUinputKeyPress(KEY_COMPOSE, 0); } } uinputif->synUinputDevice(); /* store keycode for repeat */ lastKeyCode = keyCode; /* Repeat delay first, then repeat rate */ repeatTimer->start(keyRepeat ? (keyRepeatRate-(KEYREPEAT_RATE-1)) : keyRepeatDelay); keyIsPressed = true; }
/* Key press handler. Called from keymap->process() if actual key was pressed */ void Tohkbd::handleKeyPressed(QList< QPair<int, int> > keyCode) { bool processAllKeys = true; /* No need to do this all if we are repeating */ if (!keyRepeat) { if (!displayIsOn && !slideEventEmitted) { emitKeypadSlideEvent(true); /* slideEventEmitted is used to limit events to just one * emitted once when key pressed while display is off * it is reset when display turns on. */ slideEventEmitted = true; } checkDoWeNeedBacklight(); /* alt+TAB is the task-switcher */ if (keymap->alt->pressed && keyCode.at(0).first == KEY_TAB) { if (!taskSwitcherVisible) { /* show taskswitcher and advance one app */ taskSwitcherVisible = true; tohkbd2user->nextAppTaskSwitcher(); tohkbd2user->showTaskSwitcher(); } else { /* Toggle to next app */ tohkbd2user->nextAppTaskSwitcher(); } /* Don't process further */ keyIsPressed = true; return; } /* Check custom key mappings */ if (keyCode.at(0).first > KEY_MAX) { switch (keyCode.at(0).first) { /* Sym-Int takes a screenshot */ case KEY_TOH_SCREENSHOT: tohkbd2user->takeScreenShot(); break; /* Sym-Del toggles "selfie" led */ case KEY_TOH_SELFIE: selfieLedOn = !selfieLedOn; tca8424->setLeds(selfieLedOn ? LED_SELFIE_ON : LED_SELFIE_OFF); break; case KEY_TOH_BACKLIGHT: forceBacklightOn = !forceBacklightOn; checkDoWeNeedBacklight(); break; case KEY_TOH_NEWEMAIL: { QDBusMessage m = QDBusMessage::createMethodCall("com.jolla.email.ui", "/com/jolla/email/ui", "", "mailto" ); QList<QVariant> args; args.append(QStringList() << "mailto:"); m.setArguments(args); QDBusConnection::sessionBus().send(m); } break; default: break; } /* Don't process further */ keyIsPressed = true; return; } /* if F1...F12 key is pressed then launch detached process */ if (FKEYS.contains(keyCode.at(0).first)) { QString cmd = applicationShortcuts[keyCode.at(0).first]; if (!cmd.isEmpty()) { printf("Requesting user daemon to start %s\n", qPrintable(cmd)); tohkbd2user->launchApplication(cmd); /* Don't process further */ keyIsPressed = true; return; } } /* Catch ctrl-alt-del (Works only from left ctrl or stickies) */ if (keymap->alt->pressed && keymap->ctrl->pressed && keyCode.at(0).first == KEY_DELETE) { printf("Requesting user daemon to reboot with remorse.\n"); tohkbd2user->actionWithRemorse(ACTION_REBOOT_REMORSE); keyIsPressed = true; return; } /* Catch ctrl-alt-backspace to restart lipstick (Works only from left ctrl or stickies) */ if (keymap->alt->pressed && keymap->ctrl->pressed && keyCode.at(0).first == KEY_BACKSPACE) { printf("Requesting user daemon to restart lipstick with remorse.\n"); tohkbd2user->actionWithRemorse(ACTION_RESTART_LIPSTICK_REMORSE); keyIsPressed = true; return; } } if (processAllKeys) { for (int i=0; i<keyCode.count(); i++) { bool tweakCapsLock = false; if (fix_CapsLock) tweakCapsLock = (capsLock == 3 && ((keyCode.at(i).first >= KEY_Q && keyCode.at(i).first <= KEY_P) || (keyCode.at(i).first >= KEY_A && keyCode.at(i).first <= KEY_L) || (keyCode.at(i).first >= KEY_Z && keyCode.at(i).first <= KEY_M) )); /* Some of the keys require shift pressed to get correct symbol */ if (keyCode.at(i).second & FORCE_COMPOSE) uinputif->sendUinputKeyPress(KEY_COMPOSE, 1); if ((keyCode.at(i).second & FORCE_RIGHTALT)) uinputif->sendUinputKeyPress(KEY_RIGHTALT, 1); if ((keyCode.at(i).second & FORCE_SHIFT) || tweakCapsLock) uinputif->sendUinputKeyPress(KEY_LEFTSHIFT, 1); if ((keyCode.at(i).second & FORCE_ALT)) uinputif->sendUinputKeyPress(KEY_LEFTALT, 1); if ((keyCode.at(i).second & FORCE_CTRL)) uinputif->sendUinputKeyPress(KEY_LEFTCTRL, 1); /* Mimic key pressing */ uinputif->sendUinputKeyPress(keyCode.at(i).first, 1); QThread::msleep(KEYREPEAT_RATE); uinputif->sendUinputKeyPress(keyCode.at(i).first, 0); if ((keyCode.at(i).second & FORCE_CTRL)) uinputif->sendUinputKeyPress(KEY_LEFTCTRL, 0); if ((keyCode.at(i).second & FORCE_ALT)) uinputif->sendUinputKeyPress(KEY_LEFTALT, 0); if ((keyCode.at(i).second & FORCE_SHIFT) || tweakCapsLock) uinputif->sendUinputKeyPress(KEY_LEFTSHIFT, 0); if ((keyCode.at(i).second & FORCE_RIGHTALT)) uinputif->sendUinputKeyPress(KEY_RIGHTALT, 0); if (keyCode.at(i).second & FORCE_COMPOSE) uinputif->sendUinputKeyPress(KEY_COMPOSE, 0); } } uinputif->synUinputDevice(); /* store keycode for repeat */ lastKeyCode = keyCode; /* Repeat delay first, then repeat rate */ repeatTimer->start(keyRepeat ? (keyRepeatRate-(KEYREPEAT_RATE-1)) : keyRepeatDelay); keyIsPressed = true; }
bool Tohkbd::checkKeypadPresence() { bool __prev_keypadPresence = keypadIsPresent; if (!vddEnabled) { /* keyboard is being connected to base */ /* TODO: how to detect keyboard is removed ??? */ printf("Presence detected, turning power on\n"); QThread::msleep(150); setVddState(true); QThread::msleep(150); tca8424->reset(); QThread::msleep(150); } tca8424driver::PresenceResult res = tca8424->testComms(); if (res == tca8424driver::DetectFail) { printf("keypad not present, turning power off\n"); setVddState(false); if (keypadIsPresent) { keyboardConnectedNotification(false); presenceTimer->stop(); handleKeyReleased(); } keypadIsPresent = false; } else { if (!keypadIsPresent) { keyboardConnectedNotification(true); controlLeds(true); checkDoWeNeedBacklight(); checkEEPROM(); } else if (res == tca8424driver::NoKeyPressedSinceReset && displayIsOn) { /* Keyboard power interrupt shortly? refresh leds just in case */ controlLeds(true); } presenceTimer->start(); keypadIsPresent = true; } if (__prev_keypadPresence != keypadIsPresent) { emit keyboardConnectedChanged(keypadIsPresent); emitKeypadSlideEvent(keypadIsPresent); vkbLayoutIsTohkbd = keypadIsPresent; changeActiveLayout(); if (forceLandscapeOrientation) changeOrientationLock(); } return keypadIsPresent; }