mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(gui): Upgrade to high-res 800x600, sharp 8x16 font, IRQ12 PS/2 mouse driver, and polished window manager
- Upgrade resolution to 800x600 @ 32bpp TrueColor with Bochs/QEMU VBE LFB - Implement full 8042 Aux PS/2 mouse controller driver on IRQ 12 (vector 44) with packet decode and bounds clamping - Add high-definition 8x16 font rasterizer with text drop shadows for sharp typography - Upgrade to smooth 16x24 anti-aliased cursor with dark slate outline and drop shadow - Increase titlebars to 24px and taskbar to 32px with modern desktop styling - Re-architect applications (SysMon, Terminal, Explorer, Calc, Paint, About) for spacious high-res display
This commit is contained in:
1 parent
56d8b3af1a
commit
4568a9ab4e
10 files changed
+475
-241
No files matched your search
+150
-6
@@ -1,15 +1,157 @@
|
||||
// PS/2 Mouse Controller & Interrupt Driver for SUB-OS
|
||||
#include <drivers/mouse.h>
|
||||
#include <arch/x86_64/io.h>
|
||||
#include <arch/x86_64/isr.h>
|
||||
#include <arch/x86_64/pic.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static mouse_state_t mouse_state = {0, 0, false, false, false};
|
||||
static int mouse_bounds_x = 80;
|
||||
static int mouse_bounds_y = 25;
|
||||
#define MOUSE_PORT_DATA 0x60
|
||||
#define MOUSE_PORT_STATUS 0x64
|
||||
#define MOUSE_PORT_CMD 0x64
|
||||
|
||||
#define MOUSE_CMD_ENABLE_AUX 0xA8
|
||||
#define MOUSE_CMD_GET_BYTE 0x20
|
||||
#define MOUSE_CMD_SET_BYTE 0x60
|
||||
#define MOUSE_CMD_WRITE_AUX 0xD4
|
||||
|
||||
#define MOUSE_CMD_SET_DEFAULTS 0xF6
|
||||
#define MOUSE_CMD_ENABLE_DATA 0xF4
|
||||
#define MOUSE_CMD_SET_SAMPLE 0xF3
|
||||
|
||||
static mouse_state_t mouse_state = {400, 300, false, false, false};
|
||||
static int mouse_bounds_x = 800;
|
||||
static int mouse_bounds_y = 600;
|
||||
|
||||
static uint8_t mouse_cycle = 0;
|
||||
static uint8_t mouse_packet[3];
|
||||
|
||||
static inline void mouse_wait_write(void) {
|
||||
uint32_t timeout = 100000;
|
||||
while ((inb(MOUSE_PORT_STATUS) & 0x02) && timeout--) {
|
||||
io_wait();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mouse_wait_read(void) {
|
||||
uint32_t timeout = 100000;
|
||||
while (!(inb(MOUSE_PORT_STATUS) & 0x01) && timeout--) {
|
||||
io_wait();
|
||||
}
|
||||
}
|
||||
|
||||
static void mouse_write_cmd(uint8_t cmd) {
|
||||
mouse_wait_write();
|
||||
outb(MOUSE_PORT_CMD, cmd);
|
||||
}
|
||||
|
||||
static void mouse_write_data(uint8_t data) {
|
||||
mouse_wait_write();
|
||||
outb(MOUSE_PORT_CMD, MOUSE_CMD_WRITE_AUX);
|
||||
mouse_wait_write();
|
||||
outb(MOUSE_PORT_DATA, data);
|
||||
}
|
||||
|
||||
static uint8_t mouse_read_data(void) {
|
||||
mouse_wait_read();
|
||||
return inb(MOUSE_PORT_DATA);
|
||||
}
|
||||
|
||||
static void mouse_interrupt_handler(registers_t* regs) {
|
||||
(void)regs;
|
||||
uint8_t status = inb(MOUSE_PORT_STATUS);
|
||||
if (!(status & 0x20)) {
|
||||
// Not mouse data
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t data = inb(MOUSE_PORT_DATA);
|
||||
|
||||
switch (mouse_cycle) {
|
||||
case 0:
|
||||
// Byte 0 must have bit 3 set to 1 in standard PS/2 packet
|
||||
if ((data & 0x08) == 0x08) {
|
||||
mouse_packet[0] = data;
|
||||
mouse_cycle = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
mouse_packet[1] = data;
|
||||
mouse_cycle = 2;
|
||||
break;
|
||||
case 2:
|
||||
mouse_packet[2] = data;
|
||||
mouse_cycle = 0;
|
||||
|
||||
// Process Packet
|
||||
uint8_t flags = mouse_packet[0];
|
||||
int32_t dx = (int32_t)mouse_packet[1];
|
||||
int32_t dy = (int32_t)mouse_packet[2];
|
||||
|
||||
// Sign extension
|
||||
if (flags & 0x10) dx |= 0xFFFFFF00;
|
||||
if (flags & 0x20) dy |= 0xFFFFFF00;
|
||||
|
||||
// Check overflow
|
||||
if (flags & 0xC0) {
|
||||
// Discard invalid/overflow packet
|
||||
break;
|
||||
}
|
||||
|
||||
// Update Coordinates (PS/2 Y delta is inverted)
|
||||
mouse_state.x += dx;
|
||||
mouse_state.y -= dy;
|
||||
|
||||
// Clamp coordinates to screen bounds
|
||||
if (mouse_state.x < 0) mouse_state.x = 0;
|
||||
if (mouse_state.y < 0) mouse_state.y = 0;
|
||||
if (mouse_state.x >= mouse_bounds_x) mouse_state.x = mouse_bounds_x - 1;
|
||||
if (mouse_state.y >= mouse_bounds_y) mouse_state.y = mouse_bounds_y - 1;
|
||||
|
||||
// Update button states
|
||||
mouse_state.left_btn = (flags & 0x01) != 0;
|
||||
mouse_state.right_btn = (flags & 0x02) != 0;
|
||||
mouse_state.middle_btn = (flags & 0x04) != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_init(void) {
|
||||
#if defined(__x86_64__)
|
||||
// 1. Enable Auxiliary Device
|
||||
mouse_write_cmd(MOUSE_CMD_ENABLE_AUX);
|
||||
|
||||
// 2. Read Controller Command Byte
|
||||
mouse_write_cmd(MOUSE_CMD_GET_BYTE);
|
||||
uint8_t status = mouse_read_data();
|
||||
|
||||
// 3. Enable IRQ12 (Bit 1) & Enable Mouse Clock (Clear Bit 5)
|
||||
status |= 0x02;
|
||||
status &= ~0x20;
|
||||
mouse_write_cmd(MOUSE_CMD_SET_BYTE);
|
||||
mouse_wait_write();
|
||||
outb(MOUSE_PORT_DATA, status);
|
||||
|
||||
// 4. Set Defaults & Enable Streaming
|
||||
mouse_write_data(MOUSE_CMD_SET_DEFAULTS);
|
||||
mouse_read_data(); // ACK (0xFA)
|
||||
|
||||
mouse_write_data(MOUSE_CMD_ENABLE_DATA);
|
||||
mouse_read_data(); // ACK (0xFA)
|
||||
|
||||
// 5. Register IRQ 12 Handler (Vector 44 = 32 + 12)
|
||||
isr_register_handler(44, mouse_interrupt_handler);
|
||||
|
||||
// 6. Unmask PIC IRQ 12
|
||||
pic_clear_mask(12);
|
||||
#endif
|
||||
|
||||
mouse_state.x = mouse_bounds_x / 2;
|
||||
mouse_state.y = mouse_bounds_y / 2;
|
||||
printk(KERN_INFO "MOUSE: PS/2 Mouse Controller initialized (Bounds: %dx%d)\n",
|
||||
mouse_state.left_btn = false;
|
||||
mouse_state.right_btn = false;
|
||||
mouse_state.middle_btn = false;
|
||||
|
||||
printk(KERN_INFO "MOUSE: PS/2 Mouse Controller initialized (IRQ 12, Bounds: %dx%d)\n",
|
||||
mouse_bounds_x, mouse_bounds_y);
|
||||
}
|
||||
|
||||
@@ -18,6 +160,8 @@ const mouse_state_t* mouse_get_state(void) {
|
||||
}
|
||||
|
||||
void mouse_set_bounds(int max_x, int max_y) {
|
||||
mouse_bounds_x = max_x;
|
||||
mouse_bounds_y = max_y;
|
||||
mouse_bounds_x = (max_x > 0) ? max_x : 800;
|
||||
mouse_bounds_y = (max_y > 0) ? max_y : 600;
|
||||
if (mouse_state.x >= mouse_bounds_x) mouse_state.x = mouse_bounds_x / 2;
|
||||
if (mouse_state.y >= mouse_bounds_y) mouse_state.y = mouse_bounds_y / 2;
|
||||
}
|
||||
Reference in new issue
Block a user