/* * main.cpp * MontaukOS Display and Graphics settings * Copyright (c) 2026 Daniel Hammer */ #include #include #include #include #include #include extern "C" { #include } using namespace gui; static constexpr int WIN_W = 620; static constexpr int WIN_H = 500; static constexpr int TAB_H = 36; static constexpr int FOOTER_H = 44; static constexpr int PAD = 18; static constexpr int GAP = 12; static constexpr int BUTTON_W = 88; static constexpr int SLIDER_H = 6; static constexpr int KNOB_R = 8; static constexpr int MODE_ROW_H = 36; static constexpr int VISIBLE_MODES = 6; static constexpr int MAX_MODES = 32; static constexpr int INFO_LABEL_W = 175; enum Tab { TAB_DISPLAY = 0, TAB_GRAPHICS = 1, TAB_COUNT = 2, }; static const char* const kTabLabels[TAB_COUNT] = { "Display", "Graphics", }; static WsWindow g_win; static Tab g_tab = TAB_DISPLAY; static int g_mouse_x = -1; static int g_mouse_y = -1; static bool g_brightness_drag = false; static Color g_accent = colors::ACCENT; static montauk::abi::DisplayInfo g_info = {}; static montauk::abi::DisplayModeInfo g_modes[MAX_MODES] = {}; static int g_mode_count = 0; static bool g_driver_available = false; static int g_selected_mode = -1; static int g_pending_brightness = -1; static bool g_tear_free = true; static bool g_saved_tear_free = true; static int g_mode_scroll = 0; static char g_status[128] = {}; static uint64_t g_status_time = 0; static uint64_t g_last_refresh = 0; static mtk::Theme app_theme() { mtk::Theme theme = mtk::make_theme(g_accent); theme.danger_soft = Color::from_rgb(0xF8, 0xE0, 0xE0); return theme; } static Rect tab_bar_rect() { return {0, 0, g_win.width, TAB_H}; } static Rect footer_rect() { return {0, g_win.height - FOOTER_H, g_win.width, FOOTER_H}; } static int display_heading_y() { return TAB_H + 20; } static int brightness_row_y() { return display_heading_y() + system_font_height() + 18; } static Rect brightness_slider_rect() { int y = brightness_row_y() + (system_font_height() - SLIDER_H) / 2; return {PAD + INFO_LABEL_W, y, g_win.width - PAD * 2 - INFO_LABEL_W - 44, SLIDER_H}; } static int modes_separator_y() { return brightness_row_y() + system_font_height() + 26; } static int modes_header_y() { return modes_separator_y() + 16; } static int mode_list_y() { return modes_header_y() + system_font_height() + 8; } static Rect mode_row_rect(int visibleIndex) { return {PAD, mode_list_y() + visibleIndex * MODE_ROW_H, g_win.width - PAD * 2, MODE_ROW_H}; } static Rect apply_button() { Rect foot = footer_rect(); return {foot.x + foot.w - PAD - BUTTON_W, foot.y + 7, BUTTON_W, 30}; } static Rect revert_button() { Rect apply = apply_button(); return {apply.x - GAP - BUTTON_W, apply.y, BUTTON_W, apply.h}; } static Rect refresh_button() { Rect apply = apply_button(); return {apply.x - GAP - BUTTON_W, apply.y, BUTTON_W, apply.h}; } static int graphics_table_y() { return TAB_H + 24 + system_font_height() + 18; } static int graphics_row_step() { return system_font_height() + 10; } static int graphics_separator_y() { return graphics_table_y() + graphics_row_step() * 5 + 4; } static int graphics_section_y() { return graphics_separator_y() + 16; } static Rect tear_free_option() { return {PAD, graphics_section_y() + system_font_height() + 8, g_win.width - PAD * 2, 24}; } static bool mouse_in(const Rect& rect) { return rect.contains(g_mouse_x, g_mouse_y); } static mtk::WidgetState button_state(const Rect& rect, bool enabled = true) { return mtk::widget_state(false, mouse_in(rect), enabled); } static void set_status(const char* msg) { snprintf(g_status, sizeof(g_status), "%s", msg ? msg : ""); g_status_time = montauk::get_milliseconds(); } static bool status_visible() { return g_status[0] && montauk::get_milliseconds() - g_status_time < 5000; } static void load_graphics_preference() { char user[64] = {}; if (montauk::getuser(user, sizeof(user)) > 0 && user[0]) { auto doc = montauk::config::load_user(user, "display"); g_tear_free = doc.get_bool("graphics.tear_free", true); doc.destroy(); } else { auto doc = montauk::config::load("display"); g_tear_free = doc.get_bool("graphics.tear_free", true); doc.destroy(); } g_saved_tear_free = g_tear_free; } static bool save_graphics_preference() { montauk::toml::Doc doc; doc.init(); montauk::config::set_bool(&doc, "graphics.tear_free", g_tear_free); char user[64] = {}; int result; if (montauk::getuser(user, sizeof(user)) > 0 && user[0]) result = montauk::config::save_user(user, "display", &doc); else result = montauk::config::save("display", &doc); doc.destroy(); if (result >= 0) g_saved_tear_free = g_tear_free; return result >= 0; } static void clamp_mode_scroll() { int max_scroll = g_mode_count > VISIBLE_MODES ? g_mode_count - VISIBLE_MODES : 0; if (g_mode_scroll < 0) g_mode_scroll = 0; if (g_mode_scroll > max_scroll) g_mode_scroll = max_scroll; } static void refresh_state(bool resetPending) { montauk::abi::DisplayInfo next = {}; if (montauk::display_info(&next) < 0) { g_driver_available = false; g_mode_count = 0; g_last_refresh = montauk::get_milliseconds(); return; } g_info = next; int count = montauk::display_modes(g_modes, MAX_MODES); g_mode_count = count > 0 ? count : 0; g_driver_available = true; if (resetPending) { g_selected_mode = g_info.currentMode; g_pending_brightness = g_info.brightness; if (g_selected_mode >= VISIBLE_MODES) g_mode_scroll = g_selected_mode - VISIBLE_MODES + 1; } clamp_mode_scroll(); g_last_refresh = montauk::get_milliseconds(); } static bool dirty() { bool display_dirty = g_driver_available && (g_selected_mode != g_info.currentMode || (g_info.brightness >= 0 && g_pending_brightness != g_info.brightness)); return display_dirty || g_tear_free != g_saved_tear_free; } static void format_mode(char* out, int cap, const montauk::abi::DisplayModeInfo& mode) { uint32_t hz = (mode.refreshMilliHz + 500) / 1000; snprintf(out, cap, "%ux%u %u Hz", (unsigned)mode.width, (unsigned)mode.height, (unsigned)hz); } static void fit_text(char* out, int outCap, const char* text, int maxWidth) { if (!out || outCap <= 0) return; out[0] = '\0'; if (!text || !text[0] || maxWidth <= 0) return; if (text_width(text) <= maxWidth) { snprintf(out, outCap, "%s", text); return; } static const char* ellipsis = "..."; int len = 0; while (text[len] && len < outCap - 4) { out[len] = text[len]; out[len + 1] = '\0'; if (text_width(out) + text_width(ellipsis) > maxWidth) break; len++; } out[len++] = '.'; out[len++] = '.'; out[len++] = '.'; out[len] = '\0'; } static void draw_text_fit(Canvas& c, int x, int y, const char* text, int maxWidth, Color color) { char fitted[160]; fit_text(fitted, sizeof(fitted), text, maxWidth); c.text(x, y, fitted, color); } static void draw_kv(Canvas& c, int* y, const char* key, const char* value, const mtk::Theme& theme) { c.text(PAD, *y, key, theme.text_muted); draw_text_fit(c, PAD + INFO_LABEL_W, *y, value, g_win.width - PAD * 2 - INFO_LABEL_W, theme.text); *y += graphics_row_step(); } static void draw_slider(Canvas& c, const Rect& rect, int value, const mtk::Theme& theme) { Color track = mtk::mix(theme.surface, theme.border, 80); c.fill_rounded_rect(rect.x, rect.y, rect.w, rect.h, rect.h / 2, track); int fill_w = (value * rect.w) / 100; if (fill_w > 0) c.fill_rounded_rect(rect.x, rect.y, fill_w, rect.h, rect.h / 2, theme.accent); int kx = rect.x + fill_w; int ky = rect.y + rect.h / 2; fill_circle(c, kx, ky, KNOB_R, theme.accent); fill_circle(c, kx, ky, KNOB_R - 3, colors::WHITE); } static void draw_display_tab(Canvas& c, const mtk::Theme& theme) { int y = display_heading_y(); if (!g_driver_available) { c.text(PAD, y, "Intel display driver unavailable", theme.danger); c.text(PAD, y + 28, "The firmware framebuffer remains active, but hardware controls are unavailable.", theme.text_subtle); return; } char headline[128]; snprintf(headline, sizeof(headline), "%s on %s", g_info.monitorName[0] ? g_info.monitorName : "Display", g_info.connectorName[0] ? g_info.connectorName : "unknown connector"); draw_text_fit(c, PAD, y, headline, g_win.width - PAD * 2, g_info.connected ? theme.text : theme.danger); y = brightness_row_y(); c.text(PAD, y, "Brightness", theme.text_subtle); if (g_info.brightness >= 0) { Rect slider = brightness_slider_rect(); draw_slider(c, slider, g_pending_brightness, theme); char percent[16]; snprintf(percent, sizeof(percent), "%d%%", g_pending_brightness); c.text(slider.x + slider.w + 14, slider.y - 6, percent, theme.text); } else { draw_text_fit(c, PAD + INFO_LABEL_W, y, "Controlled by the external display", g_win.width - PAD * 2 - INFO_LABEL_W, theme.text_muted); } y = modes_separator_y(); mtk::draw_separator(c, PAD, y, g_win.width - PAD * 2, theme); y = modes_header_y(); c.text(PAD, y, "AVAILABLE MODES", theme.text_muted); const char* hint = "Grey modes require link training"; c.text(g_win.width - PAD - text_width(hint), y, hint, theme.text_muted); for (int row = 0; row < VISIBLE_MODES; row++) { int index = g_mode_scroll + row; if (index >= g_mode_count) break; Rect option = mode_row_rect(row); bool valid = (g_modes[index].flags & montauk::abi::DISPLAY_MODE_DRIVER_VALID) != 0; bool selected = index == g_selected_mode; if (selected) c.fill_rounded_rect(option.x, option.y + 2, option.w, option.h - 4, 4, theme.accent_soft); Rect radio = {option.x + 4, option.y, 18, option.h}; mtk::draw_radio(c, radio, "", selected, theme); char mode_text[64]; format_mode(mode_text, sizeof(mode_text), g_modes[index]); Color text = valid ? theme.text : theme.text_muted; int textY = option.y + (option.h - system_font_height()) / 2; c.text(option.x + 34, textY, mode_text, text); const char* state = nullptr; Color stateColor = theme.text_subtle; if (g_modes[index].flags & montauk::abi::DISPLAY_MODE_CURRENT) { state = "Current"; stateColor = theme.accent; } else if (g_modes[index].flags & montauk::abi::DISPLAY_MODE_PREFERRED) { state = "Preferred"; } else if (!valid) { state = "Link training required"; stateColor = theme.text_muted; } if (state) c.text(option.x + option.w - text_width(state) - 10, textY, state, stateColor); } if (g_mode_count == 0) { c.text(PAD + 4, mode_list_y() + 9, "No EDID modes were reported; the firmware mode remains active.", theme.text_subtle); } if (g_mode_count > VISIBLE_MODES) { char page[48]; snprintf(page, sizeof(page), "Modes %d-%d of %d (scroll)", g_mode_scroll + 1, g_mode_scroll + VISIBLE_MODES < g_mode_count ? g_mode_scroll + VISIBLE_MODES : g_mode_count, g_mode_count); c.text(PAD, footer_rect().y - 22, page, theme.text_muted); } } static const char* yes_no(bool value) { return value ? "Available" : "Unavailable"; } static void draw_graphics_tab(Canvas& c, const mtk::Theme& theme) { int y = TAB_H + 24; c.text(PAD, y, "Intel Graphics", theme.text); y = graphics_table_y(); if (!g_driver_available) { c.text(PAD, y, "No managed Intel GPU was detected.", theme.danger); return; } char device[96]; snprintf(device, sizeof(device), "%s (Gen %u, PCI %04X)", g_info.gpuName, (unsigned)g_info.generation, (unsigned)g_info.deviceId); draw_kv(c, &y, "Adapter", device, theme); draw_kv(c, &y, "EDID modes", yes_no((g_info.capabilities & montauk::abi::DISPLAY_CAP_EDID) != 0), theme); draw_kv(c, &y, "Page flipping", yes_no((g_info.capabilities & montauk::abi::DISPLAY_CAP_PAGE_FLIP) != 0), theme); draw_kv(c, &y, "VBlank interrupt", yes_no((g_info.capabilities & montauk::abi::DISPLAY_CAP_VBLANK_IRQ) != 0), theme); draw_kv(c, &y, "Safe mode switch", yes_no((g_info.capabilities & montauk::abi::DISPLAY_CAP_SAFE_SWITCH) != 0), theme); y = graphics_separator_y(); mtk::draw_separator(c, PAD, y, g_win.width - PAD * 2, theme); y = graphics_section_y(); c.text(PAD, y, "PRESENTATION", theme.text_muted); Rect option = tear_free_option(); bool flipAvailable = (g_info.capabilities & montauk::abi::DISPLAY_CAP_PAGE_FLIP) != 0; mtk::draw_checkbox(c, option, "Prefer tear-free hardware page flipping", mtk::check_state(g_tear_free), theme, flipAvailable, mouse_in(option)); c.text(option.x + 24, option.y + option.h + 2, flipAvailable ? "Applied when the next desktop session starts." : "Unavailable on this boot; the software copy path is active.", flipAvailable ? theme.text_subtle : theme.text_muted); int safetySeparator = option.y + option.h + system_font_height() + 18; mtk::draw_separator(c, PAD, safetySeparator, g_win.width - PAD * 2, theme); c.text(PAD, safetySeparator + 16, "MODESETTING SAFETY", theme.text_muted); c.text(PAD, safetySeparator + 16 + system_font_height() + 8, "The driver keeps the firmware-trained display link and only exposes modes", theme.text_subtle); c.text(PAD, safetySeparator + 16 + system_font_height() * 2 + 10, "that can be changed without unsafe PLL or DisplayPort retraining.", theme.text_subtle); } static void draw_footer(Canvas& c, const mtk::Theme& theme) { Rect foot = footer_rect(); c.fill_rect(foot.x, foot.y, foot.w, foot.h, theme.surface); mtk::draw_separator(c, 0, foot.y, g_win.width, theme); const char* message = status_visible() ? g_status : (dirty() ? "Unsaved display changes" : "Display settings ready"); c.text(PAD, foot.y + (foot.h - system_font_height()) / 2, message, dirty() ? theme.text : theme.text_subtle); if (g_tab == TAB_DISPLAY || dirty()) { Rect revert = revert_button(); Rect apply = apply_button(); mtk::draw_button(c, revert, "Revert", mtk::BUTTON_SECONDARY, button_state(revert, dirty()), theme); mtk::draw_button(c, apply, "Apply", mtk::BUTTON_PRIMARY, button_state(apply, dirty()), theme); } else { Rect refresh = refresh_button(); mtk::draw_button(c, refresh, "Refresh", mtk::BUTTON_SECONDARY, button_state(refresh), theme); } } static void render() { mtk::StandaloneHost host(&g_win); Canvas c = host.canvas(); mtk::Theme theme = app_theme(); c.fill(theme.window_bg); mtk::draw_tab_bar(c, tab_bar_rect(), kTabLabels, TAB_COUNT, (int)g_tab, theme); if (g_tab == TAB_DISPLAY) draw_display_tab(c, theme); else draw_graphics_tab(c, theme); draw_footer(c, theme); host.present(); } static int brightness_from_x(int mx) { Rect slider = brightness_slider_rect(); int value = ((mx - slider.x) * 100) / slider.w; if (value < 0) value = 0; if (value > 100) value = 100; return value; } static bool slider_hit(int mx, int my) { Rect slider = brightness_slider_rect(); return mx >= slider.x - KNOB_R && mx <= slider.x + slider.w + KNOB_R && my >= slider.y - KNOB_R - 4 && my <= slider.y + slider.h + KNOB_R + 4; } static void revert_changes() { g_selected_mode = g_info.currentMode; g_pending_brightness = g_info.brightness; g_tear_free = g_saved_tear_free; set_status("Changes reverted"); } static void apply_changes() { if (!dirty()) return; bool graphics_changed = g_tear_free != g_saved_tear_free; if (g_driver_available && g_info.brightness >= 0 && g_pending_brightness != g_info.brightness) { int result = montauk::display_brightness(g_pending_brightness); if (result < 0) { set_status("Could not change panel brightness"); return; } } if (g_driver_available && g_selected_mode != g_info.currentMode) { int result = montauk::display_set_mode(g_selected_mode); if (result < 0) { set_status(result == -2 ? "Mode needs unsupported display-link training" : "Mode change failed; previous mode restored"); refresh_state(true); return; } } if (graphics_changed && !save_graphics_preference()) { set_status("Could not save graphics preference"); return; } refresh_state(true); set_status(graphics_changed ? "Saved; takes effect next desktop session" : "Display settings applied"); } static bool handle_mouse(const montauk::abi::WinEvent& ev) { int mx = ev.mouse.x; int my = ev.mouse.y; uint8_t buttons = ev.mouse.buttons; uint8_t previous = ev.mouse.prev_buttons; bool pressed = (buttons & 1) && !(previous & 1); bool released = !(buttons & 1) && (previous & 1); if (pressed) { int tab = mtk::hit_tab_bar(tab_bar_rect(), TAB_COUNT, mx, my); if (tab >= 0) { g_tab = (Tab)tab; return true; } } if (g_tab == TAB_DISPLAY && g_info.brightness >= 0) { if (pressed && slider_hit(mx, my)) g_brightness_drag = true; if (g_brightness_drag && (buttons & 1)) g_pending_brightness = brightness_from_x(mx); if (released) g_brightness_drag = false; } if (g_tab == TAB_DISPLAY && ev.mouse.scroll != 0) { g_mode_scroll += ev.mouse.scroll > 0 ? -1 : 1; clamp_mode_scroll(); return true; } if (!pressed) return g_brightness_drag; if (g_tab == TAB_DISPLAY) { for (int row = 0; row < VISIBLE_MODES; row++) { int index = g_mode_scroll + row; if (index >= g_mode_count) break; if (mode_row_rect(row).contains(mx, my) && (g_modes[index].flags & montauk::abi::DISPLAY_MODE_DRIVER_VALID)) { g_selected_mode = index; return true; } } } else if (tear_free_option().contains(mx, my) && (g_info.capabilities & montauk::abi::DISPLAY_CAP_PAGE_FLIP)) { g_tear_free = !g_tear_free; return true; } if (revert_button().contains(mx, my) && dirty()) { revert_changes(); return true; } if (apply_button().contains(mx, my) && dirty()) { apply_changes(); return true; } if (refresh_button().contains(mx, my) && !dirty()) { refresh_state(true); set_status("Display status refreshed"); return true; } return false; } static bool handle_key(const montauk::abi::KeyEvent& key) { if (!key.pressed) return false; if (key.scancode == 0x01) { g_win.closed = true; return true; } if (key.ascii == '\t') { g_tab = g_tab == TAB_DISPLAY ? TAB_GRAPHICS : TAB_DISPLAY; return true; } if (key.ascii == '\n' || key.ascii == '\r') { apply_changes(); return true; } if (key.ascii == 'r' || key.ascii == 'R') { refresh_state(!dirty()); set_status("Display status refreshed"); return true; } return false; } extern "C" void _start() { if (!fonts::init()) montauk::exit(1); g_accent = mtk::load_system_accent(); load_graphics_preference(); if (!g_win.create("Display", WIN_W, WIN_H)) montauk::exit(1); refresh_state(true); render(); while (g_win.id >= 0 && !g_win.closed) { montauk::abi::WinEvent ev; int result = g_win.poll(&ev); bool redraw = false; if (result < 0) break; if (result == 0) { uint64_t now = montauk::get_milliseconds(); if (!dirty() && now - g_last_refresh >= 3000) { refresh_state(true); redraw = true; } if (status_visible()) redraw = true; if (redraw) render(); montauk::sleep_ms(16); continue; } if (ev.type == 3) break; if (ev.type == 2 || ev.type == 4) { redraw = true; } else if (ev.type == 1) { g_mouse_x = ev.mouse.x; g_mouse_y = ev.mouse.y; redraw = true; handle_mouse(ev); } else if (ev.type == 0) { redraw = handle_key(ev.key); } if (redraw) render(); } g_win.destroy(); montauk::exit(0); }