Linux - Состояние Num Lock

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Linux - Состояние Num Lock

Сообщение swa1 » 18.03.2010 20:10:03

Подскажите, как в Linux читать и управлять Num Lock. :?:
Консольное приложение.

Или подскажите где почитать...
Аватара пользователя
swa1
новенький
 
Сообщения: 80
Зарегистрирован: 25.09.2007 11:04:08
Откуда: Ялта

Re: Linux - Состояние Num Lock

Сообщение coyot.rush » 18.03.2010 21:07:23

заюзать асм http://forum.developing.ru/archive/index.php/t-13857.html Должно работать под любой осью.

Добавлено спустя 1 минуту 23 секунды:
BBB
21.04.2008, 12:23
Вообще-то, как это ни может показаться невероятным, для "зажигания"/"тушения" клавиш достаточно изменить соответсвующие биты в в соответствующем байте в области данных BIOS (40h:17h)

Например, следующий код "тушит" NumLock:

.model tiny
.Code
Org 100h
Start:
Xor Ax,Ax
Mov Es,Ax
And byte ptr Es:[0417h],(not 20h)
Ret
End Start


Биты, сответсвующие клавишам:

Bit Val Meaning
7 $80 Insert on
6 $40 Caps Lock on
5 $20 Num Lock on
4 $10 Scroll Lock on
3 $08 <Alt> depressed
2 $04 <Ctrl> depressed
1 $02 <LeftShift> depressed
0 $01 <RightShift> depressed


Добавлено спустя 25 минут 10 секунд:
взято http://vbrus.narod.ru/PascalInfo3.htm
Код: Выделить всё
33. Как прочитать нажатия клавиш функциональных клавиш (Ctrl, Alt, Shift и.т.д.) - Паскаль

      Q:> А как прочитать нажатия клавиш Ctrl, Alt и подобных?

      A: Для функции ReadKey эти клавиши не генерируют никаких кодов.
      Однако, информация о нажатии подобных клавиш все-таки
      имеется и располагается в памяти (область данных BIOS)
      по адресу:

      Seg0040:$17 - Keyboard Status Flags #1 (основные флаги спец.клавиш)

      Ячейка Seg0040:$0017:

                          <-+---- номера битов
         Њ7+6+5+4+3+2+1+0|
         |i|c|n|s|A|^|S|S| Бит Знач. Назначение бита
         Іs+s+s+s+-+-+L+R|  N
          | | | | | | | +-. 0:  01h  нажат Right-shift
          | | | | | | +---. 1:  02h  нажат Left-shift
          | | | | | +-----. 2:  04h  нажат Ctrl (любой)
          | | | | +-------. 3:  08h  нажат Alt (любой)
          | | | +---------. 4:  10h  состяние ScrollLock
          | | +-----------. 5:  20h  состяние NumLock
          | +-------------. 6:  40h  состяние CapsLock
          +---------------. 7:  80h  состяние Insert

      В этих ячейках каждый бит отвечает за одну конкретную спец.клавишу - если бит установлен, то клавиша нажата, если сброшен - то не нажата. Исключение составляют клавиши ScrollLock, NumLock, CapsLock, Insert - при первом нажатии соответствующий бит устанавливается в 1, а при следующем - сбрасывается в 0.
      Вот вам функция для вытаскивания этой информации
      их байтов Seg040:$17.

      Пример вызова: if GetLockKey(Ctrl) then {нажат Ctrl}

      Type
      Keytype=(Ins, Caps, Num, Scroll, Ctrl, Alt, LShift, RShift);

      function GetLockKey(lock:Keytype):Boolean;
      {Проверяет, нажата ли спец.клавиша}
      var b:word;
      begin
      case lock of
      Ins : b:=$0080;
      Caps : b:=$0040;
      Num : b:=$0020;
      Scroll : b:=$0010;
      Alt : b:=$0008;
      Ctrl : b:=$0004;
      LShift : b:=$0002;
      RShift : b:=$0001;
      end;
      if (mem[0:$417] and b)=b then GetLockKey:=true
      else GetLockKey:=false;
      end;


      Аналогично (домашнее задание! ;-) можно анализировать и байт по адресу
      Seg040:$18 (Keyboard Status Flags #2)

      Ячейка Seg0040:$0018:

                          <-+---- номера битов
         Њ7+6+5+4+3+2+1+0|
         |i|c|n|s|p|q|A|^| Бит Знач. Назначение бита
         Іd+d+d+d+-+d+l+l|  N
          | | | | | | | +-. 0:  01h нажат левый Ctrl
          | | | | | | +---. 1:  02h нажат левый Alt
          | | | | | +-----. 2:  04h SysReq DOWN
          | | | | +-------. 3:  08h hold/pause state
          | | | +---------. 4:  10h нажат ScrollLock
          | | +-----------. 5:  20h нажат NumLock
          | +-------------. 6:  40h нажат CapsLock
          +---------------. 7:  80h нажат Insert

      Посмотрите на прилагаемый тест, попробуйте нажать несколько клавиш сразу, обратите внимание на то, что статус клавиатуры изменяется как при нажатии на клавиши, так и при отпускании тоже!
      --- * Origin: (2:5020/794.13)

      {> Cut here. FileName= GETKEY.PAS }
      {From: Valery Votintsev 2:5021/22}
      {Alt, Shift, Ctrl test for 0040:0017 keyboard status}
      Uses CRT;
      Const
      RightShift = $0001;
      LeftShift = $0002;
      AnyCtrl = $0004;
      AnyAlt = $0008;
      ScrollActive = $0010;
      NumLockActive = $0020;
      CapsLockActive= $0040;
      InsActive = $0080;
      LeftCtrl = $0100;
      LeftAlt = $0200;
      SysReq = $0400;
      PauseKey = $0800;
      ScrollLock = $1000;
      NumLock = $2000;
      CapsLock = $4000;
      Insert = $8000;

      const hex_num:array [0..15] of char='0123456789ABCDEF';

      var
      key:char; {код нажатой клавиши}
      flags:word; {флаги состояния клавиатуры}
      newflags:word;

      function word2hex(w:word):string;
      {перевод в 16-ричное число}
      var
      b:array[1..2] of byte absolute w;
      begin
      word2hex:=hex_num[b[2] shr 4]+hex_num[b[2] and $0F] +
      hex_num[b[1] shr 4]+hex_num[b[1] and $0F]
      end;

      function GetFlags:Word;
      {Считывает состояние флагов спец.клавиш}
      begin
      GetFlags:=memW[0:$417];
      end;

      function AnyKeyEvent:boolean;<
      begin
      AnyKeyEvent:= (KeyPressed or (newflags<>flags));
      end;

      function Pressed(lock:word):Boolean;
      {Проверяет, нажата ли спец.клавиша с кодом LOCK}
      begin
      if (flags and word(lock))<>0 then Pressed:=true
      else Pressed:=false;
      end;

      Procedure WriteKeyCode;
      begin
      TextAttr:=White;
      If KeyPressed then begin
      key:= ReadKey; {читаем код }
      if Key = #0 then begin {код оказался расширенным}
      Write(Ord(Key):3,','); {печатаем нулевой код }
      key:= ReadKey; {читаем расширенный код }
      end;
      Write(Ord(Key):3); {печатаем основной код }
      end
      else write(' ');
      end;

      Procedure WriteFlags;
      begin
      TextAttr:=LightGray;
      Write(' Flags:',word2hex(memW[Seg0040:$17]));
      {Теперь печатаем флаги спец.клавиш}
      TextAttr:=Cyan;
      If Pressed(RightShift) then Write(' RightShift');
      If Pressed(LeftShift ) then Write(' LeftShift');
      If Pressed(AnyAlt ) then Write(' AnyAlt');
      If Pressed(AnyCtrl ) then Write(' AnyCtrl');
      If Pressed(LeftCtrl ) then Write(' LeftCtrl');
      If Pressed(LeftAlt ) then Write(' LeftAlt');
      If Pressed(SysReq ) then Write(' SysReq');
      If Pressed(PauseKey ) then Write(' Pause');
      If Pressed(ScrollLock) then Write(' ScrollLock');
      If Pressed(NumLock ) then Write(' NumLock');
      If Pressed(CapsLock ) then Write(' CapsLock');
      If Pressed(Insert ) then Write(' Insert');

      {Теперь печатаем состояние переключателей}
      TextAttr:=Yellow;
      If Pressed(ScrollActive ) then Write(' ScrollLockActive');
      If Pressed(NumLockActive ) then Write(' NumLockActive');
      If Pressed(CapsLockActive) then Write(' CapsLockActive');
      If Pressed(InsActive ) then Write(' InsActive');
      Writeln;
      TextAttr:=LightGray;
      end;

      begin
      while keypressed do readkey; {Очистить буфер клавиатуры}
      flags:=GetFlags; {начальное состояние флагов}
      repeat
      newflags:=GetFlags; {новое состояние флагов}
      If AnyKeyEvent then begin {если чего-нибудь нажато}
      WriteKeyCode;
      flags:=newflags; {запомнить состояние флагов}
      WriteFlags;
      end;
      until Key = #27; {Цикл, пока не нажмем Esc}
      while keypressed do readkey; {Очистить буфер клавиатуры}
      end. Наверх

34. Как узнать состояние клавиш Shift, Alt, Ctrl, Num Lock, Caps Lock, Scroll Lock и искусственно переключать их? - Pascal

      Состояние этих клавиш храниться в памяти по адресу 0:$417. Каждой из этих клавиш в байте по этому адресу соответствует свой бит. Следующие процедуры показывает как можно читать и изменять состояния клавиш

      Type
      TKeytype=(ktCaps, ktNum, ktScroll, ktCtrl, ktAlt, ktLShift, ktRShift);

      function GetLock(lock:TKeytype):Boolean;
      var
      b:byte;
      begin
      case lock of
      ktCaps : b:=$40;
      ktNum : b:=$20;
      ktScroll : b:=$10;
      ktCtrl : b:=$04;
      ktAlt : b:=$08;
      ktLShift : b:=$02;
      ktRShift : b:=$01;
      end;
      if (mem[0:$417] and b)<>0 then GetLock:=true
      else GetLock:=false;
      end;

      procedure SetLock(lock:TKeytype; On:Boolean);
      var
      b:byte;
      begin
      case lock of
      ktCaps : b:=$40;
      ktNum : b:=$20;
      ktScroll : b:=$10;
      ktCtrl : b:=$04;
      ktAlt : b:=$08;
      ktLShift : b:=$02;
      ktRShift : b:=$01;
      end;
      if On then
      mem[0:$417]:=mem[0:$417] or b
      Else
      mem[0:$417]:=mem[0:$417] and not b;
      end;
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Linux - Состояние Num Lock

Сообщение swa1 » 19.03.2010 13:07:26

Спасибо за ответ!

coyot.rush писал(а):взято http://vbrus.narod.ru/PascalInfo3.htm

Тут я был, смотрел.... Но в linux нет массива mem..... :( , точнее есть такой файл в /dev но по этим адресам ничего не видно.
Как я понял, это отображение оперативной...
coyot.rush писал(а):заюзать асм http://forum.developing.ru/archive/inde ... 13857.html Должно работать под любой осью.

Только не под виндой начиная с 2000...
Ща буду пробовать. Спасибо еще раз

Добавлено спустя 1часа 10 минут 13 секунд:
Код: Выделить всё
procedure OffNumLock;
begin
{$ASMMODE INTEL}
asm
    xor ax, ax
    mov ds,ax
    mov byte ptr ds:[0417h],al
    ret
end;     

Segmentacion fault :(

Добавлено спустя 2часа 18 минут 7 секунд:
Кто то знает под linux аналог mem[0:$417]
Аватара пользователя
swa1
новенький
 
Сообщения: 80
Зарегистрирован: 25.09.2007 11:04:08
Откуда: Ялта


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru