From 56d23ae060268e4b5cc00daeaffc89eefad73fee Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Fri, 30 Jun 2006 12:23:15 +0000 Subject: [PATCH] Hotkeys are now supported git-svn-id: svn://kolibrios.org@92 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/core/sys32.inc | 87 ++++++++---- kernel/trunk/docs/sysfuncr.txt | 167 +++++++++++++++-------- kernel/trunk/gui/event.inc | 13 +- kernel/trunk/hid/keyboard.inc | 237 +++++++++++++++++++++++---------- kernel/trunk/kernel.asm | 142 +++++++++++++------- 5 files changed, 445 insertions(+), 201 deletions(-) diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 9b0079b27..39d005baf 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -733,6 +733,40 @@ terminate: ; terminate application mov [0xf500],byte 0 ; empty button buffer +; remove defined hotkeys + mov eax, hotkey_list +.loop: + cmp [eax+8], esi + jnz .cont + mov ecx, [eax] + jecxz @f + push dword [eax+12] + pop dword [ecx+12] +@@: + mov ecx, [eax+12] + push dword [eax] + pop dword [ecx] + xor ecx, ecx + mov [eax], ecx + mov [eax+4], ecx + mov [eax+8], ecx + mov [eax+12], ecx +.cont: + add eax, 16 + cmp eax, hotkey_list+256*16 + jb .loop +; remove hotkeys in buffer + mov eax, hotkey_buffer +.loop2: + cmp [eax], esi + jnz .cont2 + and dword [eax+4], 0 + and dword [eax], 0 +.cont2: + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb .loop2 + mov ecx,esi ; remove buttons bnewba2: mov edi,[0xfe88] @@ -764,13 +798,11 @@ terminate: ; terminate application add esi,window_data mov ax,[esi+0] mov word [dlx],ax - mov bx,[esi+8] - add ax,bx + add ax,[esi+8] mov word [dlxe],ax mov ax,[esi+4] mov word [dly],ax - mov bx,[esi+12] - add ax,bx + add ax,[esi+12] mov word [dlye],ax mov [esi+0],word 0 mov [esi+8],word 5 @@ -798,18 +830,11 @@ terminate: ; terminate application mov edi,esi shl edi,5 - add edi,window_data - mov [edi+4],eax + mov [edi+4+window_data],eax - popa - - pusha - mov edi,esi - shl edi,5 add edi,draw_data mov ecx,32/4 xor eax, eax - ; cld rep stosd popa @@ -864,30 +889,34 @@ terminate: ; terminate application nlc41: popa - pusha ; remove hd1 reservation - mov edx,esi - shl edx, 5 ;imul edx,0x20 - add edx,0x3000 - mov edx,[edx+4] - cmp [hd1_status],edx - jne no_hd1_s_remove - mov [hd1_status],0 - no_hd1_s_remove: - popa + push esi ; remove hd1 & cd & flp reservation + shl esi, 5 + mov esi, [esi+0x3004] + cmp [hd1_status], esi + jnz @f + mov [hd1_status], 0 +@@: + cmp [cd_status], esi + jnz @f + mov [cd_status], 0 +@@: + cmp [flp_status], esi + jnz @f + mov [flp_status], 0 +@@: + pop esi pusha ; remove all irq reservations - mov edx,esi - shl edx, 5 ;imul edx,0x20 - add edx,0x3000 - mov edx,[edx+4] + mov eax,esi + shl eax, 5 ;imul edx,0x20 + mov eax,[edx+0x3000+4] mov edi,irq_owner mov ecx,16 newirqfree: - cmp [edi],edx + scasd jne nofreeirq - mov [edi],dword 0 + mov [edi-4],dword 0 nofreeirq: - add edi,4 loop newirqfree popa diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 0f0d815d9..ba1a76ed7 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -127,15 +127,19 @@ * если буфер пуст, возвращается eax=1 * если буфер непуст, то возвращается al=0, ah=код нажатой клавиши, старшее слово регистра eax обнулено + * если есть "горячая клавиша", то возвращается + al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш), + старшее слово регистра eax содержит состояние управляющих клавиш + в момент нажатия горячей клавиши Замечания: * Существует общесистемный буфер нажатых клавиш размером 120 байт, организованный как очередь. + * Существует ещё один общесистемный буфер на 120 "горячих клавиш". * При вызове этой функции приложением с неактивным окном - возвращается ответ "буфер пуст". - * Эта функция не сообщает о клавишах, нажатых в комбинации с Alt, - для таких случаев есть подфункция 12 функции 18. + считается, что буфер нажатых клавиш пуст. * По умолчанию эта функция возвращает ASCII-коды; переключиться на режим сканкодов (и назад) можно с использованием функции 66. + Однако, горячие клавиши всегда возвращаются как сканкоды. * Узнать, какие комбинации клавиш соответствуют каким кодам, можно, запустив приложения keyascii и scancode. * Сканкоды возвращаются непосредственно клавиатурой и фиксированы; @@ -144,6 +148,8 @@ подфункцией 2 функции 26. * Как следствие, ASCII-коды учитывают текущую раскладку клавиатуры (rus/en) в отличие от сканкодов. + * Поступает информация только о тех горячих клавишах, которые были + определены этим потоком подфункцией 4 функции 66. ====================================================================== ================ Функция 3 - получить системное время. =============== @@ -826,48 +832,6 @@ естественно, будет другой, но первые два поля сохранятся неизменными. -====================================================================== -=== Функция 18, подфункция 12 - получить последнюю нажатую клавишу. == -====================================================================== -Параметры: - * eax = 18 - номер функции - * ebx = 12 - номер подфункции -Возвращаемое значение: - * al = режим ввода с клавиатуры (0=ASCII,1=сканкоды), который - имел место при обработке нажатия последней клавиши на клавиатуре - * ah = код последней нажатой клавиши - * старшее слово регистра eax обнулено -Замечания: - * Только эта функция позволяет считывать клавиши, во время - считывания которых из буфера была нажата клавиша Alt, функция 2 - в случае, когда при её вызове была нажата Alt, возвращает - "буфер пуст", тем не менее считывая клавишу из очереди в - глобальную системную переменную last_key_press и продвигая очередь - вперёд. - * После считывания код последней нажатой клавиши сбрасывается в 0. - Следовательно, не стоит использовать эту функцию в двух различных - программах (и даже два раза в одной программе). - * Приложение @panel использует эту функцию для реагирования - на Alt+F4, Alt+Win, Alt+Ctrl+F12. - * last_key_press обновляется в точности в следующих случаях: - * Обнуляется при вызове описываемой функции. - * Когда управление получает некоторая процедура - (main_loop_sys_getkey) главного цикла операционной системы: - если буфер непуст, то первая клавиша буфера копируется в - last_key_press (и не забирается из очереди). - * При вызове функции 2: если буфер непуст, то считанная клавиша - копируется в last_key_press (и возвращается приложению, - вызвавшему функцию 2, но только если в момент считывания - не нажата Alt). - * Поскольку при активизации окна сбрасываются очереди клавиш и - кнопок, то в большинстве случаев интерпретация ah соответствует al - (т.е. понятно, что хранится в ah - ASCII-код или сканкод). - Тем не менее возможны неприятные случаи, когда активное окно, - не заботясь об оставшихся в буфере клавишах, вызывает функцию 66, - переключаясь между режимами; если после этого пользователь нажмёт - на клавишу, то значение переменной, соответствующей al, изменится, - а начальные клавиши в буфере останутся в старом режиме. - ====================================================================== ========== Функция 18, подфункция 13 - получить версию ядра. ========= ====================================================================== @@ -1028,9 +992,6 @@ db 'Kolibri',0 нормальная раскладка, после чего из кода вычитается 0x60; если не нажата ни одна из управляющих клавиш, то используется нормальная раскладка. - * Ценность установки раскладки с Alt представляется сомнительной, - поскольку всё равно функция 2 не возвращает клавиши при - нажатом Alt. * Получить раскладки и идентификатор страны можно с помощью подфункции 2 функции 26. * Идентификатор страны - глобальная системная переменная, которая @@ -3188,6 +3149,55 @@ dword- в замороженном состоянии; для запуска используйте подфункцию 5 функции 69. +====================================================================== +=== Функция 59 - получить информацию о последних системных вызовах. == +====================================================================== +Получает данные о всех системных вызовах всех процессов. +Параметры: + * eax = 59 - номер функции + * ebx = 0 - единственная подфункция + * ecx = указатель на буфер + * edx = размер буфера +Возвращаемое значение: + * eax = общее число системных вызовов, + сделанных с момента загрузки системы (по модулю 2^32) + * ebx = 0 +Формат информации об одном вызове: (размер = 0x40 = 64 байта) + * +0: dword: PID процесса/потока + * +4: 7*dword: мусор + * +32 = +0x20: dword: значение edi при вызове + * +36 = +0x24: dword: esi + * +40 = +0x28: dword: ebp + * +44 = +0x2C: dword: указатель стэка обработчика ядра + * +48 = +0x30: dword: ebx + * +52 = +0x34: dword: edx + * +56 = +0x38: dword: ecx + * +60 = +0x3C: dword: eax (=номер системной функции) +Замечания: + * Функция используется только в приложении systrace. + Довольно трудно представить ситуацию, в которой это приложение + или эта функция действительно полезны, а вот все системные вызовы + для поддержки этой функции несколько замедляются + (хотя и ненамного)... + * В связи с этим есть предложение поддержку этой функции + из ядра убрать совсем, вместе с приложением systrace. + * Информация о системных вызовах сохраняется в + системном кольцевом буфере на 0x10 входов. + Эта функция просто копирует указанный объём данных + из упомянутого буфера по указанному адресу. + * Какой из входов в буфере соответствует последнему вызову, + можно определить по значению eax, а именно, + вход (eax and 0xF) (по смещению (eax and 0xF)*0x40). + * В текущей реализации возможны редко встречающиеся + проблемы рассинхронизации, когда о некоторых вызовах + информация устаревает. + * Под системный буфер выделена страница, 4Кб. + Размер входа = 64 байта. + Почему используется только 16 входов - непонятно. + * Значение esp в момент системного вызова + этой функцией узнать нельзя. + * Проверки корректности edx в текущей реализации не делается. + ====================================================================== =========== Функция 60 - Inter Process Communication (IPC). ========== ====================================================================== @@ -3392,6 +3402,8 @@ IPC fff = номер функции устройства * cl = номер регистра (должен быть чётным для bl=9, делиться на 4 для bl=10) + * dl/dx/edx (в зависимости от запрошенного размера) содержит + данные для записи Возвращаемое значение: * eax = -1 - ошибка (запрещён доступ к PCI или неподдерживаемые параметры) @@ -3468,13 +3480,12 @@ IPC динамического выделения/освобождения памяти приложения. ====================================================================== -=========== Функция 66 - режим получения данных клавиатуры. ========== +================= Функция 66 - работа с клавиатурой. ================= ====================================================================== -Режим ввода влияет на результаты чтения клавиш функцией 2 -и получения последней нажатой клавиши подфункцией 12 функции 18. +Режим ввода влияет на результаты чтения клавиш функцией 2. При загрузке программы для неё устанавливается ASCII-режим ввода. ------------------- Подфункция 1 - установить режим. ------------------ +-------- Подфункция 1 - установить режим ввода с клавиатуры. --------- Параметры: * eax = 66 - номер функции * ebx = 1 - номер подфункции @@ -3484,7 +3495,7 @@ IPC Возвращаемое значение: * функция не возвращает значения -------------------- Подфункция 2 - получить режим. ------------------- +--------- Подфункция 2 - получить режим ввода с клавиатуры. ---------- Параметры: * eax = 66 - номер функции * ebx = 2 - номер подфункции @@ -3508,6 +3519,52 @@ IPC * бит 8 (маска 0x100): ScrollLock включён * прочие биты сброшены +----- Подфункция 4 - установить общесистемную "горячую клавишу". ----- +О нажатии "горячей клавиши" извещаются только приложения, +установившие её; активное приложение (к которому поступает +весь нормальный ввод) таких клавиш не получает. +Извещение заключается в посылке события с кодом 2. +Прочитать "горячую клавишу" можно так же, как и обычную, - +функцией 2. +Параметры: + * eax = 66 - номер функции + * ebx = 4 - номер подфункции + * cl задаёт сканкод клавиши; + используйте cl=0 для задания комбинаций типа Ctrl+Shift + * edx = 0xXYZ задаёт возможные состояния управляющих клавиш: + * Z (младшие 4 бита) задаёт состояние клавиш LShift и RShift: + * 0 = ни одна из клавиш не должна быть нажата; + * 1 = ровно одна из клавиш должна быть нажата; + * 2 = обе клавиши должны быть нажаты; + * 3 = должна быть нажата LShift, но не RShift; + * 4 = должна быть нажата RShift, но не LShift + * Y - аналогично для LCtrl и RCtrl; + * X - аналогично для LAlt и RAlt +Возвращаемое значение: + * eax=0 - успешно + * eax=1 - слишком много "горячих клавиш" (допускается максимум 256) +Замечания: + * Горячая клавиша может срабатывать либо при нажатии, + либо при отпускании. Сканкод отпускания клавиши на 128 больше, + чем сканкод нажатия (т.е. установлен старший бит). + * Несколько приложений могут установить одну и ту же комбинацию; + о нажатии такой комбинации будут извещаться все такие приложения. + +------ Подфункция 5 - удалить установленную "горячую клавишу". ------- +Параметры: + * eax = 66 - номер функции + * ebx = 5 - номер подфункции + * cl = сканкод клавиши и edx = 0xXYZ такие же, как и в подфункции 4 +Возвращаемое значение: + * eax = 0 - успешно + * eax = 1 - нет такой горячей клавиши +Замечания: + * При завершении процесса/потока удаляются все установленные им + горячие клавиши. + * Вызов функции не влияет на другие приложения. + Если другое приложение определило эту же комбинацию, + оно по-прежнему будет получать уведомления. + ====================================================================== ============ Функция 67 - изменить положение/размеры окна. =========== ====================================================================== @@ -4274,8 +4331,8 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); Коды событий: * 1 = сообщение о перерисовке (сбрасывается при вызове функции 0) * 2 = нажата клавиша на клавиатуре (поступает, только когда окно - активно; сбрасывается, когда все клавиши из буфера - считаны функцией 2) + активно) или нажата "горячая клавиша"; + сбрасывается, когда все клавиши из буфера считаны функцией 2 * 3 = нажата кнопка, определённая ранее функцией 8 (или кнопка закрытия, созданная неявно функцией 0; кнопка минимизации обрабатывается системой и о ней сообщения не приходит; diff --git a/kernel/trunk/gui/event.inc b/kernel/trunk/gui/event.inc index c883fe7a7..3c71fb1c4 100644 --- a/kernel/trunk/gui/event.inc +++ b/kernel/trunk/gui/event.inc @@ -69,12 +69,21 @@ get_event_for_app: movzx edx,word [0xC000+ecx*2] mov eax, [0x3004] cmp eax,edx - jne no_eventoccur2 + jne no_eventoccur2x cmp [0xf400],byte 0 - je no_eventoccur2 + je no_eventoccur2x + eventoccur2: popad mov eax,2 ret + no_eventoccur2x: + mov eax, hotkey_buffer +@@: + cmp [eax], ecx + jz eventoccur2 + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb @b no_eventoccur2: ;mov edi,[0x3010] ; BUTTON IN BUFFER diff --git a/kernel/trunk/hid/keyboard.inc b/kernel/trunk/hid/keyboard.inc index 7cedad0a2..b79a7184d 100644 --- a/kernel/trunk/hid/keyboard.inc +++ b/kernel/trunk/hid/keyboard.inc @@ -26,8 +26,64 @@ uglobal ctrl_alt_del db 0 kb_lights db 0 + +align 4 + hotkey_scancodes rd 256 ; we have 256 scancodes + hotkey_list rd 256*4 ; max 256 defined hotkeys + hotkey_buffer rd 120*2 ; buffer for 120 hotkeys endg +iglobal +hotkey_tests dd hotkey_test0 + dd hotkey_test1 + dd hotkey_test2 + dd hotkey_test3 + dd hotkey_test4 +hotkey_tests_num = 5 +endg + +hotkey_test0: + test al, al + setz al + ret +hotkey_test1: + test al, al + setnp al + ret +hotkey_test2: + cmp al, 3 + setz al + ret +hotkey_test3: + cmp al, 1 + setz al + ret +hotkey_test4: + cmp al, 2 + setz al + ret + +hotkey_do_test: + push eax + mov edx, [kb_state] + shr edx, cl + add cl, cl + mov eax, [eax+4] + shr eax, cl + and eax, 15 + cmp al, hotkey_tests_num + jae .fail + xchg eax, edx + and al, 3 + call [hotkey_tests + edx*4] + cmp al, 1 + pop eax + ret +.fail: + stc + pop eax + ret + align 4 irq1: save_ring3_context @@ -44,52 +100,55 @@ irq1: in al,0x60 mov [keyboard_data],al +; ch = scancode +; cl = ext_code +; bh = 0 - normal key +; bh = 1 - modifier (Shift/Ctrl/Alt) +; bh = 2 - extended code + mov ch,al cmp al,0xE0 je @f cmp al,0xE1 jne .normal_code - @@: mov [ext_code],al - jmp .no_key.end + @@: + mov bh, 2 + mov [ext_code], al + jmp .writekey .normal_code: - mov cl,[ext_code] - mov [ext_code],0 + mov cl, 0 + xchg cl, [ext_code] and al,0x7F + mov bh, 1 @@: cmp al,0x2A jne @f cmp cl,0xE0 - je .no_key.end + je .writekey mov eax,VKEY_LSHIFT - jmp .no_key + jmp .modifier @@: cmp al,0x36 jne @f cmp cl,0xE0 - je .no_key.end + je .writekey mov eax,VKEY_RSHIFT - jmp .no_key + jmp .modifier @@: cmp al,0x38 jne @f - cmp cl,0xE0 - je .alt.r - mov eax,VKEY_LALT - jmp .no_key - .alt.r: - mov eax,VKEY_RALT - jmp .no_key + mov eax, VKEY_LALT + test cl, cl + jz .modifier + mov al, VKEY_RALT + jmp .modifier @@: cmp al,0x1D jne @f - cmp cl,0 - jne .ctrl.r - mov eax,VKEY_LCONTROL - jmp .no_key - .ctrl.r: - cmp cl,0xE1 - jne .ctrl.r.2 - mov [ext_code],cl - jmp .no_key.end - .ctrl.r.2: - mov eax,VKEY_RCONTROL - jmp .no_key + mov eax, VKEY_LCONTROL + test cl, cl + jz .modifier + mov al, VKEY_RCONTROL + cmp cl, 0xE0 + jz .modifier + mov [ext_code], cl + jmp .writekey @@: cmp al,0x3A jne @f mov bl,4 @@ -97,8 +156,8 @@ irq1: jmp .no_key.xor @@: cmp al,0x45 jne @f - cmp cl,0 - jne .no_key.end + test cl, cl + jnz .writekey mov bl,2 mov eax,VKEY_NUMLOCK jmp .no_key.xor @@ -108,8 +167,8 @@ irq1: mov eax,VKEY_SCRLOCK jmp .no_key.xor @@: - test ch,0x80 - jnz .no_key.end + test ch,ch + js .writekey movzx eax,ch ; plain key mov bl,[keymap+eax] mov edx,[kb_state] @@ -117,10 +176,9 @@ irq1: jz .noctrlaltdel test dl,VKEY_ALT jz .noctrlaltdel - cmp bl,134+48 + cmp ch,53h jne .noctrlaltdel mov [ctrl_alt_del],1 - jmp .no_key.end .noctrlaltdel: test dl,VKEY_CONTROL ; ctrl on ? jz @f @@ -164,47 +222,90 @@ irq1: mov [0x2E0000+4096*12+0x10],edx mov bl,0 @@: + mov bh, 0 + jmp .writekey +.modifier: + test ch, ch + js .modifier.up + or [kb_state], eax + jmp .writekey +.modifier.up: + not eax + and [kb_state], eax + jmp .writekey +.no_key.xor: + mov bh, 0 + test ch, ch + js .writekey + xor [kb_state], eax + xor [kb_lights], bl + call set_lights + +.writekey: +; test for system hotkeys + movzx eax, ch + cmp bh, 1 + ja .nohotkey + jb @f + xor eax, eax +@@: + mov eax, [hotkey_scancodes + eax*4] +.hotkey_loop: + test eax, eax + jz .nohotkey + mov cl, 0 + call hotkey_do_test + jc .hotkey_cont + mov cl, 2 + call hotkey_do_test + jc .hotkey_cont + mov cl, 4 + call hotkey_do_test + jnc .hotkey_found +.hotkey_cont: + mov eax, [eax] + jmp .hotkey_loop +.hotkey_found: + mov eax, [eax+8] +; put key in buffer for process in slot eax + mov edi, hotkey_buffer +@@: + cmp dword [edi], 0 + jz .found_free + add edi, 8 + cmp edi, hotkey_buffer+120*8 + jb @b +; no free space - replace first entry + mov edi, hotkey_buffer +.found_free: + mov [edi], eax + movzx eax, ch + cmp bh, 1 + jnz @f + xor eax, eax +@@: + mov [edi+4], ax + mov eax, [kb_state] + mov [edi+6], ax + jmp .exit.irq1 +.nohotkey: cmp [keyboard_mode],0 ; return from keymap - jne .no_key.end - mov [keyboard_mode_sys],0 - cmp bl,0 - je .no_key.end + jne .scancode + test bh, bh + jnz .exit.irq1 + test bl, bl + jz .exit.irq1 + jmp .dowrite +.scancode: + mov bl, ch +.dowrite: movzx eax,byte[0xF400] cmp al,120 - jae .no_key.end - inc al + jae .exit.irq1 + inc eax mov [0xF400],al mov [0xF400+eax],bl - jmp .no_key.end - - .no_key: - test ch,0x80 - jz .no_key.down - not eax - and [kb_state],eax - jmp .no_key.end - .no_key.xor: - test ch,0x80 - jnz .no_key.end - xor [kb_state],eax - xor [kb_lights],bl - call set_lights - jmp .no_key.end - .no_key.down: - or [kb_state],eax - .no_key.end: - cmp [keyboard_mode],1 ; return scancode - jne .no_scancode - mov [keyboard_mode_sys],1 - movzx eax,byte[0xF400] - cmp al,120 - jae .no_scancode - inc al - mov [0xF400],al - mov [0xF400+eax],ch - .no_scancode: - .exit.irq1: mov [check_idle_semaphore],5 diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 654963cdd..3d39d9a31 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -775,7 +775,7 @@ finit ;reset the registers, contents which are still equal RM mov al, 0xF3 ; set repeat rate & delay call kb_write call kb_read - mov al, 00100010b ; 24 500 ;00100100b ; 20 500 + mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 call kb_write call kb_read ;// mike.dld [ @@ -826,7 +826,6 @@ osloop: call [draw_pointer] call checkbuttons - call main_loop_sys_getkey call checkwindows ; call check_window_move_request call checkmisc @@ -2271,12 +2270,9 @@ sysfn_getdiskinfo: ; 18.11 = get disk info table rep movsd ret -sysfn_lastkey: ; 18.12 = get all key pressed with ALT - mov eax,[last_key_press] - mov al,[keyboard_mode_sys] - mov [esp+36],eax - mov [last_key_press],0 - ret +sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) + and dword [esp+36], 0 + ret sysfn_getversion: ; 18.13 = get kernel ID and version mov edi,[3010h] @@ -2324,8 +2320,6 @@ screen_workarea RECT ;// mike.dld, 2006-29-01 ] window_minimize db 0 sound_flag db 0 -last_key_press dd 0 -keyboard_mode_sys db 0 endg iglobal @@ -2340,15 +2334,6 @@ UID_NONE=0 UID_MENUETOS=1 ;official UID_KOLIBRI=2 ;russian -main_loop_sys_getkey: - cmp [0xf400],byte 0 - je .finish - movzx eax,byte [0xf401] - shl eax,8 - mov [last_key_press],eax - .finish: - ret - sys_cachetodiskette: ; pushad ; cmp eax,1 @@ -2516,6 +2501,7 @@ align 4 sys_getkey: mov [esp+36],dword 1 +; test main buffer mov ebx, [0x3000] ; TOP OF WINDOW STACK movzx ecx,word [0xC000 + ebx * 2] mov edx,[0x3004] @@ -2538,27 +2524,27 @@ sys_getkey: mov ebx, 0xF401 call memmove pop eax - mov [last_key_press],eax - - mov eax,[kb_state] - and al,110000b - cmp al,100000b - je .yes_win_key - cmp al,10000b - je .yes_win_key - mov eax,[last_key_press] - jmp .no_win_key -; cmp ah,232 -; je .yes_win_key -; cmp ah,233 -; jne .no_win_key - .yes_win_key: - mov eax,1 - .no_win_key: +.ret_eax: mov [esp+36],eax - .finish: ret - + .finish: +; test hotkeys buffer + mov ecx, hotkey_buffer +@@: + cmp [ecx], ebx + jz .found + add ecx, 8 + cmp ecx, hotkey_buffer+120*8 + jb @b + ret +.found: + mov ax, [ecx+6] + shl eax, 16 + mov ah, [ecx+4] + mov al, 2 + and dword [ecx+4], 0 + and dword [ecx], 0 + jmp .ret_eax align 4 @@ -4395,26 +4381,23 @@ sys_trace: sys_process_def: + mov edi, [0x3000] - cmp eax,1 ; set keyboard mode + dec eax ; 1 = set keyboard mode jne no_set_keyboard_setup - mov edi,[0x3000] shl edi,8 - add edi,0x80000+0xB4 - mov [edi],bl + mov [edi+0x800B4],bl ret no_set_keyboard_setup: - cmp eax,2 ; get keyboard mode + dec eax ; 2 = get keyboard mode jne no_get_keyboard_setup - mov edi,[0x3000] shl edi,8 - add edi,0x80000+0xB4 - movzx eax, byte [edi] + movzx eax, byte [0x800B4+edi] mov [esp+36],eax @@ -4422,7 +4405,7 @@ sys_process_def: no_get_keyboard_setup: - cmp eax,3 ; get keyboard ctrl, alt, shift + dec eax ; 3 = get keyboard ctrl, alt, shift jne no_get_keyboard_cas ; xor eax,eax @@ -4444,7 +4427,72 @@ sys_process_def: no_get_keyboard_cas: + dec eax + jnz no_add_keyboard_hotkey + mov eax, hotkey_list +@@: + cmp dword [eax+8], 0 + jz .found_free + add eax, 16 + cmp eax, hotkey_list+16*256 + jb @b + mov dword [esp+36], 1 + ret +.found_free: + mov [eax+8], edi + mov [eax+4], ecx + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov ecx, [ebx] + mov [eax], ecx + mov [ebx], eax + mov [eax+12], ebx + jecxz @f + mov [ecx+12], eax +@@: + and dword [esp+36], 0 + ret + +no_add_keyboard_hotkey: + + dec eax + jnz no_del_keyboard_hotkey + + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov eax, [ebx] +.scan: + test eax, eax + jz .notfound + cmp [eax+8], edi + jnz .next + cmp [eax+4], ecx + jz .found +.next: + mov eax, [eax] + jmp .scan +.notfound: + mov dword [esp+36], 1 + ret +.found: + mov ecx, [eax] + jecxz @f + mov edx, [eax+12] + mov [ecx+12], edx +@@: + mov ecx, [eax+12] + mov edx, [eax] + mov [ecx], edx + xor edx, edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax], edx + mov [esp+36], edx + ret + +no_del_keyboard_hotkey: ret