Alpine's libinput, libseat, seatd, xf86-input-libinput and usbutils join the image, and seatd runs from schinit. libinput lists the keyboard and pointer as an ordinary user, Xorg now drives both through libinput, and a program linked to libseat running as schos opens seat0 through seatd, is handed /dev/input/event0 and reads its name through the descriptor. Two kernel bugs stood in the way, and both would have stopped a Wayland compositor too. The socket connect() queues for a listener was allocated with its domain at zero, so sendmsg refused SCM_RIGHTS on the accepted end: a server could receive descriptors and never send one. And sendmsg treated a control buffer longer than its messages as an error, where Linux takes a following header too short to be one as the end; seatd passes a zeroed CMSG_SPACE array with one descriptor at the front. Found with /proc/strace and a temporary kinfo in sendmsg's EINVAL sites. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
79 lines
5.1 KiB
Markdown
79 lines
5.1 KiB
Markdown
# The desktop: Xorg on the framebuffer
|
||
|
||
The desktop is X11, on the framebuffer: Alpine's `xorg-server` with the `fbdev` video
|
||
driver and the `evdev` input driver, Window Maker as the window manager, and `xterm`.
|
||
`startx` runs `wmaker`. Nothing here is written by SchOS except the kernel interfaces it
|
||
stands on and four small files in `tools/posix/mkaroot.sh`.
|
||
|
||
**Xorg is the desktop for now, not for ever.** SchOS will not write its own compositor (the one it had, Schcom, was deleted).
|
||
What comes next is whichever of XLibre (the Xorg fork), Xorg or a Wayland compositor from Alpine suits the machine; the groundwork
|
||
Wayland needs — udev, `/sys/devices`, libinput, a DRM device — is in [../plan/roadmap.md](../plan/roadmap.md) §5.
|
||
|
||
## Why X and not Wayland
|
||
|
||
Every Wayland compositor worth running — labwc, and everything built on wlroots — needs
|
||
DRM/KMS, libinput, udev and libseat. DRM/KMS is the largest of them by far: a kernel graphics
|
||
subsystem, and in practice a great deal taken from Linux. Xorg runs on a plain framebuffer
|
||
through `fbdev`, which SchOS already had. That is the shorter road to a desktop by a long way,
|
||
and it brings the window managers with it. udev, libinput and libseat are now in the image
|
||
([udev.md](udev.md)); DRM/KMS is the part still missing, and it is the GPU plan
|
||
([../plan/gpu.md](../plan/gpu.md)).
|
||
|
||
## What it stands on
|
||
|
||
| | |
|
||
|---|---|
|
||
| **fbdev** | `/dev/fb0` speaks Linux's fbdev ([graphics.md](graphics.md#devfb0-and-how-xorg-draws)) |
|
||
| **evdev** | `/dev/input/event0` (every keyboard) and `event1` (every mouse and touchpad) with Linux's queries, LED writes and key/button/relative-axis bits |
|
||
| **VTs** | `/dev/tty0`, `VT_SETMODE(VT_PROCESS)`, `KD_GRAPHICS`, the release/acquire handshake ([terminals.md](terminals.md)) |
|
||
| **dlopen** | Xorg loads its drivers as modules, so `exec` does dynamic linking ([kernel.md](kernel.md)) |
|
||
| **sysfs** | `/sys/bus/pci/devices/*/{boot_vga,enable,graphics/fb0}`, which libpciaccess reads |
|
||
| **ptys** | `xterm` runs its shell on a pseudo-terminal |
|
||
| **Unix sockets** | the X11 socket, abstract names, `SO_PEERCRED`, `flock` |
|
||
| **headers** | `<linux/*.h>` in the build sysroot, as `ports/linux-headers` |
|
||
|
||
`cmd/xready` checks every one of the kernel calls Xorg makes before it draws anything — the
|
||
evdev queries, the fbdev calls, the console calls, and the `/sys` files — one at a time, on a
|
||
terminal of its own, and puts everything back. The calls were written against what the
|
||
programs are documented to do; each step past it found one that was not, which is what running
|
||
the real program is for.
|
||
|
||
## The four files
|
||
|
||
- **`/root/.xserverrc`** starts `X` on the VT `startx` was started from (startx works that
|
||
out only when `uname -s` says Linux, and SchOS's says SchIFT). It used to add **`-dumbSched`**,
|
||
Xorg's switch for reading input on the main loop, because Xorg normally reads input on a
|
||
thread of its own and, when SchOS had no threads, the server crashed the first time a client
|
||
disconnected, in `pthread_join` on a thread that was never made. Threads exist now and the switch
|
||
is gone: under QEMU, X starts with Window Maker, `xclock` and `xeyes` connect and disconnect, an
|
||
`xterm` runs and exits, and the server stays up.
|
||
- **`/root/.xinitrc`** is `exec wmaker`. Without it xinit falls back to twm and an xterm, which
|
||
are not in the image.
|
||
- **`/etc/X11/xorg.conf.d/10-schos.conf`** holds what the defaults do not give: Ctrl+Alt+Backspace
|
||
enabled, the keyboard options, and the framebuffer driver. Input devices are *found*, not
|
||
named: Xorg asks libudev, which reads what `udevd` wrote to `/run/udev` ([udev.md](udev.md)).
|
||
- **`/etc/asound.conf`** is for sound, not X ([audio.md](audio.md)).
|
||
|
||
## Using it
|
||
|
||
Twelve virtual terminals, switched with Ctrl+Alt+F1–F12 — on the console and under X
|
||
alike, because X owns the keyboard while it runs and switches only with that chord. `startx` on
|
||
a terminal runs the desktop there; Ctrl+Alt+Backspace ends the session and gives the terminal
|
||
back. Window Maker, `xterm`, `xeyes`, `xclock`, `xcalc`, DejaVu fonts; SDL 2 games
|
||
(`lbreakouthd`) and NetSurf, a GTK 3 browser, run in it.
|
||
|
||
Touchpads that sit on an I2C bus (most laptops) are driven by `kernel/acpi/i2c_hid.c`, found
|
||
through ACPI, and reach X as a mouse: pointer, click and tap.
|
||
|
||
## What it does not do
|
||
|
||
- **No acceleration.** Software rendering to the framebuffer: no DRM, no glamor, no DRI, no
|
||
OpenGL beyond what software gives. GPU drivers are a plan ([../plan/gpu.md](../plan/gpu.md)).
|
||
- **udev covers the kernel's own devices only.** Input, terminals, memory devices, the
|
||
framebuffer and disks are announced; PCI and USB devices are in `/sys/bus/*/devices` but are
|
||
not yet in the `/sys/devices` tree or on the uevent socket ([udev.md](udev.md)).
|
||
- **Touchpads are mice**: no two-finger scroll, no gestures, no palm rejection.
|
||
- **No resolution change from inside X.** The mode is the console's; `schmode` changes the
|
||
`vgpud` head only, and the loader's menu is where a real panel's mode is chosen.
|
||
- **Runs as an ordinary user.** `startx` as `schos` works by group permission alone
|
||
([users.md](users.md)); X itself is still a single seat with no logind or seatd.
|