A little over two years ago, I wrote about 3 Decades of OpenWindows and how I had ported XView and OWacomp to RHEL 8 with GCC 8.5. At the time, I had tried asking ChatGPT for help and found it about as useful as "Captain Obvious" — it paraphrased compiler errors without understanding the codebase.
Things have changed dramatically. Over the past week, I've been working with Cursor, an AI-powered IDE, to port and modernize several legacy OpenWindows applications. The difference between what was possible in January 2024 and what is possible in March 2026 is staggering.
What We Accomplished
In the span of a few days, Cursor helped me complete work that would normally have taken weeks of careful manual porting:
On the library side, several foundational libraries were ported to make the application work possible:
- libXol (OLIT) — The OPEN LOOK Intrinsics Toolkit, Sun's Xt-based widget set. Required for olprops and the OLIT sampler/table demos.
- libtt / libdstt — The ToolTalk messaging libraries, originally part of Sun's inter-application communication framework. Required by several DeskSet tools.
With these libraries in place, the following applications were ported and enhanced:
- olprops — The full-featured OLIT Workspace
Properties editor from Sun's WS_OLS10 was ported from Solaris to
Linux, including Xt resource handling and Solaris workspace tile
patterns. This replaces the more limited XView
propsclient. - contool 3.3a — The classic console message
tool was ported to Linux with a modern twist: instead of reading
from
/dev/console(which requires root on Linux), it now integrates with the systemd journal viasd-journal, streaming system messages in real time through the existing XView filter and display pipeline. - bibcard 1.11 — The bibliography card manager, built with Guide/libguidexv, was ported with its extensive UI intact.
- meminfo 1.3 — This C++/UIT system monitor was ported and then enhanced with HugePages gauges (2MB and 1GB from sysfs), dynamic MB/GB unit formatting, and a clean exit path that avoids the C++ global destructor vs. XView notifier conflict.
- workman 1.3.4 — The CD player was hardened to start gracefully on modern systems that lack a physical CD-ROM drive or OSS mixer device, with properly grayed-out controls instead of crashing on startup.
- privtool 0.90 — The PGP-aware mail reader
had its file locking and temporary file handling fixed to work
without the
mailgroup privileges it assumed on older systems. - wsinfo 0.1.5 — The workstation information
tool was modernized with an OS field that reads
/etc/os-releaseinstead of dumping the full kernel string, a separate Kernel field, dynamic memory units, and a new OWacomp Release field.
The Nature of the Code
These are not trivial applications. They were written in the early
1990s for SunOS and Solaris, using toolkits (XView, OLIT, UIT) that
have been unmaintained for decades. The code is full of K&R C
function declarations, sys_errlist[] instead of
strerror(), BSD-style pseudo-TTY handling, Solaris
STREAMS ioctls, and assumptions about /dev/console
behavior that no longer hold on modern Linux.
The porting work involved converting K&R declarations to ANSI C,
replacing BSD PTY loops with POSIX openpty(), adapting
/proc parsing for the modern Linux format, dealing with
32-bit compilation requirements (the XView and OLIT libraries are
only available as 32-bit), and handling the subtle interactions
between C++ global object destructors and the XView notifier's
shutdown sequence.
How Cursor Helped
What made Cursor effective where ChatGPT had failed two years ago was its ability to work within the codebase. It could read the actual source files, understand the existing patterns, search for how other parts of the code handled similar problems, and make targeted edits that respected the project's conventions.
The workflow was genuinely collaborative: I would describe what I
wanted ("port contool to Linux" or "make workman start without a
CD-ROM"), and Cursor would explore the source, propose changes,
and I would review every source-level change, build and test on
the actual systems, and sometimes write or fix code myself when
I knew the codebase better than the AI did. When something
didn't work — a segfault, a layout issue, a build error
— I'd share the error output and we'd debug it together,
sometimes using gdb backtraces to pinpoint the
exact issue.
It wasn't perfect. NFS caching across my cluster sometimes meant the AI was looking at stale file contents. The RPM spec changelog dates needed manual verification (rpmbuild catches day-of-week mismatches). And some decisions — like whether to rename a directory or how to pair OWacomp releases with XView versions for the website — required human judgment about project history and conventions.
But the mechanical parts — converting function signatures, writing Makefiles, adapting API calls, structuring RPM spec entries, reorganizing website publishing scripts — were handled quickly and accurately. The time I saved on boilerplate let me focus on testing and making design decisions.
The Bigger Picture
I'm still not a C programmer by trade. I work in IT. But with the right tools, I can keep a 30-year-old desktop environment running on modern RHEL 9 with a level of effort that would have been unthinkable even two years ago. The codebase went from a handful of ported clients to a full suite of DeskSet-style tools, all building cleanly as 32-bit RPMs on both RHEL 8 and RHEL 9.
The rabbit hole keeps going, and I'm still willing to follow it.
The latest OWacomp and XView RPMs are available on SourceForge and GitHub.
