シフトキーの反応
1 はじめに
前のセクションでは、キーボードの応答の処理に多くのエネルギーを費やしました。
これまでのところ、私たちのカーネルは、指定されたウィンドウに主要な文字を正確かつ合理的に表示できます。
しかし、現在のカーネルが Shift キーを押しても反応しないという点がまだ残念です。
Shift キーを押してから数字キー 1 を押します
その場合、表示される文字は「1」ではなく「!」になるはずです。
ここで扱うのはShiftキーのクリック処理への対応です。
2.コード
Shift キーを押してから数字キー 1、2、3 をクリックするとわかります。
表示されるのは数字ではなく、対応する特殊文字です。
対応するコードの実装を見てみましょう
最初に変更する必要があるのはwrite_vga_desktop.cです。
static char keytable1[0x80] = {
0, 0, '!', '@', '#', '$', '%','^', '&', '*', '(', ')', '-', '=', '~', 0, 0,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`', '{', 0, 0, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', '+', '*', 0, 0, '}', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '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
};
int key_shift = 0;
まず、入力テーブル keytable1 と変数 key_shift を追加しました。
Shift キーを押すと、この変数の値は 0 以外になります。
シフトキーを離すと、この変数の値は 0 に戻ります。
同様に、keytable1 テーブルは、Shift キーが押されたときにキーボード文字を表示するときに使用されます。
Shift キーが押されていない場合は、キーテーブル テーブルを使用します。
char transferScanCode(int data) {
if (data == 0x2a) {//left shift key down
key_shift |= 1;
}
if (data == 0x36) {
//right shift key down
key_shift |= 2;
}
if (data == 0xaa) {
//left shift key up
key_shift &= ~1;
}
if (data == 0xb6) {
//right shift key up
key_shift &= ~2;
}
if (data == 0x2a || data == 0x36 || data == 0xaa || data == 0xb6 ||
data >= 0x54) {
return 0;
}
char c = 0;
if (key_shift == 0 && data<0x54 && keytable[data] != 0) {
c = keytable[data];
}
else if (key_shift != 0 && data < 0x80 && keytable1[data] != 0){
c = keytable1[data];
}
else {
c = 0;
}
return c;
}
上記の関数は、キー押下によって生成されたスキャン コードとブレーク コードを処理するために使用されます。
左シフト キーを押すと、キーボードから送信されるスキャン コードは 0x2a になります。
右側のシフトキーを押すと、キーボードのスキャンコードは0x36になります。
左シフト キーを放すと、キーボードから送信されるブレーク コードは 0xaa になります。
右側のシフト キーを放した後、キーボードから送信されるブレーク コードは 0xb6 です。
左シフト キーを押すと、key_shift の値が 1 に設定されます。
右シフトキーを押すと、key_shift の値は 2 になります。
Shift キーを放すと、key_shift の値が 0 に変わります。
コードから、key_shift の値が 0 に等しくない場合、つまり Shift キーが押された場合もわかります。
次に、keytable1 に移動して、キーに対応する文字を見つけます。
key_shift 値が 0 の場合、つまり Shift キーが押されていない場合。
次に、キーテーブル テーブルに移動して、キーに対応する文字を見つけます。
文字の表示方法を見てみましょう
void CMain(void) {
....
for(;;) {
....
else if (key_to == 0) {
if (transferScanCode(data) != 0 && cursor_x < 144) {
boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, COL8_FFFFFF,cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
char c = transferScanCode(data);
char buf[2] = {c, 0};
showString(shtctl, shtMsgBox, cursor_x, 28, COL8_000000, buf);
cursor_x += 8;
stop_task_A = 1;
boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, cursor_c, cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
}
}
....
}
void console_task(struct SHEET *sheet) {
....
for(;;) {
....
else {
if (cursor_x < 240 && transferScanCode(i) != 0) {
boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, sheet, cursor_x, 28, cursor_x+8, 44);
s[0] = transferScanCode(i);
s[1] = 0;
showString(shtctl, sheet, cursor_x, 28, COL8_FFFFFF, s);
cursor_x += 8;
}
....
}
}
上記のコードから、それがコンソール ウィンドウであるかテキスト ボックス ウィンドウであるかがわかります。
文字を表示する前に、transferScanCode 関数を呼び出して、キーボードから送信された値を変換します。
変換結果が 0 でない場合は、結果の文字がウィンドウに表示されます。
上記のコードを完了すると、この記事の冒頭で説明した実行結果を取得できます。