Skip to content

GUI Subsystem

kazah-png edited this page Jul 26, 2026 · 9 revisions

GUI Subsystem

A double-buffered window compositor over a VBE linear framebuffer. Up to 32 windows across 4 workspaces, with a taskbar, Start menu, drag-reorderable desktop icons, keyboard window management, and a "Nightfall" purple theme driven from a single palette header.

See also: Desktop Applications, Selene Browser, Image Decoders, Drivers, Boot Process

Framebuffer (vbe.c, fb.c)

Bochs VBE extensions set the mode; the linear framebuffer lives at 0xE0000000. Default is 1024×768×32, changeable at runtime with setres <w> <h> or mode <w> <h> <bpp>.

fb.c provides the primitives: fb_put_pixel, fb_fill_rect, fb_blit, fb_draw_char, rounded-rectangle helpers, and a clip region (which is what makes rounded window corners possible without drawing outside the frame).

Double buffering

fb_enable_backbuffer() redirects fb_addr to a RAM back buffer the size of the screen. Drawing is then invisible until fb_present() blits the whole thing to the hardware framebuffer in one shot — which is what eliminates flicker. The login screen deliberately calls fb_use_lfb_direct() to draw straight to the LFB instead.

Everything in the compositor is laid out on a 1024×768 design grid and scaled to the live framebuffer. Deriving coordinates from fb_get_width() in drawing code applies the scale twice — a bug that has been fixed more than once.

Font (font.c)

The IBM VGA 8×16 ROM font, 256 glyphs, rendered by font_draw_string.

Compositor (compositor.c)

Windows are kept in z-order, each assigned to a workspace. The window list is capped at MAX_WINDOWS (32).

Window chrome

  • Title bar with a gradient, drop shadow, and rounded top corners
  • Minimise / maximise / close buttons
  • Focused windows take the brand accent colour
  • Drag to move, edge-drag to resize

Keyboard window management

Shortcut Action
Alt+Tab Cycle focus in a stable, repeatable order
Alt+F4 Close the focused window
Alt+←/→ Snap to the left or right half (pressing the same side again un-snaps)
Alt+↑ Maximise, or climb the snap ladder
Alt+↓ Restore, or descend the snap ladder

Snapping is a two-axis grid — a horizontal side plus a vertical zone — so Alt+←then Alt+↑ gives a quarter tile. Snapped and maximised geometry is defined by the screen, so it is re-derived when the resolution changes rather than snapping back to stale coordinates.

Desktop

  • Icons wrap into a grid that reflows on a resolution change, so shrinking the screen never strands one off the edge. Each app has its own drawn emblem, and icons can be drag-reordered.
  • Taskbar with window buttons, a clock, workspace indicators, and a user badge — clicking it opens a menu to change your profile picture or log out (returning to the login screen without a reboot).
  • Start menu and a right-click desktop context menu, both sharing one visual style.
  • 4 workspaces (WORKSPACE_COUNT).

Idle behaviour

When nothing is happening the compositor sleep(5)s instead of busy-polling, handing the CPU to background jobs. Any input skips the sleep, so the worst-case response is 5 ms. While a foreground ring-3 job runs, the compositor recomposites at roughly 16 fps, which is what lets full-screen TUIs like top and edit render live inside the terminal window.

Fullscreen takeover

A ring-3 program that calls fbpresent() owns the whole screen for as long as it keeps calling it; the compositor yields and returns shortly after the program stops. This is the path DOOM uses — see Syscalls.

Theme (theme.h)

Every GUI colour is a named role, not a literal, so the desktop can be re-themed from one file:

#define THEME_ACCENT      fb_rgb(130,  90, 210)   /* brand purple, "Morado" */
#define THEME_ACCENT_DIM  fb_rgb( 92,  64, 150)
#define THEME_ON_ACCENT   fb_rgb(255, 255, 255)

They are macros rather than a const struct because fb_rgb() is a runtime function — this keeps the header a pure compile-time constant set with no initialisation order to worry about, and leaves room for a runtime theme later without touching a single call site.

Important

New GUI colours belong here as a role, not as a fresh fb_rgb(…) literal at the call site. Before theme.h existed, every colour was scattered across compositor.c and each *_win.c, and re-theming meant hunting call sites.

Palette reference

Role RGB Used for
THEME_ACCENT 130, 90, 210 Brand purple, "Morado"
THEME_ACCENT_DIM 92, 64, 150 Pressed / darker accent
THEME_ON_ACCENT 255, 255, 255 Text and icons on an accent fill
THEME_WINDOW_BG 45, 45, 50 Window and menu body
THEME_PANEL 30, 30, 35 Insets, list backgrounds
THEME_PANEL_HEADER 40, 45, 55 Panel headers
THEME_BORDER 100, 100, 100 1 px window/menu border
THEME_ROW_DIV 55, 55, 60 Row separators
THEME_TITLE_ACTIVE = THEME_ACCENT Focused title bar
THEME_TITLE_INACTIVE 80, 85, 95 Unfocused title bar
THEME_TITLE_TEXT 255, 255, 255 Title-bar text
THEME_FRAME_HI 180, 180, 180 Frame top and left, unfocused
THEME_FRAME_LO 80, 80, 80 Frame bottom and right, unfocused
THEME_BUTTON 60, 70, 80 Button fill
THEME_TASKBAR_BG 40, 45, 55 Taskbar background
THEME_TASKBAR_FG 220, 220, 220 Taskbar text
THEME_TASKBAR_HL = THEME_ACCENT Active menu, focused window button
THEME_INDICATOR_ON 240, 240, 245 Current workspace
THEME_INDICATOR_OFF 80, 80, 80 Other workspaces
THEME_SELECTION = THEME_ACCENT Selected item
THEME_TEXT 230, 230, 240 Body text
THEME_TEXT_DIM 175, 175, 185 Secondary text

Terminal window

The GUI terminal is an 80×24 character grid with 2000 lines of scrollback.

Feature Detail
Scrollback PgUp/PgDn, mouse wheel, and a scrollbar
History Command recall
Tab completion Builtins, .elf programs, and filesystem paths
Working directory Per-window
Colour ANSI SGR (ESC[…m) — ls --color, the editor status bar

Screen mode

Full-screen TUIs need cursor addressing, so the terminal implements a CSI parser:

Sequence Effect
ESC[row;colH Cursor position
ESC[H / ESC[f Home
ESC[2J Clear screen
ESC[K Clear to end of line
ESC[…m SGR colour and attributes

On the first CSI sequence the terminal switches from scrollback to screen mode: the line buffer becomes a fixed grid and the editing point renders as an inverted block cursor. It reverts when the command exits.

Ctrl-A…Ctrl-Z arrive as control bytes 0x010x1A for editor bindings, with Ctrl-C still raising SIGINT and Ctrl-Z raising SIGTSTP against the foreground process.

Graphical panic screen

A kernel panic draws a visual stop screen with the faulting RIP, CS, ring and error code, rather than freezing silently. Before this, a double fault triple-faulted and rebooted instantly — the IST stacks had never worked, because the TSS struct carried three leftover 32-bit dwords that shifted every IST pointer four bytes early.

Built-in applications

Ten desktop icons: Files, Terminal, Editor, Viewer, Settings, Paint, Sounds, Calc, Games, Selene, plus About and Shutdown from the Start menu. Each is a *_win.c file in kernel/.

They have their own page: Desktop Applications.

See also

External resources

Clone this wiki locally