Тачпад та клавіатура з підручного девайсу на Windows Mobile

У вас є комунікатор з WM та необхідність управління ПК за його допомогою?

Можливо, ви хочете провести якусь хитру презентацію, яка потребує мишки у кишені?

клавіатура

Ок, вам потрібно під кат (є картинки).

Якщо вас цікавить лише кінцевий продукт, але не технічні подробиці, рекомендую не затримуючись пройти до розділу FAQ.

Завдання: WM-комунікатор перетворити на повноцінний тачпад і клавіатуру, знайшовши при цьому можливість керувати з його допомогою якоюсь win-системою. Взагалі, керована система може бути і не win, але про це нижче. В якості транспорту будемо використовувати UDP/IP Wi-Fi, або (для цінителів) Bluetooth. Що для цього потрібно:

  • захопити введення з дефолтної клавіатури девайса;
  • за допомогою тачскріна комунікатора емулювати:
  • звичайний тачпад, зі скроллом та кліками;
  • коліщатко миші;
  • кнопки миші (з можливістю переміщення курсору із затиснутим кліком для drag'n'drop);
  • додаток на керованій системі (сервер), здатне писати в потік клавіатури та миші дані, які отримують від пристрою;
  • протокол обміну клієнтської програми з сервером на керованій системі.
  • По порядку, клієнтська частина – це

    Додаток для WM

    Небагато про терміни, в яких виражається принцип емуляції тачпада - вони використовуються в подальшому описі:

    • Static Move – якщо користувач підтягнув свій палець до кордону тачпада і залишив його там, керований курсор буде повільно повзти у напрямку цього кордону. Зручно для перетягування курсора із затиснутим кліком;
    • Scroll – користувач провів пальцем по особливому регіону біля краю тачпада, що інтерпретується як прокручування коліщатка;
    • Scroll Pad – згаданий вище «особливий регіон»біля краю тачпада. Якщо палець починає рух на ньому, то включається прокручування, інакше він працює як звичайний тачпад.
    • Inertial Scrolling – користувач активував прокручування, та прибрав палець, не зупиняючи його рух. Прокручування буде виконуватися далі на колишній швидкості без участі користувача, доки він не спроможеться знову торкнутися тачпада.
    • Click and Drag - натиснули, прибрали палець, і відразу ж натиснули ще раз - тепер можна керувати курсором із затиснутим кліком.
    Логіка тачпада реалізована в класі MouseHandler, ось він:
    девайсу
    ConfigApply та ConfigStore прямо до справи не належать; Вся робота з MouseHandler зводиться до обробки його подій, призначення якого в цілому ясно з назв.

    Клавіатура

    Клас, чия задача – формувати керуючі повідомлення для відправки на сервер:

    девайсу
    Отримуємо запрошену дію через метод типу KeyboardCommand(), MouseMove(), etc; формуємо повідомлення, відправляємо його до сокету через подію OnPacketSend.

    Користувачеві є унікальна можливість правити свої конфіги в рульному XML-форматі. Як у додатку реалізована робота з ними, подивіться самі, якщо комусь цікаво. Я не хочу говорити про це.

    девайсу

    Скрін:

    підручного

    При малюванні інтерфейсу я надихався популярною картиною Казимира Малевича:

    девайсу
    підручного
    Оскільки GUI прийнято вважати самодокументуючим інтерфейсом користувача, я все ж залишив підписи кнопок (скрин зліва), які зникають після першого торкання тачпада ). Так, я ще не сказав: це чорне поле на екрані і є тачпад; призначення кнопок має бути очевидним з їхньої назви. Використання клавіатури теж викликати не повинно. Використана портретна орієнтація вікна, щоб заощадити площу екранутачпада; при цьому використання самого тачпада передбачається в landscape (але це налаштовується).

    Перша спроба створити більш-менш кроссплатформенний сервер за допомогою python та SendKeys провалилася, оскільки з'ясувалося, що SendKeys не вміє Unicode. Як працювати з пітона з мишкою, я навіть не дивився. Другою спробою (успішною) було використання WinAPI з консольної програми на C, де робота по запису команд у потік миші та клавіатури виконується за допомогою функції SendInput. Проста консольна програма, яка слухає UDP-сокет і періодично викликає SendInput(), розгляду не варто. Зауважу лише, що системних ресурсів воно практично не споживає (особливо за відключеного клієнта), так що його можна тримати запущеним постійно.

    Що стосується переносимості, то не важко написати platform-specific додаток для будь-якої іншої платформи (була б потреба в аудиторії), оскільки для доставки команд на керовану систему використовується простий у реалізації

    Дані передаються лише від клієнта до сервера, жодних підтверджень чи зворотних команд не передбачено. Будь-яка команда відправляється у кадрі фіксованого розміру, що складається з таких полів:

    • заголовок - 3 байти, рядок «d2k»
    • порядковий номер пакета (щоб уникнути повторів пакетів при broadcast-розсилці, яке використовується по дефолту) — 1 байт
    • тип команди (керівний символ, юнікод-символ, перемістити мишу, etc) - 1 байт
    • дані команди (координати курсору, код символу, etc) – 4 байти, little endian
    Дефолтний порт 12358 (вибір підказаний фрагментом послідовності).

    Q:Я не хочу використовувати бездротові інтерфейси. Як бути?A:Підключити комунікатор до керованого PC зі встановленимActiveSync, залишивши дефолтні налаштування клієнта. Все працюватиме.

    Q:Я зафіксував клік, виконуючи Drag’n’Drop, але з'єднання з сервером було перервано, і клік залишився затиснутий. Що робити?A:Зачекайте 3 секунди. Якщо сервер не отримає від клієнта команди встановлення стану кліків мишки протягом цього часу, він відпустить усі кнопки.

    Q:При тривалому переміщенні курсору миші моя мережа ляже через лютий трафік, так?A:Дефолтна періодичність оновлення позиції курсору – 10мс (100 разів на секунду); розмір пакета (3+1+1+4) == 9 байт + оверхед UDP/IP-фрейму 28 байт, отримаємо 37 байт в 1 повідомленні, або 3.6 кбіт/сек. Якщо мишка не рухається, її позиція не оновлюється. Відповідь негативна.

    Висновок

    А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»