Русификация
клавиатуры устройств на базе PalmOS Впервые проблема русификации клавиатуры для Palm возникла еще летом 2000 г., когда в России появились первые модели складной клавиатуры StowAway Keyboard. Эта клавиатура, можно сказать, работала замечательно - складывалась, раскладывалась, а также позволяла вполне сносно работать с латиницей. Однако о кириллице ее создатели, как водится, не позаботились, и клавиатура "не понимала" русского языка. Проблема русификации распадалась на две: нанесение русских букв на клавиатуру и программная ее локализация. Первая проблема решается легко и просто, последняя - несколько сложнее. Дело в том, что существует два подхода: либо разрабатывать собственный клавиатурный драйвер, либо "налаживать" взаимодействие между существующим драйвером (что решает проблемы обработки русских символов, зато ставит проблему совместимости драйвера с любыми клавиатурами) и существующим русификатором (что сложнее в реализации, но не требует переписывания драйвера клавиатуры). Для реализации ввода русских символов с клавиатуры в русификаторе CyrHack было решено использовать последний метод, основываясь на простейшем принципе, когда вводимые с клавиатуры символы латиницы по таблице перекодировки заменяются на символы кириллицы. При этом необходимо соблюдать два условия: драйвер клавиатуры присутствует (и активен), текущий язык в системе - русский. Обращения к разработчикам фирм - изготовителей клавиатур (Palm Computing и LandWare) с просьбой пролить свет на возможность организации взаимодействия стороннего программного обеспечения с драйверами соответствующих устройств остались без ответа. Пришлось ступить на тропу экспериментальных изысканий. Определить наличие драйвера Palm Portable Keyboard достаточно легко. Сразу после активизации драйвер определяет системную функцию (feature, здесь и далее используется терминология PalmOS, дополнительную информацию о программировании для PalmOS можно найти на www.palmos.com) с идентификатором (ID) 'KO01' и номером 39 (для версии драйвера 1.1). Return-значение, равное 1, соответствует активному состоянию клавиатуры, 0 - клавиатура не используется. ... KbdDriverID equ 'KO01' GoTypeDriverID equ 'dwKB' ... ; проверяем наличие драйвера Palm Portable Keyboard Palm ; вызов функции FtrGet PalmOS, в скобках перечислены аргументы, ; идентификатор GoTypeDriverID описан выше (creator ID, номер ; системной функции, определяемой драйвером клавиатуры, третий ; параметр - 32 - двоичный адрес локальной (относительно регистра ; a6) переменной kbddriver systrap FtrGet(#KbdDriverID.l, #39.w, &kbddriver(a6).l) tst.l d0 bne GoType ; проверяем состояние переключателя "Enable Keyboard" move.l kbddriver(a6), d0 beq.s NoKeyboard bra.s Keyboard Ситуация с GoType! немного проще. Драйвер для клавиатуры GoType! доступен как в форме программы-расширения для пакета HackMaster, так и в виде обычной программы. И в том, и в другом случае перехват стандартных системных функций PalmOS выполняется вполне обычным для Palm OS образом, что позволяет обойтись одним вызовом Feature Manager: ; проверяем наличие драйвера GoType! Keyboard GoType systrap FtrGet(#GoTypeDriverID.l, #1000.w, &kbddriver(a6).l) tst.l d0 bne NoKeyboard ; считаем, что драйвер клавиатуры присутствует и активен Keyboard ... Перекодирование ввода - обычная таблица подстановки; метод, особенного интереса не представляющий. Перекодируются символы a...z, A...Z, а также цифры 2, 5, 6, 7, 8 (поддержка знаков пунктуации). Остаются семь особых случаев - символы [, {, ] и } в верхнем алфавитном ряду клавиатуры, которым соответствуют буквы х, Х, ъ, Ъ, символы ;, :, ', ", в среднем ряду (буквы ж, Ж, э, Э) и символы ,, <, ., >, в нижнем ряду (буквы б, Б, ю, Ю), а также символы ` и ~ (буквы ё и Ё). Таблица перекодировки тут не поможет, так как их коды не соответствуют буквам латиницы и функция GrfGetState работает одинаково, независимо от состояния CapsLock. Для этих семи символов было решено воспользоваться неизящной, но действенной цепочкой условных операторов: ... ; функция GrfGetState возвращает статусную ; информацию системы ввода Graffiti systrap GrfGetState (&capsLock(a6).l, &numLock(a6).l, &tempShift(a6).l, &autoShifted(a6).l) tst.b capsLock(a6) beq.s Exit Key0 cmp.w #'[', d3 bne.s Key1 moveq #'{', d3 bra.s Exit Key1 cmp.w #']', d3 bne.s Key2 moveq #'}', d3 bra.s Exit Key3 ... Key6 cmp.w #'`', d3 bne.s Exit moveq #'~', d3 Exit ... Кроме того, чтобы пользователь мог работать одновременно и с клавиатуры, и с Graffiti перехватывается код символа функцией GrfProcessStroke; по результатам анализа return-значения в русификаторе устанавливается некоторый флаг. В дальнейшем этот флаг анализируется при обработке события keyDownEvent и при необходимости символ латиницы, передаваемый драйвером, заменяется символом кириллицы. systrap FtrGet(#CyrCreatorID.l, #GrfProcessStrokeID.w, &pfnOldProc(a6).l) move.w p3(a6),-(a7) move.l p2(a6),-(a7) move.l p1(a6),-(a7) move.l pfnOldProc(a6),a0 jsr (a0) move.w p3(a6),d0 andi.w #$ff00,d0 bne.s Done move.l d0,-(a7) systrap FtrGet(#CyrCreatorID.l, #777.w, &ftr(a6).l) move.l ftr(a6),a0 move.l #1,Features.isstroke(a0) move.l (a7)+,d0 -- |