獲取更多操作系統開發相關信息,請參看視頻:
Linux kernel Hacker, 從零構建自己的內核
有了桌面背景,能夠顯示字符串,現在在圖形界面上還少了點東西,那就是鼠標指針,如果有個鼠標能在桌面里動來動去,那系統就有點意思了。
就像前幾節說的那樣,任何圖像都是二維平面上點的集合,把不同位置的點設置成不同顏色,那么我們想要的圖像就顯示出來了,我們先來看看一個用來表示二維圖標的數組:
static char cursor[16][16] = {
"**************..",
"*OOOOOOOOOOO*...",
"*OOOOOOOOOO*....",
"*OOOOOOOOO*.....",
"*OOOOOOOO*......",
"*OOOOOOO*.......",
"*OOOOOOO*.......",
"*OOOOOOOO*......",
"*OOOO**OOO*.....",
"*OOO*..*OOO*....",
"*OO*....*OOO*...",
"*O*......*OOO*..",
"**........*OOO*.",
"*..........*OOO*",
"............*OO*",
".............***"
};
大家看上面的數組是不是有個鼠標的模樣了,只要把*對應的像素點畫成黑色,0代表的像素點畫成白色,. 代表的像素點設置成背景色,那么一個鼠標的圖像就出來了:
我們接下來就通過代碼設置相關像素點的顏色
void init_mouse_cursor(char* mouse, char bc) {
static char cursor[16][16] = {
"**************..",
"*OOOOOOOOOOO*...",
"*OOOOOOOOOO*....",
"*OOOOOOOOO*.....",
"*OOOOOOOO*......",
"*OOOOOOO*.......",
"*OOOOOOO*.......",
"*OOOOOOOO*......",
"*OOOO**OOO*.....",
"*OOO*..*OOO*....",
"*OO*....*OOO*...",
"*O*......*OOO*..",
"**........*OOO*.",
"*..........*OOO*",
"............*OO*",
".............***"
};
int x, y;
for (y = 0; y < 16; y++) {
for (x = 0; x < 16; x++) {
if (cursor[y][x] == '*') {
mouse[y*16 + x] = COL8_000000;
}
if (cursor[y][x] == 'O') {
mouse[y*16 + x] = COL8_FFFFFF;
}
if (cursor[y][x] == '.') {
mouse[y*16 + x] = bc;
}
}
}
}
代碼中把設置成黑色,O設置成白色,. 設置成背景色。有了上面的顏色二維數組后,我們需要把該數組的數值寫入顯存,但顯存是一維數組,所以需要將上面的1616二維數組轉換為一個256字節的數組然后寫入顯存,代碼如下:
void putblock(char* vram, int vxsize, int pxsize,
int pysize, int px0, int py0, char* buf, int bxsize) {
int x, y;
for (y = 0; y < pysize; y++)
for (x = 0; x < pxsize; x++) {
vram[(py0+y) * vxsize + (px0+x)] = buf[y * bxsize + x];
}
}
上面代碼中,vxsize是整個屏幕的寬度,也就是320,pxsize,pysize, bxsize 等于16,也就是二維數值的行和列值, px0,py0是鼠標所在的左上角坐標,有了上面代碼后,在主函數中通過以下調用就能畫出鼠標:
void CMain() {
....
init_mouse_cursor(mcursor, COL8_008484);
putblock(vram, xsize, 16, 16, 80, 80, mcursor, 16);
for(;;){
io_hlt();
}
上面代碼把鼠標畫到左上角坐標為80,80的屏幕處,運行上面代碼,反編譯后加入內核匯編代碼,最后編譯內核,用虛擬機加載后結果如下:
雖然鼠標畫出來,但動不了,那是因為我們還沒有在內核中建立相關機制,要想讓鼠標動起來,我們需要設置中斷處理,當我們觸摸鼠標硬件,硬件會向CPU發送信號,CPU接收信號后引發中斷,放下手中正在處理的任務,去執行中斷代碼,如果這段中斷代碼是我們寫的話,那么我們可以乘此機會重新繪制鼠標,改變鼠標位置,這樣鼠標就動起來了。設置中斷由于涉及到硬件,所以將會是一個難度比較大的技術點,我們又需要操作類似GDT這種數據結構,在后面的時間里,我們會就這些問題深入研究。