time_stamp_freq=SYS_TIMER_FREQ*( GetTimeStamp-time_stamp_start)/ (ReadSysTimer-sys_timer_start); time_stamp_kHz_freq=time_stamp_freq/1000; #help_index "Char/Input" U8Fifo *scan_code_fifo=NewU8Fifo(128); U8 last_down_scan_code=0; void KbdCmdSend(U8 port, U1 val,BoolU4 *btimeout=NULL) { LTDate timeout=BootTime+LTDATE_FREQ/10; do { if (!(InP(KEYB_CTRL)&2)) { timeout=0; break; } } while (BootTime=0x50) return 0; else return table[sc]; } U1 scan_code_map[0x100]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,SC_SHIFT,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,SC_CR,SC_CTRL,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,SC_HOME,SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END, SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INSERT,SC_DELETE,0,0,0,0,0,0,0,0,SC_GUI,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; U1 num_lock_map[0x100]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,8,9,10,0,5,6,7,0,2, 3,4,11,0x34,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,SC_CR,SC_CTRL,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,SC_HOME,SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END, SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INSERT,SC_DELETE,0,0,0,0,0,0,0,0,SC_GUI,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; public void SetTypeMatic(U1 delay) { KbdCmdSend(KEYB_CTRL,0xA7); //Disable Mouse KbdCmdSend(KEYB_CTRL,0xAE); //Enable Keyboard KbdCmdSend(KEYB_PORT,0xF3); KbdCmdSend(KEYB_PORT,delay); //Typematic rate KbdCmdSend(KEYB_CTRL,0xA8); //Enable Mouse } #help_index "Char/Conversion" public I1 *ASCIIToKeyName(I8 ch,BoolU4 include_ctrl=TRUE) { I8 i; I1 buf[64]; *buf=0; if (ch) { if (ch<26) { if (ch==CH_CR) StrCat(buf,"ENTER"); else if (ch==CH_ESC) StrCat(buf,"ESC"); else if (ch==CH_BACKSPACE) StrCat(buf,"BACKSPACE"); else if (ch==CH_TAB) StrCat(buf,"TAB"); else if (ch==CH_CURSOR) StrCat(buf,"CURSOR"); else { if (include_ctrl) StrCat(buf,"CTRL "); buf[i=StrLen(buf)]=ch-1+'A'; buf[i+1]=0; } } else if (Bt(printable_chars_bitmap,ch)) { if (ch==CH_SPACE) StrCat(buf,"SPACE"); else if (ch==CH_SHIFT_SPACE) StrCat(buf,"SHIFT_SPACE"); else { buf[i=StrLen(buf)]=ch; buf[i+1]=0; } } } return NewStr(buf); } public I1 *ScanCodeToKeyName(I8 sc) { I8 ch=ScanCodeToASCII(sc); I1 buf[64],*st; *buf=0; if (sc&SCF_CTRL) StrCat(buf,"CTRL "); if (sc&SCF_ALT) StrCat(buf,"ALT "); if (sc&SCF_SHIFT) StrCat(buf,"SHIFT "); if (ch) { st=ASCIIToKeyName(ch,FALSE); StrCpy(buf+StrLen(buf),st); Free(st); } else { switch (sc.u1[0]) { case SC_BACKSPACE:StrCat(buf,"BACK"); break; case SC_CAPS: StrCat(buf,"CAPS"); break; case SC_NUM: StrCat(buf,"NUM"); break; case SC_SCROLL: StrCat(buf,"SCROLL"); break; case SC_CURSOR_UP:StrCat(buf,"UP"); break; case SC_CURSOR_DOWN:StrCat(buf,"DOWN"); break; case SC_CURSOR_LEFT:StrCat(buf,"LEFT"); break; case SC_CURSOR_RIGHT:StrCat(buf,"RIGHT"); break; case SC_PAGE_UP:StrCat(buf,"PAGE_UP"); break; case SC_PAGE_DOWN:StrCat(buf,"PAGE_DOWN"); break; case SC_HOME: StrCat(buf,"HOME"); break; case SC_END: StrCat(buf,"END"); break; case SC_INSERT: StrCat(buf,"INSERT"); break; case SC_DELETE: StrCat(buf,"DELETE"); break; case SC_F1: StrCat(buf,"F1"); break; case SC_F2: StrCat(buf,"F2"); break; case SC_F3: StrCat(buf,"F3"); break; case SC_F4: StrCat(buf,"F4"); break; case SC_F5: StrCat(buf,"F5"); break; case SC_F6: StrCat(buf,"F6"); break; case SC_F7: StrCat(buf,"F7"); break; case SC_F8: StrCat(buf,"F8"); break; case SC_F9: StrCat(buf,"F9"); break; case SC_F10: StrCat(buf,"F10"); break; case SC_F11: StrCat(buf,"F11"); break; case SC_F12: StrCat(buf,"F12"); break; case SC_GUI: StrCat(buf,"WINDOWS"); break; case SC_PRTSCRN1: StrCat(buf,"PRTSCRN1"); break; case SC_PRTSCRN2: StrCat(buf,"PRTSCRN2"); break; } } return NewStr(buf); } #help_index "Training" I8 display_keys_row=TEXT_ROWS/2; public BoolU4 kbd_display_special_keys=FALSE; void DisplayKeysPopUp() { I8 i; I1 *st; InitLocalTask; Fs->win_left=TEXT_COLS/2-8; Fs->win_top=display_keys_row; Fs->win_right=TEXT_COLS/2+8; Fs->win_bottom=Fs->win_top; Fs->text_attribute=(YELLOW<<4)+BLACK; Fs->border_attribute=(YELLOW<<4)+BLACK; Btr(&Fs->crt_flags,CRTf_HAS_CLOSE_WIN); UseConsoleLtf(NULL); Fs->cur_ltf->flags&=~LTFF_ATTR_BY_PARTITION; Fs->aux_ltf->flags&=~LTFF_ATTR_BY_PARTITION; Fs->cur_ltf->start_text_attribute=(YELLOW<<4)+BLACK; Fs->aux_ltf->start_text_attribute=(YELLOW<<4)+BLACK; st=ScanCodeToKeyName(last_down_scan_code); PrintF("%s",st); Free(st); LtfRecalc(Fs->cur_ltf); Bts(&Fs->crt_flags,CRTf_SHOW); display_keys_row+=4; for (i=0;i<1000;i++) { WinToTop(Fs); Sleep(1); } display_keys_row-=4; } void DisplaySpecialKeys(I8 sc) { I8 ch; if (!(sc&SCF_KEY_UP) && sc&SCF_NEW_KEY ) { ch=ScanCodeToASCII(sc); if (!ch || (ch='a' && ch<='z') { if (ctrl_alt_letter_routines[ch-'a']) { CallInd(ctrl_alt_letter_routines[ch-'a']); goto mostly_done; } } } } } new_key_done: sc|=SCF_NEW_KEY; mostly_done: sys_cur_scan_code=sc|sc2| (sc|sc_raw)<<32; if (kbd_display_special_keys) DisplaySpecialKeys(sys_cur_scan_code); if (Btr(&sys_cur_scan_code,SCf_NEW_KEY)) { Btr(&sys_cur_scan_code,32+SCf_NEW_KEY); U8FifoInsert(scan_code_fifo,sys_cur_scan_code); if (!(sys_cur_scan_code&SCF_KEY_UP)) last_down_scan_code=sys_cur_scan_code; } } #help_index "Input Pointer" public double mxx_scale=0.5, myy_scale=0.5, mzz_scale=1.0; public I8 mxx_prescale=GR_WIDTH/mxx_scale/2.0, myy_prescale=GR_HEIGHT/myy_scale/2.0, mzz_prescale=0/mzz_scale; public I8 mxx=GR_WIDTH>>1, myy=GR_HEIGHT>>1, mzz=0; BoolU4 mouse_buttons[5]; BoolU4 mouse_installed=FALSE; U8 mouse_install_attempts=0; BoolU4 mouse_has_wheel=FALSE; BoolU4 mouse_has_ext_buttons=FALSE; BoolU4 mouse_evt=FALSE; BoolU4 mouse_irqs_working=FALSE; U8 mouse_pkt_size=3; BoolU8 MouseGetDeviceType() { BoolU4 my_btimeout; U1 b; KbdMouseCmdAck(0xF2,&my_btimeout); if (my_btimeout) return FALSE; b=KbdCmdRead; if (b==3) mouse_has_wheel=TRUE; else if (b==4) mouse_has_ext_buttons=TRUE; return TRUE; } BoolU8 MouseReset() { I8 i; BoolU4 my_btimeout,result=FALSE; mouse_has_wheel=FALSE; mouse_has_ext_buttons=FALSE; KbdCmdFlush; KbdCmdSend(KEYB_CTRL,0xAD,&my_btimeout); //Disable Kbd if (my_btimeout) goto done; KbdCmdSend(KEYB_CTRL,0xA8,&my_btimeout); //Enable Mouse if (my_btimeout) goto done; KbdMouseCmdAck(0xFF,&my_btimeout); //Reset if (my_btimeout) goto done; for (i=0;i<250;i++) { KbdCmdRead(&my_btimeout); if (!my_btimeout) break; } KbdCmdRead(&my_btimeout); KbdMouseCmdAck(0xF3,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(200,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(0xF3,&my_btimeout); // enable Mouse if (my_btimeout) goto done; KbdMouseCmdAck(100,&my_btimeout); // Set Rate if (my_btimeout) goto done; KbdMouseCmdAck(0xF3,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(80,&my_btimeout); //Resolution if (my_btimeout) goto done; if (!MouseGetDeviceType) goto done; // enable Mouse KbdMouseCmdAck(0xF3,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(10,&my_btimeout); if (my_btimeout) goto done; if (!MouseGetDeviceType) goto done; // enable Mouse KbdMouseCmdAck(0xE8,&my_btimeout); //Resolution if (my_btimeout) goto done; KbdMouseCmdAck(0x03,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(0xE6,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(0xF3,&my_btimeout); // Set Rate if (my_btimeout) goto done; KbdMouseCmdAck(100,&my_btimeout); if (my_btimeout) goto done; KbdMouseCmdAck(0xF4,&my_btimeout); // enable Mouse if (my_btimeout) goto done; result=TRUE; done: KbdCmdSend(KEYB_CTRL,0xAE); //Enable Keyboard if (mouse_has_wheel || mouse_has_ext_buttons) mouse_pkt_size=4; else mouse_pkt_size=3; if (!result) KbdCmdSend(KEYB_CTRL,0xA7); //Disable Mouse return result; } void MouseHandler() { I8 i,dx,dy,dz,old_x=mxx,old_y=myy,old_z=mzz; U1 mouse_buf[4]; BoolU4 old_buttons[5]; for (i=0;i<5;i++) old_buttons[i]=mouse_buttons[i]; for (i=0;i<4;i++) if (!U1FifoRemove(kbdmouse_fifo,&mouse_buf[i])) mouse_buf[i]=0; mouse_buttons[0] = mouse_buf[0] & 1; mouse_buttons[1] = (mouse_buf[0] & 2) >> 1; mouse_buttons[2] = (mouse_buf[0] & 4) >> 2; mouse_buttons[3] = (mouse_buf[3] & 0x10) >> 4; mouse_buttons[4] = (mouse_buf[3] & 0x20) >> 5; if (mouse_buf[0] & 0x10) dx=mouse_buf[1]-256; else dx=mouse_buf[1]; if (mouse_buf[0] & 0x20) dy=256-mouse_buf[2]; else dy=-mouse_buf[2]; if (mouse_buf[3] & 0x08) dz=(mouse_buf[3]&7)-8; else dz=mouse_buf[3]&7; mxx_prescale+=dx; myy_prescale+=dy; mzz_prescale+=dz; mxx=mxx_prescale*mxx_scale; myy=myy_prescale*myy_scale; mzz=mzz_prescale*mzz_scale; if (mxx < 0) { mxx=0; mxx_prescale=0; } if (mxx>=GR_WIDTH) { mxx=GR_WIDTH-1; mxx_prescale=mxx/mxx_scale; } if (myy < 0) { myy=0; myy_prescale=0; } if (myy>=GR_HEIGHT) { myy=GR_HEIGHT-1; myy_prescale=myy/myy_scale; } if (mxx!=old_x||myy!=old_y||mzz!=old_z) mouse_evt=TRUE; else for (i=0;i<5;i++) if (mouse_buttons[i]!=old_buttons[i]) { mouse_evt=TRUE; break; } } U8 kbdmouse_timeout=0; void ResetKbdMouse(I8 Hz=50) { Btr(&sys_semas[SYS_SEMA_KEY_PRESSED],0); KbdCmdFlush(Hz); U1FifoFlush(kbdmouse_fifo); U8FifoFlush(scan_code_fifo); kbdmouse_timeout=0; OutP(0x21,InP(0x21)&~2); } BoolU8 InstallMouseDriver() { I8 i; Preempt(ON); mouse_installed=FALSE; for(i=0;i<5;i++) mouse_buttons[i]=0; if (MouseReset) mouse_installed=TRUE; ResetKbdMouse; mouse_install_attempts++; mouse_evt=mouse_installed; return mouse_installed; } void HandleKbdMouse() { U1 i; if (U1FifoCnt(kbdmouse_fifo)) { if (kbdmouse_timeout && GetTimeStamp>kbdmouse_timeout) { ResetKbdMouse; return; } if (Btr(&sys_semas[SYS_SEMA_KEY_PRESSED],0)) { while (U1FifoCnt(kbdmouse_fifo)) { if (U1FifoCnt(kbdmouse_fifo)==1) { U1FifoPeek(kbdmouse_fifo,&i); if (i==0xE0) { if (!kbdmouse_timeout) kbdmouse_timeout=GetTimeStamp+time_stamp_freq/50; Bts(&sys_semas[SYS_SEMA_KEY_PRESSED],0); return; } } kbdmouse_timeout=0; KbdHandler; OutP(0x21,InP(0x21)&~2); } } else { if (!mouse_installed) U1FifoFlush(kbdmouse_fifo); else { if (U1FifoCnt(kbdmouse_fifo)>=mouse_pkt_size) { kbdmouse_timeout=0; mouse_evt_time=GetTimeStamp; while (U1FifoCnt(kbdmouse_fifo)>=mouse_pkt_size) MouseHandler; } else if (!kbdmouse_timeout) kbdmouse_timeout=GetTimeStamp+time_stamp_freq/50; } } } else kbdmouse_timeout=0; } #define KBDMOUSE_POLL_RATE 500 U8 last_kbdmouse_poll_time=GetTimeStamp; extern void PollKbdMouse(); TssStruct *poll_kbdmouse_tss=NULL; void PollKbdMouseTsk() { //Poll for a minute I8 i; for (i=0;itime_stamp_freq/KBDMOUSE_POLL_RATE*4) { last_kbdmouse_poll_time=poll_time; ResetKbdMouse(0); if (!poll_kbdmouse_tss) poll_kbdmouse_tss=Spawn(&PollKbdMouseTsk,"Poll KbdMouse"); } else { last_kbdmouse_poll_time=poll_time; while (InP(KEYB_CTRL)&1) { U1FifoInsert(kbdmouse_fifo,InP(KEYB_PORT)); HandleKbdMouse; } } } #help_index "" InitKbd; Spawn(&InstallMouseDriver);