Skip to content

GUI AWT

opencode-agent[bot] edited this page Sep 27, 2026 · 7 revisions

GUI & AWT

JNode implements a graphical user interface subsystem that supports the standard Java Abstract Window Toolkit (AWT), allowing many standard Java graphical applications to run unmodified.

Overview

Because JNode does not have an underlying host OS like X11 or Wayland, it must implement the entire graphical stack from the ground up—from writing pixels directly to the video card framebuffer, up to handling mouse clicks, and finally rendering AWT components.

Architecture

The GUI stack is divided into hardware drivers and the AWT implementation.

Location: gui/src/

1. Video Drivers (org.jnode.driver.video)

Location: gui/src/driver/org/jnode/driver/video/

Video drivers manage the physical graphics hardware through the Video-Driver-Architecture subsystem.

  • VGA/VESA: Standard fallback drivers that use BIOS calls (during boot) or VBE to set up a linear framebuffer.
  • Hardware-Specific Drivers: JNode includes rudimentary support for specific chipsets (e.g., ATI, VMware, NVIDIA) to enable hardware acceleration or better resolution switching.
  • Framebuffer (FrameBufferAPI): The driver exposes a raw chunk of memory representing the screen pixels through the Surface abstraction.

2. Input Drivers (org.jnode.driver.input)

Location: core/src/driver/org/jnode/driver/input/

Handles user interaction. See Input-Drivers for details.

  • Keyboard: Translates raw PS/2 or USB scancodes into Java KeyEvents.
  • Mouse: Translates hardware motion and clicks into MouseEvents.
  • Input events are queued and dispatched to the active AWT window.

3. AWT Implementation (org.jnode.awt)

Location: gui/src/awt/org/jnode/awt/

To support standard Java GUI applications, JNode provides a custom implementation of java.awt.Toolkit and peer classes. See AWT-Peer-Implementation for details.

  • JNodeToolkit: The entry point for AWT. When an application calls Toolkit.getDefaultToolkit(), JNode returns this instance.
  • Peers: In standard Java, peers bridge AWT to the native OS windowing system (e.g., WButtonPeer on Windows). In JNode, peers (like JNodeButtonPeer) render themselves using JNode's own 2D graphics primitives directly to the video driver's framebuffer.
  • Font Rendering: JNode includes a FreeType-based font rasterizer to render TrueType fonts onto the screen.

Desktop Environments

JNode supports multiple presentation layers:

  • TextScreen: A raw 80x25 VGA text mode interface. Used during early boot and for the raw console.
  • Swing Console: A graphical terminal emulator that draws text onto the graphical framebuffer, allowing for higher resolutions and custom fonts while presenting a traditional CLI.
  • Thinlet: A lightweight GUI framework supported by JNode for simple desktop applications.

Window Management

The SwingToolkit / Desktop layer manages window stacking, activation and repainting. Two independent mechanisms keep the framebuffer consistent:

  • Window paint clipping — an occluded JInternalFrame still repaints its full bounds (there is no damage tracking), so SwingToolkit.getWindowPaintRegions(JInternalFrame) computes the visible regions from the JDesktopPane z-order and SwingComponentPeer.getGraphics() installs them via SurfaceGraphics2D.setPaintClip(List<Rectangle>). null means unrestricted; an empty list means fully covered. See JNode-Graphics2D.
  • Activation and taskbar stacking — because a JNode window is a JInternalFrame, isSelected() is not a reliable "frontmost" test. SwingToolkit.activateWindow raises explicitly, Desktop.DesktopManagerImpl overrides dragFrame/activateFrame (the Swing defaults are no-ops), and WindowBar.isTopFrame gates iconification on real z-order. See AWT-Peer-Implementation and DesktopFrame.

Swing's z-order is index-based with lower index on top, so "in front of me" is otherZ < myZ.

Surface Integrity

Because VESACore maps a claimed MemoryResource straight onto VRAM with no page flip and a stub updateScreen(), any unclipped or unsynchronized write is instantly visible corruption. Three layers defend the framebuffer:

  • AbstractBitmapGraphics.drawPixels/fillRect clamp count against the surface width — MemoryResourceImpl only bounds-checks the end of a bulk write, so an unclamped run silently overwrites the next scanline.
  • VESACore makes every drawing entry point synchronized and fillRect clamps all four edges before delegating.
  • SoftwareCursor hides the sprite around every operation with a cursorDrawn flag, row-wise bulk save, run-length blitting, and source and destination intersection checks in copyArea.

See Video-Driver-Architecture.

GUI Testing

gui/build-tests.xml is the sixth build-tests.xml in the tree (alongside core, fs, net, shell, cli) and is picked up automatically by all/build.xml's tests target via <subant><fileset dir="${root.dir}" includes="**/build-tests.xml"/></subant>.

sh build.sh tests                                # runs all subprojects including gui
sh build.sh -f gui/build-tests.xml all-junit     # GUI suite only

gui/src/test/org/jnode/awt/swingpeers/GuiTestSuite.java is a @RunWith(Suite.class) over SwingToolkitClippingTest. The test runs in a forked host JVM (<junit fork="on" haltonfailure="on">, classpath refid="cp-test", reports to gui/build/reports/junit), compiled by the host JDK against the JNode core jar via the jnode.compile.test preset. It is headless-safe: the fixture uses a plain JInternalFrame("source") on an 800×600 JDesktopPane, not a real java.awt.Frame. SwingToolkitClippingTest lives in the same package as SwingToolkit so it can call the package-private getWindowPaintRegions, and covers: null when fully visible, one uncovered band for a single occluder, region collapse for two occluders (subtract chain 1 → 2 → 1), and the empty-list "paint nothing" contract.

Everything else under gui/src/test/org/jnode/test/gui/*.java (JInternalFrameTest, JDPTest, SwingTest, AWTFrameTest, …) is a manual main() demo app, not part of any suite. See Testing.

Related Pages

Clone this wiki locally