/* * devexplorer.h * Shared header for the MontaukOS Device Explorer * Copyright (c) 2026 Daniel Hammer */ #pragma once #include #include #include #include #include #include extern "C" { #include #include } using namespace gui; // ============================================================================ // Constants // ============================================================================ static constexpr int INIT_W = 640; static constexpr int INIT_H = 460; static constexpr int TOOLBAR_H = 36; static constexpr int CAT_H = 28; static constexpr int ITEM_H = 24; static constexpr int MAX_DEVS = 64; static constexpr int MAX_VIRTUAL_DEVS = 4; static constexpr int MAX_TOTAL_DEVS = MAX_DEVS + MAX_VIRTUAL_DEVS; static constexpr int POLL_MS = 2000; static constexpr int INDENT = 28; static constexpr int FONT_SIZE = 18; enum DeviceCategory { CAT_CPU = 0, CAT_INTERRUPT, CAT_TIMER, CAT_INPUT, CAT_USB, CAT_NETWORK, CAT_DISPLAY, CAT_STORAGE, CAT_PCI, CAT_AUDIO, CAT_ACPI, CAT_PRINTER, NUM_CATEGORIES }; static constexpr Color BG_COLOR = Color::from_rgb(0xFF, 0xFF, 0xFF); static constexpr Color TOOLBAR_BG = Color::from_rgb(0xF5, 0xF5, 0xF5); static constexpr Color BORDER_COLOR = Color::from_rgb(0xCC, 0xCC, 0xCC); static constexpr Color TEXT_COLOR = Color::from_rgb(0x22, 0x22, 0x22); static constexpr Color DIM_TEXT = Color::from_rgb(0x66, 0x66, 0x66); static constexpr Color WHITE = Color::from_rgb(0xFF, 0xFF, 0xFF); static constexpr Color ACCENT_COLOR = Color::from_rgb(0x33, 0x66, 0xCC); // ============================================================================ // Category data // ============================================================================ static const char* category_names[] = { "CPU", "Interrupt", "Timer", "Input", "USB", "Network", "Display", "Storage", "PCI", "Audio", "ACPI", "Printers", }; static const Color category_colors[] = { Color::from_rgb(0x33, 0x66, 0xCC), Color::from_rgb(0x88, 0x44, 0xAA), Color::from_rgb(0x22, 0x88, 0x22), Color::from_rgb(0xCC, 0x88, 0x00), Color::from_rgb(0x00, 0x88, 0x88), Color::from_rgb(0xCC, 0x55, 0x22), Color::from_rgb(0x44, 0x66, 0xCC), Color::from_rgb(0x99, 0x55, 0x00), Color::from_rgb(0x66, 0x66, 0x66), Color::from_rgb(0x8A, 0x5A, 0xCC), Color::from_rgb(0x55, 0x77, 0x88), Color::from_rgb(0x2F, 0x8B, 0x57), }; // ============================================================================ // Display row model // ============================================================================ enum RowType { ROW_CATEGORY, ROW_DEVICE }; struct DisplayRow { RowType type; int category; int dev_index; }; static constexpr int MAX_DISPLAY_ROWS = MAX_TOTAL_DEVS + NUM_CATEGORIES; // ============================================================================ // Scroll metrics (pixel-space) — shared by render and input handling so the // draggable MTK scrollbar and the row layout stay in sync. // ============================================================================ struct ScrollMetrics { int list_y; // top of the scrollable list area int list_h; // viewport height (view extent) int total_h; // total content height (content extent) int max_scroll_px; // maximum pixel scroll offset int scroll_px; // current pixel scroll offset (clamped scroll_y) }; // Bounds of the toolbar "Refresh" button — shared by render and hit-testing. inline Rect refresh_button_rect() { constexpr int btn_w = 80, btn_h = 26; return { 8, (TOOLBAR_H - btn_h) / 2, btn_w, btn_h }; } // ============================================================================ // Disk detail window // ============================================================================ static constexpr int DD_TAB_COUNT = 2; static const char* dd_tab_labels[DD_TAB_COUNT] = { "General", "Features" }; static constexpr int DD_INIT_W = 440; static constexpr int DD_INIT_H = 420; static constexpr int DD_TAB_BAR_H = 32; struct DiskDetailState { Montauk::DiskInfo info; int active_tab; int win_id; int win_w, win_h; uint32_t* pixels; bool open; }; // ============================================================================ // Main state // ============================================================================ struct DevExplorerState { Montauk::DevInfo devs[MAX_TOTAL_DEVS]; int dev_count; bool collapsed[NUM_CATEGORIES]; int selected_row; int scroll_y; // vertical scroll offset, in pixels (not rows) uint64_t last_poll_ms; int last_click_row; uint64_t last_click_ms; // Draggable MTK scrollbar interaction state int mouse_x, mouse_y; // last known pointer position (for hover) bool sb_hover; // pointer is over the scrollbar track bool sb_dragging; // thumb is being dragged int sb_drag_offset; // pointer offset from thumb top when drag began bool btn_hover; // pointer is over the Refresh button DiskDetailState detail; }; // ============================================================================ // Global state (extern — defined in main.cpp) // ============================================================================ extern int g_win_w, g_win_h; extern DevExplorerState g_state; extern TrueTypeFont* g_font; extern mtk::Theme g_theme; // ============================================================================ // Function declarations — render.cpp // ============================================================================ void render(uint32_t* pixels); // ============================================================================ // Function declarations — main.cpp // ============================================================================ int build_display_rows(DevExplorerState* de, DisplayRow* rows); int append_printer_devices(Montauk::DevInfo* out, int max_count); ScrollMetrics compute_scroll_metrics(DevExplorerState* de, const DisplayRow* rows, int row_count); void set_scroll_from_px(DevExplorerState* de, const DisplayRow* rows, int row_count, int target_px); // ============================================================================ // Function declarations — diskdetail.cpp // ============================================================================ void render_disk_detail(); void open_disk_detail(int port, const char* model); void close_disk_detail(); bool handle_detail_mouse(int mx, int my, bool clicked);