feat: Intel HDA audio driver, audio streaming syscalls, userspace Music app, fixes and improvements, rudimentary Bluetooth support
This commit is contained in:
@@ -29,20 +29,70 @@ void disktool_refresh() {
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Create partition
|
||||
// Create partition — confirmation dialog
|
||||
// ============================================================================
|
||||
|
||||
void do_create_partition() {
|
||||
void open_newpart_dialog() {
|
||||
auto& dt = g_state;
|
||||
if (dt.selected_disk < 0 || dt.selected_disk >= dt.disk_count) return;
|
||||
if (dt.np_dlg.open) return;
|
||||
|
||||
int part_indices[MAX_PARTS];
|
||||
int nparts = get_disk_parts(part_indices, MAX_PARTS);
|
||||
|
||||
if (nparts == 0) {
|
||||
auto& dlg = dt.np_dlg;
|
||||
dlg.will_init_gpt = (nparts == 0);
|
||||
dlg.hover_confirm = false;
|
||||
dlg.hover_cancel = false;
|
||||
|
||||
Montauk::DiskInfo& disk = dt.disks[dt.selected_disk];
|
||||
char sz[24];
|
||||
format_disk_size(sz, sizeof(sz), disk.sectorCount, disk.sectorSizeLog);
|
||||
snprintf(dlg.disk_desc, sizeof(dlg.disk_desc), "Disk %d: %s (%s)",
|
||||
dt.selected_disk, disk.model, sz);
|
||||
|
||||
if (dlg.will_init_gpt) {
|
||||
snprintf(dlg.warn_line1, sizeof(dlg.warn_line1),
|
||||
"This will initialize a new GPT on this disk.");
|
||||
snprintf(dlg.warn_line2, sizeof(dlg.warn_line2),
|
||||
"ALL existing partitions will be destroyed!");
|
||||
} else {
|
||||
snprintf(dlg.warn_line1, sizeof(dlg.warn_line1),
|
||||
"This will add a new partition in the largest");
|
||||
snprintf(dlg.warn_line2, sizeof(dlg.warn_line2),
|
||||
"free region on this disk.");
|
||||
}
|
||||
|
||||
Montauk::WinCreateResult wres;
|
||||
const char* title = dlg.will_init_gpt ? "Initialize Disk" : "New Partition";
|
||||
if (montauk::win_create(title, NP_DLG_W, NP_DLG_H, &wres) < 0 || wres.id < 0) {
|
||||
set_status("Failed to open dialog");
|
||||
return;
|
||||
}
|
||||
dlg.win_id = wres.id;
|
||||
dlg.pixels = (uint32_t*)(uintptr_t)wres.pixelVa;
|
||||
dlg.open = true;
|
||||
|
||||
render_newpart_window();
|
||||
montauk::win_present(dlg.win_id);
|
||||
}
|
||||
|
||||
void close_newpart_dialog() {
|
||||
auto& dlg = g_state.np_dlg;
|
||||
if (!dlg.open) return;
|
||||
montauk::win_destroy(dlg.win_id);
|
||||
dlg.open = false;
|
||||
}
|
||||
|
||||
void newpart_dialog_confirm() {
|
||||
auto& dt = g_state;
|
||||
auto& dlg = dt.np_dlg;
|
||||
|
||||
if (dlg.will_init_gpt) {
|
||||
int r = montauk::gpt_init(dt.selected_disk);
|
||||
if (r < 0) {
|
||||
set_status("Failed to initialize GPT on disk");
|
||||
close_newpart_dialog();
|
||||
return;
|
||||
}
|
||||
set_status("Initialized GPT");
|
||||
@@ -69,13 +119,18 @@ void do_create_partition() {
|
||||
int r = montauk::gpt_add(¶ms);
|
||||
if (r < 0) {
|
||||
set_status("Failed to create partition");
|
||||
return;
|
||||
} else {
|
||||
set_status("Partition created successfully");
|
||||
}
|
||||
|
||||
set_status("Partition created successfully");
|
||||
close_newpart_dialog();
|
||||
disktool_refresh();
|
||||
}
|
||||
|
||||
void do_create_partition() {
|
||||
open_newpart_dialog();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Mount partition
|
||||
// ============================================================================
|
||||
|
||||
@@ -72,6 +72,8 @@ static constexpr int NUM_FS_TYPES = 1;
|
||||
|
||||
static constexpr int FMT_DLG_W = 280;
|
||||
static constexpr int FMT_DLG_H = 220;
|
||||
static constexpr int NP_DLG_W = 340;
|
||||
static constexpr int NP_DLG_H = 200;
|
||||
|
||||
struct FormatDialog {
|
||||
bool open;
|
||||
@@ -84,6 +86,18 @@ struct FormatDialog {
|
||||
uint32_t* pixels;
|
||||
};
|
||||
|
||||
struct NewPartDialog {
|
||||
bool open;
|
||||
bool will_init_gpt; // true if GPT init is needed (most destructive)
|
||||
bool hover_confirm;
|
||||
bool hover_cancel;
|
||||
char disk_desc[80];
|
||||
char warn_line1[96];
|
||||
char warn_line2[96];
|
||||
int win_id;
|
||||
uint32_t* pixels;
|
||||
};
|
||||
|
||||
struct DiskToolState {
|
||||
Montauk::DiskInfo disks[MAX_DISKS];
|
||||
int disk_count;
|
||||
@@ -95,6 +109,7 @@ struct DiskToolState {
|
||||
char status[80];
|
||||
uint64_t status_time;
|
||||
FormatDialog fmt_dlg;
|
||||
NewPartDialog np_dlg;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -125,6 +140,7 @@ void format_disk_size(char* buf, int bufsize, uint64_t sectors, uint16_t sectorS
|
||||
|
||||
void render(uint32_t* pixels);
|
||||
void render_format_window();
|
||||
void render_newpart_window();
|
||||
|
||||
// ============================================================================
|
||||
// Function declarations — actions.cpp
|
||||
@@ -136,3 +152,6 @@ void do_mount_partition();
|
||||
void open_format_dialog();
|
||||
void close_format_dialog();
|
||||
void format_dialog_do_format();
|
||||
void open_newpart_dialog();
|
||||
void close_newpart_dialog();
|
||||
void newpart_dialog_confirm();
|
||||
|
||||
@@ -180,6 +180,40 @@ static bool handle_content_click(int mx, int my) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// New partition dialog mouse handling
|
||||
// ============================================================================
|
||||
|
||||
static bool handle_newpart_dialog_click(int mx, int my, bool clicked) {
|
||||
auto& dlg = g_state.np_dlg;
|
||||
if (!dlg.open) return false;
|
||||
|
||||
int dw = NP_DLG_W, dh = NP_DLG_H;
|
||||
|
||||
int btn_w = 90, btn_h = 30;
|
||||
int btn_y = dh - btn_h - 16;
|
||||
int gap = 16;
|
||||
int total_w = btn_w * 2 + gap;
|
||||
int bx = (dw - total_w) / 2;
|
||||
|
||||
dlg.hover_confirm = (mx >= bx && mx < bx + btn_w && my >= btn_y && my < btn_y + btn_h);
|
||||
dlg.hover_cancel = (mx >= bx + btn_w + gap && mx < bx + btn_w * 2 + gap && my >= btn_y && my < btn_y + btn_h);
|
||||
|
||||
if (!clicked) return true;
|
||||
|
||||
if (dlg.hover_confirm) {
|
||||
newpart_dialog_confirm();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dlg.hover_cancel) {
|
||||
close_newpart_dialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Format dialog mouse handling
|
||||
// ============================================================================
|
||||
@@ -236,6 +270,16 @@ static bool handle_key(const Montauk::KeyEvent& key) {
|
||||
|
||||
auto& dt = g_state;
|
||||
|
||||
// New partition dialog keys
|
||||
if (dt.np_dlg.open) {
|
||||
if (key.scancode == 0x01) { // Escape
|
||||
close_newpart_dialog();
|
||||
} else if (key.ascii == '\n' || key.ascii == '\r') {
|
||||
newpart_dialog_confirm();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Format dialog keys
|
||||
if (dt.fmt_dlg.open) {
|
||||
if (key.scancode == 0x01) { // Escape
|
||||
@@ -313,6 +357,28 @@ extern "C" void _start() {
|
||||
bool redraw_main = false;
|
||||
bool redraw_dlg = false;
|
||||
|
||||
bool redraw_np = false;
|
||||
|
||||
// Poll new partition dialog window
|
||||
if (g_state.np_dlg.open) {
|
||||
int dr = montauk::win_poll(g_state.np_dlg.win_id, &ev);
|
||||
if (dr > 0) {
|
||||
if (ev.type == 3) { // close
|
||||
close_newpart_dialog();
|
||||
redraw_main = true;
|
||||
} else if (ev.type == 0 && ev.key.pressed) {
|
||||
handle_key(ev.key);
|
||||
redraw_np = g_state.np_dlg.open;
|
||||
redraw_main = true;
|
||||
} else if (ev.type == 1) {
|
||||
bool clicked = (ev.mouse.buttons & 1) && !(ev.mouse.prev_buttons & 1);
|
||||
handle_newpart_dialog_click(ev.mouse.x, ev.mouse.y, clicked);
|
||||
redraw_np = g_state.np_dlg.open;
|
||||
redraw_main = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Poll format dialog window
|
||||
if (g_state.fmt_dlg.open) {
|
||||
int dr = montauk::win_poll(g_state.fmt_dlg.win_id, &ev);
|
||||
@@ -341,7 +407,8 @@ extern "C" void _start() {
|
||||
// Even with no main event, dialog may have triggered redraws
|
||||
if (redraw_main) { render(pixels); montauk::win_present(win_id); }
|
||||
if (redraw_dlg) { render_format_window(); montauk::win_present(g_state.fmt_dlg.win_id); }
|
||||
if (!redraw_main && !redraw_dlg) montauk::sleep_ms(16);
|
||||
if (redraw_np) { render_newpart_window(); montauk::win_present(g_state.np_dlg.win_id); }
|
||||
if (!redraw_main && !redraw_dlg && !redraw_np) montauk::sleep_ms(16);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -383,8 +450,10 @@ extern "C" void _start() {
|
||||
|
||||
if (redraw_main) { render(pixels); montauk::win_present(win_id); }
|
||||
if (redraw_dlg) { render_format_window(); montauk::win_present(g_state.fmt_dlg.win_id); }
|
||||
if (redraw_np) { render_newpart_window(); montauk::win_present(g_state.np_dlg.win_id); }
|
||||
}
|
||||
|
||||
close_newpart_dialog();
|
||||
close_format_dialog();
|
||||
montauk::win_destroy(win_id);
|
||||
montauk::exit(0);
|
||||
|
||||
@@ -345,6 +345,61 @@ void render_format_window() {
|
||||
px_button(px, dw, dh, bx + btn_w + gap, btn_y, btn_w, btn_h, "Cancel", can_bg, WHITE, 6);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Render: new partition confirmation dialog
|
||||
// ============================================================================
|
||||
|
||||
void render_newpart_window() {
|
||||
auto& dlg = g_state.np_dlg;
|
||||
if (!dlg.open) return;
|
||||
|
||||
uint32_t* px = dlg.pixels;
|
||||
int dw = NP_DLG_W, dh = NP_DLG_H;
|
||||
int fh = font_h();
|
||||
|
||||
px_fill(px, dw, dh, 0, 0, dw, dh, BG_COLOR);
|
||||
|
||||
// Title
|
||||
const char* title = dlg.will_init_gpt ? "Initialize Disk" : "New Partition";
|
||||
int tw = text_w(title);
|
||||
px_text(px, dw, dh, (dw - tw) / 2, 12, title, TEXT_COLOR);
|
||||
|
||||
// Disk description
|
||||
int ddw = text_w(dlg.disk_desc);
|
||||
px_text(px, dw, dh, (dw - ddw) / 2, 12 + fh + 6, dlg.disk_desc, DIM_TEXT);
|
||||
|
||||
// Warning lines
|
||||
Color warn_color = dlg.will_init_gpt
|
||||
? Color::from_rgb(0xCC, 0x22, 0x22)
|
||||
: TEXT_COLOR;
|
||||
|
||||
int wy = 12 + fh * 2 + 20;
|
||||
int w1w = text_w(dlg.warn_line1);
|
||||
px_text(px, dw, dh, (dw - w1w) / 2, wy, dlg.warn_line1, warn_color);
|
||||
int w2w = text_w(dlg.warn_line2);
|
||||
px_text(px, dw, dh, (dw - w2w) / 2, wy + fh + 4, dlg.warn_line2, warn_color);
|
||||
|
||||
// Buttons
|
||||
int btn_w = 90, btn_h = 30;
|
||||
int btn_y = dh - btn_h - 16;
|
||||
int gap = 16;
|
||||
int total_w = btn_w * 2 + gap;
|
||||
int bx = (dw - total_w) / 2;
|
||||
|
||||
Color confirm_bg = dlg.will_init_gpt
|
||||
? (dlg.hover_confirm ? Color::from_rgb(0xDD, 0x44, 0x44)
|
||||
: Color::from_rgb(0xCC, 0x33, 0x33))
|
||||
: (dlg.hover_confirm ? Color::from_rgb(0x4A, 0x88, 0xC8)
|
||||
: Color::from_rgb(0x42, 0x7A, 0xB5));
|
||||
const char* confirm_label = dlg.will_init_gpt ? "Initialize" : "Create";
|
||||
px_button(px, dw, dh, bx, btn_y, btn_w, btn_h, confirm_label, confirm_bg, WHITE, 6);
|
||||
|
||||
Color can_bg = dlg.hover_cancel
|
||||
? Color::from_rgb(0x99, 0x99, 0x99)
|
||||
: Color::from_rgb(0x88, 0x88, 0x88);
|
||||
px_button(px, dw, dh, bx + btn_w + gap, btn_y, btn_w, btn_h, "Cancel", can_bg, WHITE, 6);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Top-level render
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user