e-mail    Debatní kniha    Mapa stránek    Hlavní  
 perličky 
 

Kontrola myši a stisku klávesy

Petr Blahoš

Program využívá přerušení 09H, které se vyvolá při každém stisku klávesy, a exitovou rutinu myši.

Přerušení 09h vyvolané při každém stisku klávesy přečte kód klávesy z portu 60H a zapíše ji do kruhového bufferu.

Předefinované přerušení zavolá původní přerušení, potom zjistí, zda byla stisknuta klávesa, tuto klávesu z bufferu vybere, zapíše její scan kód a ASCII kód do proměnné keycode a what nastaví na KEY.

Exitová rutina myši se vyvolá při stisku levého nebo pravého tlačítka. Nastaví proměnné pos_x a pos_y na aktuální souřadnice kurzoru, inkrementuje counter a proměnnou what nastaví na MOUSE.

Při čekání na vstup teď stačí vynulovat proměnnou what a potom ji testovat. Výhoda tohoto způsobu je v tom, že se nemusejí volat funkce, které testují vstup z klávesnice nebo z myši, ale stačí testovat proměnnou what, což není časově tak náročné a navíc se přitom může vykonávat ještě jiná činnost.

Program byl napsán a odladěn v Borland C 2.0.
Poznámky k exitové rutině myši:

Přerušení 33h:
  * Definice exitové rutiny -- služba 0Ch (AX=0Ch)
  * Výměna exitové rutiny   -- služba 14h (AX=14h)
  * Vstup (pro obě služby stejný):
     CX=aktivační maska
     DX=offset exitové rutiny
     ES=její segment
Aktivační maska (nastaven bit):
  * 0: změna polohy
  * 1: stisk levého tlačítka
  * 2: uvolnění levého tlačítka
  * 3: stisk pravého tlačítka
  * 4: uvolnění pravého tlačítka
  * 5: stisk středního tlačítka
  * 6: uvolnění středního tlačítka
  * ostatní bity: nastavit na nulu
Exitová rutina musí být FAR a musí zachovávat obsah registrů.

Stav registrů v exitové rutině:
  * CX: x-ová souřadnice kurzoru
  * DX: y-ová souřadnice kurzoru
  * BX: stav tlačítek (nastaven bit):
     0: levé tlačítko stisknuto
     1: pravé tlačítko stisknuto
     2: střední tlačítko stisknuto
Tato problematika je podrobněji popsána v [1].

Literatura:
[1] NortonGuide: MS-DOS verze 3.30
[2] NortonGuide: BIOS Technical Reference
#include<stdio.h> #include<dos.h> #define KEY 5 #define MOUSE 7 void interrupt (*old09)(...); volatile int what=0, // stav counter=0, // počet stisků tlačítek myši keycode=0, // (scan code)*256+(ASCII code) // stisknuté klávesy pos_x=0, // x-pozice kurzoru myši // při posledním stisku pos_y=0; // y-pozice kurzoru myši // při posledním stisku void huge domouse() // nová exitová rutina { pos_x = _CX; pos_y = _DX; what = MOUSE; counter++; } void interrupt dokeyboard(...) { unsigned int far* tail= (unsigned int far*)(MK_FP(0x0040,0x001c)); // tail bufferu klávesnice unsigned char far* head= (unsigned char far*)(MK_FP(0x0040,0x001a)); // head bufferu klávesnice old09(); // volání původní obsluhy přerušení if(*tail!=*head) // byla přečtena klávesa? { what = KEY; keycode =peek(0x0040,*head); if(*head==0x003c) // posunutí konce kruhového *head = 0x001e; // bufferu klávesnice o 2 bajty else // nebo na začátek bufferu *head+= 2; pokeb(0x0040,0x001a,*tail); } } void main(void) { _AX=0x0000; // init myši geninterrupt(0x33); _AX=0x0001; // zobrazení kurzoru myši geninterrupt(0x33); //-----------------// nastavení uživat. exitové rutiny _DX=FP_OFF(domouse); _ES=FP_SEG(domouse); _AX=0x000C; // služba 0x0C - zavedení uživ.exit.rutiny _CX=0x000A; // stisk levého nebo pravého tlačítka geninterrupt(0x33); //-----------------// přesměrování přerušení 09 old09 = getvect(0x09); setvect(0x09,dokeyboard); for(;keycode!=0x11b;) // Esc { what=0; for(;what==0;); // čekání na stisk klávesy switch(what) // nebo tlačítka myši { case KEY : printf("\nStisknuta klavesa code=0x%x", keycode); break; case MOUSE : printf("\nTlacitko mysi stisknuto %ukrat, x=%u, y=%u", counter,pos_x,pos_y); } } _AX=0x0002; // zhasnutí kurzoru myši geninterrupt(0x33); //-----------------// zrušení uživatelské exitové rutiny _AX=0x000C; _CX=0x0000; _DX=0x0000; _ES=0x0000; geninterrupt(0x33); //-----------------// obnoví původní přerušení 09 setvect(0x09,old09); }


Pascal - hlavní
Překladače
Vlastní články
Převzaté články
Věci na stáhnutí
Odkazy k tématu
BP7 buglist
Chyba Run-time 200

BASIC