3 extern scan2key_t *kbd_scan2key_tab;
4 extern scan2mod_t *kbd_scan2mod_tab;
6 /* State of keyboard matrix and key press reporting */
8 unsigned char key_down_arr[KBD_SCAN_CNT];
9 unsigned char key_chng_arr[KBD_SCAN_CNT];
10 unsigned char key_hit;
16 /* Internal state for repeat processing */
20 kbd_interval_t key_time;
22 #define KEY_STATE_IDLE 0
23 #define KEY_STATE_PUSH 1
24 #define KEY_STATE_RELEASE 2
25 #define KEY_STATE_REPEAT 4
26 #define KEY_STATE_NOISE 8
27 #define KEY_STATE_BUSY (KEY_STATE_PUSH|KEY_STATE_RELEASE)
31 * kbd_scan - Scan keyboard matrix and report requests for state change
33 * Scans keyboard matrix connected row by row by calling function
34 * mx1_kbd_onerow(). Number of scanned output lines is defined
35 * by %KBD_SCAN_CNT. Checks read keyboard state against @key_down_arr
36 * and updates @key_change_arr array. The @key_down_arr state is
37 * left unchanged. It is changed later by kbd_down() function.
38 * Returns 0, if no keyboard activity is found. Returns 1
39 * if at least one key is pressed. Returns 2 or 3 in case
46 unsigned char mask, val, chng;
47 for(i=0,mask=1;i<KBD_SCAN_CNT;i++,mask<<=1) {
49 chng=val^key_down_arr[i];
54 /* mx1_kbd_onerow(~0); */
60 * kbd_scan2mod - Propagate keyboard matrix changes between modifiers
61 * @scan_code: Scan code of last detected key change
63 * Functions check keyboard matrix state in @key_down_arr.
64 * It updates @key_mod according to @key_down_arr and
65 * modifiers transformations table @kbd_scan2mwmod_tab.
68 kbd_scan2mod(int scan_code)
70 unsigned char val, chng;
72 scan2mod_t *mt=kbd_scan2mod_tab;
74 for(;(s=mt->scan);mt++) {
77 val=key_down_arr[s/KBD_RET_CNT]&(1<<(s%KBD_RET_CNT));
84 key_mod&=~mt->set_mod;
90 * kbd_down - Detects changed key scancode and applies changes to matrix state
92 * Functions check @key_chng_arr and process changes.
93 * It updates its internal state @key_state, does
94 * noise cancellation and repeat timing, then updates
95 * @key_down_arr, stores detected scancode to @key_last_changed
96 * and calls modifiers processing kbd_scan2mod().
97 * Return value is zero if no change is detected.
98 * In other case evaluated scancode is returned.
99 * Variable @key_hit signals by value 1 pressed key, by value
108 if(!(key_state&KEY_STATE_BUSY)){
109 for(i=0;i<KBD_SCAN_CNT;i++) {
110 if(!(val=key_chng_arr[i])) continue;
111 for(j=0;!(val&1);j++) val>>=1;
112 key_last_changed=i*KBD_RET_CNT+j+1;
113 if(key_down_arr[i]&(1<<j)){
114 key_time=KEY_TIMER+KEY_PUSH_T;
115 key_state=KEY_STATE_RELEASE;
117 key_time=KEY_TIMER+KEY_RELEASE_T;
118 key_state=KEY_STATE_PUSH;
122 if(key_state==KEY_STATE_IDLE)
125 if(!key_last_changed){
126 key_state=KEY_STATE_IDLE;
129 i=(key_last_changed-1)/KBD_RET_CNT;
130 j=(key_last_changed-1)%KBD_RET_CNT;
131 if(!(key_chng_arr[i]&(1<<j))){
133 if(!(key_state&KEY_STATE_NOISE)){
134 key_time=KEY_TIMER+KEY_RELEASE_T;
135 key_state|=KEY_STATE_NOISE;
141 if(KEY_TIMER) key_use_timer=1;
142 if(key_state&KEY_STATE_REPEAT) return 0;
144 if((long)(KEY_TIMER-key_time)<0) return 0;
147 if(key_state==KEY_STATE_PUSH) {
148 key_down_arr[i]|=1<<j;
149 kbd_scan2mod(key_last_changed);
150 key_state=KEY_STATE_REPEAT;
151 key_time=KEY_TIMER+KEY_REPFIRST_T;
153 return key_last_changed;
154 } else if(key_state==KEY_STATE_REPEAT) {
155 key_time=KEY_TIMER+KEY_REPNEXT_T;
157 return key_last_changed;
158 } else if(key_state==KEY_STATE_RELEASE) {
159 key_down_arr[i]&=~(1<<j);
160 kbd_scan2mod(key_last_changed);
161 key_state=KEY_STATE_IDLE;
163 return key_last_changed;
165 key_state=KEY_STATE_IDLE;
170 * kbd_scan2key - Converts scancode to kbd_key_t keyboard values
171 * @scan: Detected scancode
173 * Computes kbd_key_t value for detected scancode.
174 * Uses @kbd_scan2key_tab transformation table
175 * and @key_mod modifiers information.
177 kbd_key_t kbd_scan2key(int scan)
179 if((key_mod&KBDMOD_SGM_SC)&&kbd_scan2key_tab[scan].sc)
180 return kbd_scan2key_tab[scan].sc;
181 return kbd_scan2key_tab[scan].bc;