Compare commits
1 Commits
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"makefile.launchConfigurations": [
|
||||||
|
{
|
||||||
|
"cwd": "/home/patrick/Sylva/build",
|
||||||
|
"binaryPath": "/home/patrick/Sylva/build/Kernel.elf",
|
||||||
|
"binaryArgs": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -50,26 +50,9 @@ All `string_utils.h` helpers are `static inline` — header-only, no link issues
|
|||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
- **Commits:** `[type] message` — types: `feat`, `fix`, `chore`, `docs`, `refactor`, `optm` (see `git log`).
|
- **Commits:** `[type] message` — types: `feat`, `fix`, `chore`, `docs`, `refactor` (see `git log`).
|
||||||
- **Languages:** C17 (`boot.c`), C++17 (`kernel/`) — `-ffreestanding -fno-stack-protector -fshort-wchar -mno-red-zone -fcf-protection=none`. Kernel adds `-DGNU_EFI_USE_MS_ABI -fno-pic`.
|
- **Languages:** C17 (`boot.c`), C++17 (`kernel/`) — `-ffreestanding -fno-stack-protector -fshort-wchar -mno-red-zone -fcf-protection=none`. Kernel adds `-DGNU_EFI_USE_MS_ABI -fno-pic`.
|
||||||
- **`kernel_main` must be `extern "C"`** — `boot.c` (C) calls into C++ (`kernel/entry.cpp:6`).
|
- **`kernel_main` must be `extern "C"`** — `boot.c` (C) calls into C++ (`kernel/entry.cpp:6`).
|
||||||
- **All UEFI protocol calls must use `uefi_call_wrapper`** — calling the member fn directly page-faults in long mode. See `kernel/main.cpp:23-24` and throughout.
|
- **All UEFI protocol calls must use `uefi_call_wrapper`** — calling the member fn directly page-faults in long mode. See `kernel/main.cpp:23-24` and throughout.
|
||||||
- **Kernel linked at `0x100000`** (`kernel/kernel.ld`); `.bss` start/end symbols exposed as `__bss_start` / `__bss_end`.
|
- **Kernel linked at `0x100000`** (`kernel/kernel.ld`); `.bss` start/end symbols exposed as `__bss_start` / `__bss_end`.
|
||||||
- **No tests, no CI, no lint config** — `make` is the only verification step. Boot by hand in QEMU to confirm kernel output in `serial.log`.
|
- **No tests, no CI, no lint config** — `make` is the only verification step. Boot by hand in QEMU to confirm kernel output in `serial.log`.
|
||||||
|
|
||||||
## Global state
|
|
||||||
|
|
||||||
| Symbol | File | Type |
|
|
||||||
|--------|------|------|
|
|
||||||
| `ST` | `kernel/entry.cpp` | `EFI_SYSTEM_TABLE*` — saved from UEFI boot |
|
|
||||||
| `g_gfx` | `include/graphics/context.h` | `gfx_context` — GOP framebuffer info |
|
|
||||||
| `g_draw_target` | `include/graphics/context.h` | `draw_target` — current draw surface |
|
|
||||||
| `g_pmm` | `include/memory/pmm.h` | `pmm_t` — physical page allocator state |
|
|
||||||
| `g_serial` | `kernel/serial.cpp` | `serial_context` — serial protocol handle |
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- **No paging** — kernel runs in physical memory, identity-mapped.
|
|
||||||
- **No libc** — all string/memory ops go through `string_utils.h` (header-only, `static inline`).
|
|
||||||
- **Window switching** uses Shift+F10 (hardcoded PS/2 scan codes in `kernel/graphics/layer.cpp`).
|
|
||||||
- **`third_party/`** is empty — no external deps beyond bundled gnu-efi in `efi/`.
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ BOOT_OBJ = build/boot.o
|
|||||||
KERNEL_ASMFLAGS = -Iinclude -Iefi/inc -ffreestanding -fno-stack-protector -fno-stack-check \
|
KERNEL_ASMFLAGS = -Iinclude -Iefi/inc -ffreestanding -fno-stack-protector -fno-stack-check \
|
||||||
-fshort-wchar -mno-red-zone -fcf-protection=none -g
|
-fshort-wchar -mno-red-zone -fcf-protection=none -g
|
||||||
|
|
||||||
KERNEL_CPP := $(shell find kernel graphics fonts devices -name '*.cpp' -type f)
|
KERNEL_CPP := $(shell find kernel graphics fonts -name '*.cpp' -type f)
|
||||||
KERNEL_ASM := $(shell find kernel -name '*.S' -type f)
|
KERNEL_ASM := $(shell find kernel -name '*.S' -type f)
|
||||||
|
|
||||||
KERNEL_OBJ := $(KERNEL_CPP:%.cpp=build/%.o) $(KERNEL_ASM:%.S=build/%.o)
|
KERNEL_OBJ := $(KERNEL_CPP:%.cpp=build/%.o) $(KERNEL_ASM:%.S=build/%.o)
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
#include <devices/cursor.h>
|
|
||||||
#include <devices/mouse.h>
|
|
||||||
#include <graphics/draw.h>
|
|
||||||
#include <graphics/context.h>
|
|
||||||
#include <memory/heap.h>
|
|
||||||
#include <common.h>
|
|
||||||
|
|
||||||
// 经典箭头光标位图 (12x16)
|
|
||||||
// 0=透明, 1=白色填充, 2=黑色轮廓
|
|
||||||
static const SUINT8 g_cursor_bitmap[CURSOR_H][CURSOR_W] = {
|
|
||||||
{2,0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{2,2,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{2,1,2,0,0,0,0,0,0,0,0,0},
|
|
||||||
{2,1,1,2,0,0,0,0,0,0,0,0},
|
|
||||||
{2,1,1,1,2,0,0,0,0,0,0,0},
|
|
||||||
{2,1,1,1,1,2,0,0,0,0,0,0},
|
|
||||||
{2,1,1,1,1,1,2,0,0,0,0,0},
|
|
||||||
{2,1,1,1,1,1,1,2,0,0,0,0},
|
|
||||||
{2,1,1,1,1,1,1,1,2,0,0,0},
|
|
||||||
{2,1,1,1,1,1,1,1,1,2,0,0},
|
|
||||||
{2,1,1,1,1,1,2,2,2,2,2,0},
|
|
||||||
{2,1,1,2,1,2,0,0,0,0,0,0},
|
|
||||||
{2,1,2,0,0,2,0,0,0,0,0,0},
|
|
||||||
{2,2,0,0,0,0,2,0,0,0,0,0},
|
|
||||||
{2,0,0,0,0,0,2,0,0,0,0,0},
|
|
||||||
{0,0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static layer_t* g_cursor_layer = NULL;
|
|
||||||
|
|
||||||
void cursor_init(void) {
|
|
||||||
g_cursor_layer = layer_create("cursor", LAYER_TYPE_MOUSE, CURSOR_W, CURSOR_H);
|
|
||||||
if (!g_cursor_layer) return;
|
|
||||||
|
|
||||||
layer_set_z(g_cursor_layer, 9999);
|
|
||||||
|
|
||||||
// 将位图写入图层缓冲区,Reserved 用作 alpha(0=透明, 255=不透明)
|
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf = g_cursor_layer->buffer;
|
|
||||||
for (UINT32 y = 0; y < CURSOR_H; y++) {
|
|
||||||
for (UINT32 x = 0; x < CURSOR_W; x++) {
|
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = &buf[y * CURSOR_W + x];
|
|
||||||
SUINT8 px = g_cursor_bitmap[y][x];
|
|
||||||
if (px == 1) {
|
|
||||||
dst->Blue = 255; dst->Green = 255; dst->Red = 255; dst->Reserved = 255;
|
|
||||||
} else if (px == 2) {
|
|
||||||
dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 255;
|
|
||||||
} else {
|
|
||||||
dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始位置:屏幕中心
|
|
||||||
layer_set_pos(g_cursor_layer,
|
|
||||||
(SSINT32)(g_gfx.hr / 2),
|
|
||||||
(SSINT32)(g_gfx.vr / 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void cursor_update(void) {
|
|
||||||
if (!g_cursor_layer) return;
|
|
||||||
|
|
||||||
SSINT32 cx = (SSINT32)(g_gfx.hr / 2) + mouse_get_x();
|
|
||||||
SSINT32 cy = (SSINT32)(g_gfx.vr / 2) + mouse_get_y();
|
|
||||||
|
|
||||||
if (cx < 0) cx = 0;
|
|
||||||
if (cy < 0) cy = 0;
|
|
||||||
if (cx + (SSINT32)CURSOR_W > (SSINT32)g_gfx.hr) cx = (SSINT32)g_gfx.hr - CURSOR_W;
|
|
||||||
if (cy + (SSINT32)CURSOR_H > (SSINT32)g_gfx.vr) cy = (SSINT32)g_gfx.vr - CURSOR_H;
|
|
||||||
|
|
||||||
layer_set_pos(g_cursor_layer, cx, cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
layer_t* cursor_get_layer(void) {
|
|
||||||
return g_cursor_layer;
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
#include <devices/mouse.h>
|
|
||||||
#include <interrupt/idt.h>
|
|
||||||
#include <interrupt/pic.h>
|
|
||||||
#include <serial.h>
|
|
||||||
|
|
||||||
static inline void outb(UINT16 port, UINT8 val) {
|
|
||||||
ASM("outb %0, %1" : : "a"(val), "Nd"(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UINT8 inb(UINT16 port) {
|
|
||||||
UINT8 ret;
|
|
||||||
ASM("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待 PS/2 控制器输入缓冲区清空
|
|
||||||
static void ps2_wait_input(void) {
|
|
||||||
for (int i = 0; i < 100000; i++) {
|
|
||||||
if (!(inb(PS2_STATUS_PORT) & PS2_STAT_IBF)) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 等待 PS/2 控制器输出缓冲区有数据
|
|
||||||
static void ps2_wait_output(void) {
|
|
||||||
for (int i = 0; i < 100000; i++) {
|
|
||||||
if (inb(PS2_STATUS_PORT) & PS2_STAT_OBF) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 向 PS/2 控制器发送命令
|
|
||||||
static void ps2_write_cmd(UINT8 cmd) {
|
|
||||||
ps2_wait_input();
|
|
||||||
outb(PS2_CMD_PORT, cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 读取 PS/2 控制器返回的数据
|
|
||||||
static UINT8 ps2_read_data(void) {
|
|
||||||
ps2_wait_output();
|
|
||||||
return inb(PS2_DATA_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 向辅助端口(鼠标)发送数据
|
|
||||||
static void ps2_write_mouse(UINT8 data) {
|
|
||||||
ps2_write_cmd(0xD4); // Write to Auxiliary Device
|
|
||||||
ps2_wait_input();
|
|
||||||
outb(PS2_DATA_PORT, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 鼠标 3 字节数据包状态
|
|
||||||
static int g_pkt_phase = 0; // 0=byte0, 1=byte1, 2=byte2
|
|
||||||
static UINT8 g_pkt_byte0 = 0;
|
|
||||||
static UINT8 g_pkt_byte1 = 0;
|
|
||||||
|
|
||||||
// 鼠标光标位置(相对于屏幕中心)
|
|
||||||
static volatile SSINT32 g_mouse_x = 0;
|
|
||||||
static volatile SSINT32 g_mouse_y = 0;
|
|
||||||
static volatile bool g_mouse_btn_l = false;
|
|
||||||
static volatile bool g_mouse_btn_r = false;
|
|
||||||
static volatile bool g_mouse_btn_m = false;
|
|
||||||
|
|
||||||
// IRQ12 处理函数
|
|
||||||
static void mouse_irq_handler(trap_frame* frame) {
|
|
||||||
(void)frame;
|
|
||||||
pic_send_eoi(PS2_MOUSE_IRQ);
|
|
||||||
|
|
||||||
// 读取状态寄存器,检查输出缓冲区是否有数据
|
|
||||||
UINT8 status = inb(PS2_STATUS_PORT);
|
|
||||||
if (!(status & PS2_STAT_OBF)) return;
|
|
||||||
|
|
||||||
UINT8 data = inb(PS2_DATA_PORT);
|
|
||||||
|
|
||||||
// 解析 3 字节数据包
|
|
||||||
switch (g_pkt_phase) {
|
|
||||||
case 0: // byte 0: 按钮 + 标志
|
|
||||||
if (!(data & PS2_MOUSE_ALWAYS1)) return; // 无效字节,重新同步
|
|
||||||
g_pkt_byte0 = data;
|
|
||||||
g_pkt_phase = 1;
|
|
||||||
break;
|
|
||||||
case 1: // byte 1: X delta
|
|
||||||
g_pkt_byte1 = data;
|
|
||||||
g_pkt_phase = 2;
|
|
||||||
break;
|
|
||||||
case 2: // byte 2: Y delta
|
|
||||||
g_pkt_byte0 = g_pkt_byte0; // 确保编译器不优化
|
|
||||||
g_pkt_byte1 = g_pkt_byte1;
|
|
||||||
|
|
||||||
// 解析按钮状态
|
|
||||||
g_mouse_btn_l = (g_pkt_byte0 & PS2_MOUSE_LEFT) != 0;
|
|
||||||
g_mouse_btn_r = (g_pkt_byte0 & PS2_MOUSE_RIGHT) != 0;
|
|
||||||
g_mouse_btn_m = (g_pkt_byte0 & PS2_MOUSE_MIDDLE) != 0;
|
|
||||||
|
|
||||||
// 解析 X delta
|
|
||||||
SSINT32 dx = (SSINT32)(SSINT8)g_pkt_byte1;
|
|
||||||
if (g_pkt_byte0 & PS2_MOUSE_X_SIGN) dx |= 0xFFFFFF00;
|
|
||||||
|
|
||||||
// 解析 Y delta
|
|
||||||
SSINT32 dy = (SSINT32)(SSINT8)data;
|
|
||||||
if (g_pkt_byte0 & PS2_MOUSE_Y_SIGN) dy |= 0xFFFFFF00;
|
|
||||||
|
|
||||||
// 更新光标位置(Y 轴在屏幕上向下为正)
|
|
||||||
g_mouse_x += dx;
|
|
||||||
g_mouse_y -= dy;
|
|
||||||
|
|
||||||
g_pkt_phase = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 丢弃输出缓冲区中的残留数据
|
|
||||||
static void ps2_flush_output(void) {
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
inb(PS2_DATA_PORT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouse_init(void) {
|
|
||||||
// 1. 控制器自检(必须在命令字节写入之前,因为自检会重置命令字节)
|
|
||||||
ps2_write_cmd(PS2_CMD_SELF_TEST);
|
|
||||||
UINT8 self_test = ps2_read_data();
|
|
||||||
if (self_test != 0x55) {
|
|
||||||
serial_write("MOUSE: self-test FAILED\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 丢弃自检可能产生的残留数据
|
|
||||||
ps2_flush_output();
|
|
||||||
|
|
||||||
// 3. 启用辅助端口(鼠标)
|
|
||||||
ps2_write_cmd(PS2_CMD_ENABLE_A2);
|
|
||||||
|
|
||||||
// 4. 读取当前命令字节
|
|
||||||
ps2_write_cmd(PS2_CMD_READ_MB);
|
|
||||||
UINT8 cmd = ps2_read_data();
|
|
||||||
|
|
||||||
// 5. 启用 IRQ12 + IRQ1
|
|
||||||
cmd |= PS2_CMD_IRQ12 | PS2_CMD_IRQ1;
|
|
||||||
|
|
||||||
// 6. 写入修改后的命令字节(在自检之后,不会被重置)
|
|
||||||
ps2_write_cmd(PS2_CMD_WRITE_MB);
|
|
||||||
ps2_wait_input();
|
|
||||||
outb(PS2_DATA_PORT, cmd);
|
|
||||||
|
|
||||||
// 7. 验证命令字节已写入
|
|
||||||
ps2_write_cmd(PS2_CMD_READ_MB);
|
|
||||||
UINT8 verify = ps2_read_data();
|
|
||||||
if (verify != cmd) {
|
|
||||||
serial_write("MOUSE: cmd verify mismatch\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置鼠标
|
|
||||||
ps2_write_mouse(PS2_MOUSE_RESET);
|
|
||||||
UINT8 ack = ps2_read_data();
|
|
||||||
if (ack == 0xFA) {
|
|
||||||
ps2_read_data(); // 丢弃第二字节
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启用鼠标数据上报
|
|
||||||
ps2_write_mouse(PS2_MOUSE_ENABLE);
|
|
||||||
ps2_read_data();
|
|
||||||
|
|
||||||
// 注册 IRQ12 处理函数并取消屏蔽
|
|
||||||
idt_set_handler(PS2_MOUSE_VECTOR, mouse_irq_handler);
|
|
||||||
pic_unmask_irq(2); // 取消主片级联屏蔽
|
|
||||||
pic_unmask_irq(PS2_MOUSE_IRQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
SSINT32 mouse_get_x(void) { return g_mouse_x; }
|
|
||||||
SSINT32 mouse_get_y(void) { return g_mouse_y; }
|
|
||||||
bool mouse_get_btn_left(void) { return g_mouse_btn_l; }
|
|
||||||
bool mouse_get_btn_right(void) { return g_mouse_btn_r; }
|
|
||||||
bool mouse_get_btn_middle(void) { return g_mouse_btn_m; }
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
#include <graphics/layer.h>
|
|
||||||
|
|
||||||
#define CURSOR_W 12
|
|
||||||
#define CURSOR_H 16
|
|
||||||
|
|
||||||
void cursor_init(void);
|
|
||||||
void cursor_update(void);
|
|
||||||
|
|
||||||
layer_t* cursor_get_layer(void);
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
|
|
||||||
#define PS2_MOUSE_IRQ 12
|
|
||||||
#define PS2_MOUSE_VECTOR (PIC_IRQ_BASE + PS2_MOUSE_IRQ)
|
|
||||||
|
|
||||||
// PS/2 controller ports
|
|
||||||
#define PS2_DATA_PORT 0x60
|
|
||||||
#define PS2_STATUS_PORT 0x64
|
|
||||||
#define PS2_CMD_PORT 0x64
|
|
||||||
|
|
||||||
// PS/2 controller commands
|
|
||||||
#define PS2_CMD_READ_MB 0x20 // Read command byte
|
|
||||||
#define PS2_CMD_WRITE_MB 0x60 // Write command byte
|
|
||||||
#define PS2_CMD_ENABLE_A2 0xA8 // Enable auxiliary (second) port
|
|
||||||
#define PS2_CMD_SELF_TEST 0xAA // Controller self-test
|
|
||||||
|
|
||||||
// PS/2 command byte bits
|
|
||||||
#define PS2_CMD_IRQ12 0x02 // Enable IRQ12 (auxiliary device)
|
|
||||||
#define PS2_CMD_IRQ1 0x01 // Enable IRQ1 (keyboard)
|
|
||||||
|
|
||||||
// PS/2 controller status bits
|
|
||||||
#define PS2_STAT_OBF 0x01 // Output buffer full (data ready)
|
|
||||||
#define PS2_STAT_IBF 0x02 // Input buffer full (controller busy)
|
|
||||||
|
|
||||||
// PS/2 mouse commands
|
|
||||||
#define PS2_MOUSE_ENABLE 0xF4 // Enable data reporting
|
|
||||||
#define PS2_MOUSE_DISABLE 0xF5 // Disable data reporting
|
|
||||||
#define PS2_MOUSE_RESET 0xFF // Reset mouse
|
|
||||||
|
|
||||||
// Mouse packet byte 0 flags
|
|
||||||
#define PS2_MOUSE_LEFT 0x01
|
|
||||||
#define PS2_MOUSE_RIGHT 0x02
|
|
||||||
#define PS2_MOUSE_MIDDLE 0x04
|
|
||||||
#define PS2_MOUSE_ALWAYS1 0x08
|
|
||||||
#define PS2_MOUSE_X_SIGN 0x10
|
|
||||||
#define PS2_MOUSE_Y_SIGN 0x20
|
|
||||||
#define PS2_MOUSE_X_OVER 0x40
|
|
||||||
#define PS2_MOUSE_Y_OVER 0x80
|
|
||||||
|
|
||||||
void mouse_init(void);
|
|
||||||
|
|
||||||
SSINT32 mouse_get_x(void);
|
|
||||||
SSINT32 mouse_get_y(void);
|
|
||||||
bool mouse_get_btn_left(void);
|
|
||||||
bool mouse_get_btn_right(void);
|
|
||||||
bool mouse_get_btn_middle(void);
|
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <memory/pmm.h>
|
#include <memory/pmm.h>
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <devices/cursor.h>
|
|
||||||
#include <interrupt/idt.h>
|
#include <interrupt/idt.h>
|
||||||
#include <interrupt/pic.h>
|
#include <interrupt/pic.h>
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
@@ -103,6 +102,12 @@ layer_t* layer_create(const char* name, layer_type_t type, UINT32 w, UINT32 h) {
|
|||||||
|
|
||||||
layer_insert_sorted(layer);
|
layer_insert_sorted(layer);
|
||||||
|
|
||||||
|
serial_write("LAYER: created '");
|
||||||
|
serial_write(name);
|
||||||
|
serial_write("' id=");
|
||||||
|
serial_write_hex(id);
|
||||||
|
serial_write("\n");
|
||||||
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +126,10 @@ void layer_destroy(layer_t* layer) {
|
|||||||
g_switch_target = NULL;
|
g_switch_target = NULL;
|
||||||
g_switch_pending = false;
|
g_switch_pending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serial_write("LAYER: destroyed '");
|
||||||
|
serial_write(layer->name);
|
||||||
|
serial_write("'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
layer_t* layer_get_by_id(UINT32 id) {
|
layer_t* layer_get_by_id(UINT32 id) {
|
||||||
@@ -225,10 +234,16 @@ void layer_init(void) {
|
|||||||
// 注册键盘 IRQ 并取消屏蔽
|
// 注册键盘 IRQ 并取消屏蔽
|
||||||
idt_set_handler(PIC_IRQ_BASE + 1, ps2_irq_handler);
|
idt_set_handler(PIC_IRQ_BASE + 1, ps2_irq_handler);
|
||||||
pic_unmask_irq(1);
|
pic_unmask_irq(1);
|
||||||
|
|
||||||
|
serial_write("LAYER: compositor init OK (back buffer = ");
|
||||||
|
serial_write_hex(buf_size);
|
||||||
|
serial_write(" bytes)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合成器任务
|
// 合成器任务
|
||||||
void layer_compositor_task(void) {
|
void layer_compositor_task(void) {
|
||||||
|
serial_write("LAYER: compositor task running\n");
|
||||||
|
|
||||||
UINT32 hr = g_gfx.hr;
|
UINT32 hr = g_gfx.hr;
|
||||||
UINT32 vr = g_gfx.vr;
|
UINT32 vr = g_gfx.vr;
|
||||||
|
|
||||||
@@ -240,12 +255,12 @@ void layer_compositor_task(void) {
|
|||||||
if (target && target->visible && target->type == LAYER_TYPE_WINDOW) {
|
if (target && target->visible && target->type == LAYER_TYPE_WINDOW) {
|
||||||
g_focused = target;
|
g_focused = target;
|
||||||
layer_set_z(target, 99);
|
layer_set_z(target, 99);
|
||||||
|
serial_write("LAYER: Shift+F10 -> '");
|
||||||
|
serial_write(target->name);
|
||||||
|
serial_write("'\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新光标位置
|
|
||||||
cursor_update();
|
|
||||||
|
|
||||||
// 清除后台缓冲区
|
// 清除后台缓冲区
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0};
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0};
|
||||||
draw_set_target(g_back_buffer, hr, vr);
|
draw_set_target(g_back_buffer, hr, vr);
|
||||||
@@ -266,17 +281,14 @@ void layer_compositor_task(void) {
|
|||||||
if (dy + (SSINT32)sh > (SSINT32)vr) sh = vr - dy;
|
if (dy + (SSINT32)sh > (SSINT32)vr) sh = vr - dy;
|
||||||
if (sw == 0 || sh == 0) { cur = cur->next; continue; }
|
if (sw == 0 || sh == 0) { cur = cur->next; continue; }
|
||||||
|
|
||||||
bool use_alpha = (cur->type == LAYER_TYPE_MOUSE);
|
|
||||||
for (UINT32 row = 0; row < sh; row++) {
|
for (UINT32 row = 0; row < sh; row++) {
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* src = cur->buffer + ((UINTN)cur->w * (sy + row)) + sx;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* src = cur->buffer + ((UINTN)cur->w * (sy + row)) + sx;
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = g_back_buffer + ((UINTN)hr * (dy + row)) + dx;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = g_back_buffer + ((UINTN)hr * (dy + row)) + dx;
|
||||||
for (UINT32 col = 0; col < sw; col++) {
|
for (UINT32 col = 0; col < sw; col++) {
|
||||||
if (!use_alpha || src->Reserved != 0) {
|
|
||||||
dst->Blue = src->Blue;
|
dst->Blue = src->Blue;
|
||||||
dst->Green = src->Green;
|
dst->Green = src->Green;
|
||||||
dst->Red = src->Red;
|
dst->Red = src->Red;
|
||||||
dst->Reserved = src->Reserved;
|
dst->Reserved = src->Reserved;
|
||||||
}
|
|
||||||
src++;
|
src++;
|
||||||
dst++;
|
dst++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
#include <interrupt/idt.h>
|
#include <interrupt/idt.h>
|
||||||
#include <interrupt/pic.h>
|
#include <interrupt/pic.h>
|
||||||
#include <interrupt/pit.h>
|
#include <interrupt/pit.h>
|
||||||
#include <devices/mouse.h>
|
|
||||||
#include <devices/cursor.h>
|
|
||||||
|
|
||||||
extern EFI_SYSTEM_TABLE *ST;
|
extern EFI_SYSTEM_TABLE *ST;
|
||||||
|
|
||||||
@@ -148,10 +146,6 @@ extern "C" void kernel_main() {
|
|||||||
// 注册 IRQ 处理函数(向量 0x20 = PIC_IRQ_BASE + 0)
|
// 注册 IRQ 处理函数(向量 0x20 = PIC_IRQ_BASE + 0)
|
||||||
idt_set_handler(PIC_IRQ_BASE + 0, irq_handler);
|
idt_set_handler(PIC_IRQ_BASE + 0, irq_handler);
|
||||||
|
|
||||||
// 初始化 PS/2 鼠标驱动
|
|
||||||
serial_write("Sylva: init mouse...\n");
|
|
||||||
mouse_init();
|
|
||||||
|
|
||||||
serial_write("Sylva: init PIT...\n");
|
serial_write("Sylva: init PIT...\n");
|
||||||
pit_init();
|
pit_init();
|
||||||
pit_set_tick_handler(scheduler_tick);
|
pit_set_tick_handler(scheduler_tick);
|
||||||
@@ -166,9 +160,6 @@ extern "C" void kernel_main() {
|
|||||||
// 初始化合成器(分配后台缓冲区,注册键盘处理)
|
// 初始化合成器(分配后台缓冲区,注册键盘处理)
|
||||||
layer_init();
|
layer_init();
|
||||||
|
|
||||||
// 初始化鼠标光标
|
|
||||||
cursor_init();
|
|
||||||
|
|
||||||
// 创建桌面图层(全屏,z=0)
|
// 创建桌面图层(全屏,z=0)
|
||||||
layer_t* desktop = layer_create("desktop", LAYER_TYPE_DESKTOP, g_gfx.hr, g_gfx.vr);
|
layer_t* desktop = layer_create("desktop", LAYER_TYPE_DESKTOP, g_gfx.hr, g_gfx.vr);
|
||||||
if (desktop) {
|
if (desktop) {
|
||||||
|
|||||||
Reference in New Issue
Block a user