java開發系統核心 鍵盤和視窗關閉API

2021-08-07 09:36:09 字數 3278 閱讀 7832

在上節,我們成功的執行起了視窗程式,但是生成的視窗無法關閉,本節我們要在核心提供乙個關閉視窗的api,還要提供乙個鍵盤訊息獲取的api,這樣應用程式就可以等待乙個某個按鍵,當使用者按下按鍵後,就可以呼叫視窗關閉api將視窗從桌面上消除。

視窗關閉api的設定如下:

edx = 14

ebx = 視窗控制代碼

然後在kernel_api中新增如下**:

int* kernel_api(int edi, int esi, int ebp, int esp,

int ebx, int edx, int ecx, int eax)

....

}

接著我們在win_sheet.h中增加sheet_free函式的定義:

void sheet_free(struct shtctl* shtctl,struct sheet *sht);
在win_sheet.c 中增加對它的實現:

void sheet_free(struct shtctl *shtctl, struct sheet *sht) 

sht->flags = 0;

return;

}

最後我們在api_call.asm中增加**,把核心api跟應用程式的呼叫介面銜接起來:

api_closewin:

;void api_closewin(int win);

push ebx

mov edx, 14

mov ebx, [esp+8]

int 02dh

pop ebx

ret

完成上面**後,在應用程式中直接呼叫api_closewin就可以關閉視窗了,然而如果直接呼叫的話,視窗便會在桌面上出現後就立馬消失,為了能讓視窗在桌面上存在一段時間後再關閉,我們可以在核心提供乙個鍵盤訊息api,這樣應用程式就可以監控按鍵訊息,當使用者按下回車鍵後再呼叫api_closewin關閉視窗。

鍵盤api的配置如下:

edx = 15

eax = 0 表示鍵盤沒有輸入時,api直接返回-1,不休眠

= 1 表示鍵盤沒有輸入時進入休眠狀態,知道有鍵盤輸入為止

eax = 輸入的鍵盤字元掃瞄碼

於是我們在kernel_api中新增如下**:

int* kernel_api(int edi, int esi, int ebp, int esp,

int ebx, int edx, int ecx, int eax)

....

}

handle_keyboard用於監控鍵盤輸入,一旦有鍵盤輸入後,將鍵盤的掃瞄碼放入reg,這樣就能把結果返回給使用者程式了。它的實現如下:

int handle_keyboard(struct task *task, int eax, int* reg)  else 

}i = fifo8_get(&task->fifo);

if (i <= 1) else

if (i == 2) else

}return

0;}

task對應的是控制台程序物件,由於使用者程式是由控制台啟動的,因此使用者程式的程序物件跟控制台是一樣的。在死迴圈裡,**看看控制台程序的佇列有沒有輸入,如果沒有輸入,並且eax的值是0,那麼它直接把-1返回給使用者程式,如果eax的值是0,那麼迴圈繼續,知道等待到有使用者輸入為止。

當輸入佇列返回的值小於2時,那麼該值對應的是游標閃爍的訊息,用於視窗出現在控制台的上方,所以我們**中游標的顏色設定成黑色,這樣游標就無需在控制台上閃來閃去了。

如果從佇列中返回來的值大於2,那表明核心獲取了鍵盤輸入,於是我們直接把鍵盤掃瞄碼放入reg,直接返回給應用程式。接著再api_call.asm中完成相應彙編**:

api_getkey:

;int api_getkey(int mode)

mov edx, 15

mov eax, [esp+4] ;mode

int 02dh

ret

void api_putchar(int c);

void api_putstr(char *s);

int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);

void api_putstrwin(int win, int x, int y, int col, int len, char *str);

void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);

void api_point(int win, int x, int y, int col);

void api_refreshwin(int win, int x0, int y0, int x1, int y1);

void api_linewin(int win, int x0, int y0, int x1, int y1, int col);

void api_closewin(int win);

int api_getkey(int mode);

#define _a 214013ll

#define _b 2531011ll

int ran = 23;

int rand()

void main()

api_refreshwin(win, 6, 26, 154, 90);

for(;;)

}api_closewin(win);

return;

}

在**中,我們建立乙個視窗後,進入乙個死迴圈,在迴圈中我們呼叫api_key獲取鍵盤訊息,輸入1是為了沒有鍵盤輸入時,持續在核心中等待,知道有鍵盤輸入為止,如果有鍵盤輸入,並且其掃瞄碼是0x1c,也就是使用者按下了回車鍵,那麼程式結束迴圈往下走,呼叫api_closewin將視窗關閉。

上面**執行後,在控制台中輸入hlt,啟動應用程式,可以看到有乙個視窗出現在桌面上:

此時我們在鍵盤上按下回車鍵,你會發現視窗消失了:

java開發系統核心 依靠多工實現多視窗

為了讓多工的特性展示的更直觀,本節,我們基於多工的基礎上,為系統實現多個視窗特效,每個視窗都執行於乙個任務或程序。由於視窗基於各自不同的程序,因此視窗自身的變化更新不會影響到其他視窗。void cmain void int i 0 for i 0 i 2 i sheet slide shtctl,s...

java開發系統核心 自動化程序切換

我們已經通過時鐘中斷完成了兩個程序間的相互切換。但當前實現有很大的缺陷,例如我們只能在兩個指定的程序間切換,如果要想增添新的程序,那麼,沒增加乙個程序,按照當前模式,我們只能再增加相應 這顯然是不可接受的。因此,這節,我們希望完成程序的切換機制,使得有新程序時,我們無需改動 程序的管理機制會自動把新...

java開發系統核心 讓核心從嚴重錯誤中恢復

微軟早期的dos系統,存在乙個嚴重的問題是,如果應用程式執行出現問題,它會導致整個系統完全奔潰掉,我們當前的系統核心也存在這一的問題,例如開啟api call.asm,其內容如下 section s32 bits 32 call main retf api putchar mov edx,1 mov...