X: The First Fully Modular Software Disaster
art.net
art.net
And in many ways they're not wrong:
- "X has defeated us by switching the meaning of client and server"
- "most computers running X run just four programs: xterm, xload, xclock, and a window manager" : the intervening 20 years have added a web browser. Almost all software run by the user is in either the xterm or the browser.
- ICCCM is hilariously complicated, although cut-and-paste largely works now. It's just that there are two different cut-and-paste mechanisms in play.
- client/server division of labour is still being fought over on the web
- X authentication is painful to do with the original mechanism, but was eventually fixed by ssh X forwarding
- Xdefaults is a great mystery, largely obsoleted by the GNOME people with their own mysterious pseudo-registries and, god help you, polkit
- X still has trouble with the wide variety of graphics hardware out there, although you can usually get 2 monitors working eventually.
- "NeWS an d NEXTSTEP were political failures because they suffer from the same two problems: oBNoXiOuS capitalization, and Amiga Persecution Attitude(TM)." : basically true, until they dropped the attitude and capitals and became Cocoa.
If you think in terms of network programming, "server" is the program that accepts incoming connections and handles requests from clients, and "client" is the program that initiates the connection and sends requests, it is not confusing at all.
The security part is true, though. X authentication sucks, and using ssh might make that usable (plus, encryption), but that is kind of like saying that eMail is not a secure communication channel, but PGP solved that.
But there is no alternative that solves the problems with X while keeping or improving upon its strengths (that I know of, I should add):
The "mechanism not policy" part is the reason it is possible to choose from several desktop environments.
Also, X has achieved something that no other current windowing environment can do: Transparent, cross-platform windowing. There are X servers available for all the free Unices, macOS, Windows, and once upon a time, I am told, for OpenVMS, too.
I am not an authority on designing network protocols by any standard, first using two separate connections for commands and data seems strange enough to begin with (at least to me). But I cannot imagine what possible reason the people who designed the protocol had.
To be clear, I am not certain if I would have done a better job.
Either way, I was very happy when I discovered sftp. :)
Do remember that FTP is very, very old. It's from 1971.
One also has the impression that FTP was supposed to be integrated into your shell and avoid the clunky client entirely, but the design wasn't quite there to support it, so we got the worst of both worlds. A funky network protocol that ran into a lot of trouble when firewalls and NAT appeared and a primitive placeholder client that only downloads a single file at a time.
Mathematics -> maths
You don't say, "I am learning mathematic", unless you are a cretin.
I can’t really come up with a situation where you would want to refer to multiple “mathematicses”; it kind of just is something ethereal, not a _thing_ where it makes sense to refer to one or many.
So why is "maths" plural? It's sure as hell not countable. What is "a math"?
At least "mathematic" makes sense—you can deconstruct the morphology to understand this is "a lesson", i.e. the gerund of "to learn". It's also the natural english adjectival form of the greek word.
"maths" is just weird. You might as well use "magicks".
Of course :-)
You should see my mathematic 8)
Here's a link to the book in its full glory:
Don't forget random enterprise software installers that insist on a graphical mode even though they could never successfully be operated by someone who isn't comfortable on the command line
I just opened up "clocktab.com" on Chrome, the first simple clock I could find by googling "clock," and Chrome's task manager shows it using a full 42 megabytes of memory.
Most of the implementational details would appear to be buried in files on engineering workstations at Chinese factories.
I found a calculator teardown at http://electronupdate.blogspot.com.au/2016/08/reverse-engine... a while ago. The author says it's very old but doesn't provide a ballpark (eg, 1990, 1995, 1998, 2003, etc). It does look quite hairy (and possibly not particularly compactly designed?).
I would guess there's a ridiculously simple ALU somewhere in there, but I wonder what else is involved in the specific context of a high-production-volume fixed-functionality design.
I hope to find something similar for a clock at some point.
I needed space on my phone the other day so I deleted the flashlight app, which turns an LED on and off, recovering 79 megabytes.
This clock sample ( https://github.com/c-smile/sciter-sdk/blob/master/samples/gr... ) is a port of Mozilla's clock : https://codepen.io/anon/pen/vJpqOY
Chrome needs 6 separate processes to run this sample with total memory consumption of 575 Mb.
Screenshot: https://i.imgur.com/09xjyPs.png
[1]: https://archive.org/details/msdos_win2_03
[2]: https://support.microsoft.com/en-us/help/32905/windows-versi... ("512K of memory or greater" for 2.03).
E.g. on DOS, with direct memory access (plus maybe some INT 10h helpers to draw the digits; although Windows clock doesn't draw them) in video mode 13h, you could do this with a .COM program that would be under a kilobyte total in and of itself. If you counted DOS itself, you'd still be under 64k.
(I realize there are ways to get this down to probably the sub-1kB level, but I wanted something I could generate reliably on the fly in a shell script, so...)
And by extension, the rather complex set of POSIX exit() semantics: http://pubs.opengroup.org/onlinepubs/000095399/functions/exi...
Using something like musl should save you some bloat, or simply call "return 0;" instead of exit().
Think about it: how many pieces of software design have remained in heavy use worldwide for 30 years. The fact that no one bothered to replace it in all that time is proof enough that whatever warts it has can't be that painful. (Now, finally, it seems like it's going to happen with Wayland, but it's not there yet.)
Not only that, but computer display technology has changed massively over X's lifetime. I'm writing this in a composited window manager hardware accelerated via natively-3D hardware outputting to multiple monitors of different resolutions over as many different digital display links. How much of this was even imagined in the 1980s? Yet the X protocol via it's extension mechanisms has proven adaptable enough to take in massive changes in the technology, and still keeps on ticking.
And to your point, there isn't a single display framework as old as it is that's still used.
> I'm writing this in a composited window manager hardware accelerated via natively-3D hardware outputting to multiple monitors of different resolutions over as many different digital display links
And I'm writing this from a very underpowerd netbook with no working hardware graphics and everything still works. Try that with windows 10, wayland, coaca or whatever other display framework you like.
I'm not convinced modern software ecosystem optimizes for quality. Many CAD packages used today have roots as old or older. The dominant CAD format (at least in construction) is DWG which - I can tell you from experience - is about as nice to work with on programmatic level as trying to skin rotten cod. The data contained in this steaming heap of obfuscation is mostly trivial in complexity. Just because we have tools in use does not mean they could not be better - it's rather that once something is in use, social proof, sunk cost fallacy and some practical reasons kick in and development stagnates to dealing with the kinks in the established system.
Unix itself.
https://github.com/freebsd/freebsd/blame/e278a20c2ee54d8fa1a...
And if you look at lines that were changed, quite often they are style changes/fixes.
Unfortunately, the easy-to-trace history doesn't go back further than that, but I think it's reasonable to assume that some of these lines, at least, could be dated back to before 1987.
I was actually assuming that most people today were running Linux, but I forgot that Macs use pieces of BSD.
For starters: The Unix that I (and quite a lot of other people) use today shares entire manual pages with the Unix of more than 30 years ago.
An example: The manual page for the ul command that was written by (then) Mark Horton is pretty much unchanged today in FreeBSD and NetBSD. For 34 years, it hasn't actually described the command correctly or fully.
I think you've got this backwards. The worse a piece of software is the harder it is to work out how it works, upgrade it, replace it with compatible software, etc.
More examples: plenty of people knew OpenSSL was awful but have you seen the code? Nobody sane is really going to want to work on it. It took a catastrophe to change that.
An even better example: LAPACK. It's been around since 1992, and until fairly recently was written in FOTRAN77. Yes, the one where function and variable names can't be longer than 6 letters or they won't fit on punch cards. Take a look:
http://www.netlib.org/lapack/explore-html/dc/dd2/group__doub...
Yes, nobody is going to rewrite most of that. (Actually there is Eigen now thankfully, but it took some time!)
When I learned it, I realized that it is excellently designed.
In the sense that (in the words of my pathologist father when I asked him how hard drug discovery and design was),
"Nature is lazy before it's intelligent. At every turn, it would rather reuse a system designed for a completely different purpose than design something new from the ground up. Which is how we end up with single pathways affecting six completely unrelated systems in the body."
So we can blame all the crazy things we do with computers and software on nature? ;-)
But seriously, that is a great insight. Both where evolution is concerned, and software development. (And other branches of engineering, too, I bet.)
Sure it's a text and you do regexes to specify objects, but I found it easy to customize and because much of it was automatic there would be a ton of the UI variables in it. You want a different color on the background of a particular text box? No problem. You want to change the font used in the app? No problem. You need to customize the contents of a menu? That might be possible! Every application used the same file so you only had to figure it out once.
Granted, you would leave 99% of the variables alone, but it was nice to have the option if you needed it.
Interestingly enough, I still have the file on my box, although I doubt it gets used much anymore. Looking at the file I forgot how you could do a sort of primitive themeing by specifying broad wildcards like "* MenuButton.Background" and "* Toggle.Font"[1]. That's probably a bit dangerous but I can't remember it ever exploding on me spectacularly. Probably because Athena widgets were so damn minimal to begin with.
Oh, man it even still has:
Netscape4*blinkingEnabled: False
Netscape4*myshopping.isEnabled: False
[1] The spaces aren't there in the file, they're just necessary to work around the way HN's markdown does italics.I judge that the authors’ rejection of mechanism/policy separation as a guiding principle of X was foundationally mistaken. I argued in The Art of Unix Programming that this principle gives X an ability to adapt to new technologies and new thinking about UI that no competitor has ever matched. I still think that’s true.
But not all the feces flung in this chapter is misdirected; Motif really did suck pretty badly, it’s a good thing it’s dead. ICCCM is about as horrible as the authors describe, but that’s hard to notice these days because modern toolkits and window managers do a pretty good job of hiding the ugliness from applications.
Though it’s not explicitly credited, I’m fairly sure most of this chapter was written by Don Hopkins. Don is a wizard hacker and a good man who got caught on the wrong side of history, investing a lot of effort in Sun’s NeWS just before it got steamrollered by X, and this chapter is best read as the same bitter lament for NeWS I heard from him face to face in the late 1980s.
Don may have been right, architecturally speaking. But X did not win by accident; it clobbered NeWS essentially because it was open source while NeWS was not. In the 20 years after 1987 that meant enough people put in enough work that X got un-broken, notably when Keith Packard came back after 2001 and completely rewrote the rendering core. The nasty resources system is pretty much bypassed by modern toolkits. X-extension hell and the device portability problems the authors were so aggrieved by turned out to be a temporary phenomenon while people were still working on understanding the 2D-graphics problem space.
That having been said, Olin Shivers’s rant about xauth is still pretty funny and I’m glad I haven’t had to use it in years.
> The right graphical client/server model is to have an extensible server. Application programs on remote machines can download their own special extension on demand and share libraries in the server. Downloaded code can draw windows, track input eents, provide fast interactive feedback, and minimize network traffic by communicating with the application using a dynamic, high-level protocol.
Certainly sounds a heck of a lot like how web applications work (even though we're currently terrible at sharing libraries, heh).
> X gave programmers a way to display windows and pixels, but it didn't speak to buttons, menus, scroll bars, or any of the other necessary elements of a graphical user interface. Programmers invented their own. Soon the Unix community had six or so different interface standards.
Now _that's_ certainly familiar. Sure, the DOM is a heck of a lot closer to a platform for displaying complex UIs than X was, but it still falls so far short of what developers need that a plethora of frameworks, UI libraries, etc. have appeared and fragmented the community. You could also stretch a bit and say things like Google's work on web components are an attempt at a Motif-like standardization around one questionable standard, but I don't know if I'm quite cynical enough to make that jump.
> Even if you can get an X program to compile, there's no guarantee it'll work with your server. If an application requires an X extension that your server doesn't provide, then it fails. X applications can't extend the server themselves -- the extension has to be compiled and linked into the server.
While a lot of new browser features are polyfillable, a lot of the more advanced ones (e.g. service workers) are not, and users and developers are at the mercy of their browsers, much users would be with their X servers.
> Myth: X is "Device Independent"
The quirks discussed in this section apply to responsive web apps too. There's actually quite a bit of nuance in making fancy canvas, WebGL, or CSS transforms that look good on retina screens, etc.
I'm sure none of these comparisons truly map 1:1 to X development (having never done it myself), but damn if it doesn't remind me how cyclical software development has been over the past few decades. Not that that's a bad thing, just that some things are very, very hard :)
NeWS was architecturally similar to what is now called AJAX, except that NeWS coherently:
+ used PostScript code instead of JavaScript for programming.
+ used PostScript graphics instead of DHTML and CSS for rendering.
+ used PostScript data instead of XML and JSON for data representation.
Hahaha
Both are asynchronous RPC protocols with bindings generated from a bunch of XML specs. Both use shared memory aggressively. Both share a lot of concepts. X just has more back-compat to deal with.
However, there is one significant architectural difference between X and Wayland that is quite difficult to evolve away. In modern X, there are actually three processes involved: the client (app), the X server, and the compositor. In Wayland, there are only two: the client (app) and the compositor.
The X design is more fragile (state managed in 3 places instead of 2) hence ICCCM, and has more latency and overhead. However, it made a lot of sense back when the X server talked to the hardware directly and therefore needed both an integrated driver and special privileges. It'd be silly to implement drivers as part of compositors, so the separation of mechanism and policy was the right way to go back then.
Since then, however, the mechanism has basically entirely moved into the kernel (DRM/KMS) and Mesa (OpenGL). This happened in bits and pieces first with the evolution of the DRI protocol and then the jump to kernel mode setting.
That is the evolutionary development which lead to the move to Wayland makeing sense.
I suppose this 3-to-2-process transition could have been evolved by refactoring the core of the X server source (the whole protocol handling etc.) into a library that compositors then simply link against. But that would have been a truly herculean task with not very many natural intermediate steps. Implementing something like Wayland from scratch on the modern Linux graphics stack is actually much less work -- except perhaps for transitioning all the toolkits, but then again, the X server source lends itself fairly well to writing various "X-on-something-else" servers, since people have been doing that for a while, so there's a natural if slightly awkward solution for backwards compatibility.
So hacking up an initial prototype for Wayland could be done very quickly, but note that actual adoption still took a long time. But the point is that the Wayland path had more presentable intermediate steps (unlike the X server refactor), so that's the path that software evolution took.
(Man, this got a lot longer than originally intended...)
Is the compositor not optional?
Youtube talk about it: https://www.youtube.com/watch?v=RIctzAQOe44
I remember connecting to my desktop from a computer on the university using NX protocol and running remote apps like was on local. And I don't had a superb internet connexion.
It is called RemoteApp on Terminal Services and exists since 2008.
https://technet.microsoft.com/en-us/library/cc753844(WS.10)....
When we got internet connectivity at Sydney University we used to just dump X-Windows from all over the world. One in particular was some displays in Sweden. Forget what was actually on them though.
Most of the rest of the complaints come off as someone with an axe to grind, especially all of the hand-wringing over flipping the client and server model around. It's not like X was the first system to do that, active mode FTP does exactly the same thing. Back in the days before firewalls and NAT this was a legitimate design decision, they just ended up on the wrong side of history.
Besides, from a network architecture standpoint it makes sense. Your local X display doesn't know that you've started an app on a remote box until something tells it. Having it make the connection out would require some local broker to inform it that it needs to make the connection.
I will agree with one point, ICCCM sucks and has been overdue for a complete rework for at least 20 years now. That said, I'm not a fan of Gnome's Ctrl-Shift-C Ctrl-Shift-V workaround either.
And Motif is based on that very same code.
http://www.art.net/studios/hackers/hopkins/Don/unix-haters/x...
At one point I got frustrated and hacked the window manager (probably piewm) so I could pass it a command line parameter telling it the window ID on which to run instead of the root framebuffer, and then I ran it on the XCalc window, so I got window frames around all the buttons and could pop up menus on them, move them back to where they belonged, resize them, iconify them, etc.
Yay ICCCM! How powerful! It was totally worth ICCM being that complicated and pushing all that complexity into every other toolkit and application, just in order to make that trick possible just once.
you know what, I love http://www.crynwr.com/piewm/ screens a lot. I'm deep into a retro 8bit mindset these days. Very fitting.
Alas I never had to write code for it, but I like the idea and look.
Here's a version of the original X10 "uwm" window manager from which "piewm" is a distant descendent (pre-ICCCM, for X10, not X11), that I hacked to implement my original version of pie menus, and then integrated with FORTH, so you could program the window manager in FORTH (foreshadowing programming NeWS in PostScript), and even fork off light weight FORTH tasks to bounce the windows around!
http://www.donhopkins.com/home/archive/piemenu/uwm1/
http://www.donhopkins.com/home/archive/piemenu/uwm1/fuwm-mai...
Here's the bouncy window code, including some reverse polish notation 68k assembler code for 256/ and 256*:
funny http://www.donhopkins.com/home/archive/piemenu/uwm1/call-ema... ;)
ps: I couldn't locate the actual exec_string that interpret Forth
That code you linked to is from Mitch Bradley's "Forthmacs", which ran on Sun workstations including 68k i86 and SPARC, and also Atari ST, Mac and other systems. He developed it into the "Open Boot ROM" architecture, which was used in Sun workstations and Apple PowerPC Macs as well as the OLPC children's laptop.
https://github.com/ForthHub/ForthFreak/blob/master/Forthmacs
https://en.wikipedia.org/wiki/Open_Firmware
http://wiki.laptop.org/go/Open_Firmware
On SunOS, Forthmacs had a library clink.f with the ability to dynamically relocate and link Unix libraries so that you could call them from Forthmacs, pass arguments on the stack, etc. SunOS didn't actually support shared libraries or dynamic address relocating at that time, so Forthmacs simply ran the Unix linker utility to create a file with the library relocated to the desired address space in the FORTH dictionary, and then read that file into memory, define its symbols in the FORTH dictionary, and let you access its variables and call its functions directly from FORTH!
That's how Mitch originally integrated MicroEmacs with Forth to make Forthmacs, and how I later integrated "uwm" into FORTH: I refactored uwm so instead of having an event loop in the main function, it was a library that could be called by FORTH, which would link the library in and run the main loop itself, calling into the library as needed to initialize and handle specific events (_uwm_init, _uwm_poop).
http://www.donhopkins.com/home/archive/piemenu/uwm1/fuwm-mai...
Here's the glue that links in the uwm library from fuwm.out:
http://www.donhopkins.com/home/archive/piemenu/uwm1/load-fuw...
.( Loading...) cr
requires tasking.f
requires uwm.f
requires clink.f
.( Linking...) cr
"" fuwm.out clink
.( Linked!) crYour xcalc screen shot made me think of that and smile a bit.
That someone could write a book on UI programming and someone else would publish a book on UI programming without any actual depictions of UI is pretty much all I need to know about X and its community (although I know a lot more, and my actual exposure to X goes back to early versions that came on 9-track tapes directly from MIT and supported mostly just frame buffers on DEC Vaxen).
(For years -- and this may still be true -- the software to manage the equipment in Comcast's head end datacenters was controlled by some X-based UI. Now, I ain't gonna say "Them folks surely deserve it, because they done me wrong" but that miserable train-wreck of a system goes a long way towards explaining why it's often hard for Comcast to fix their stuff. I have un-fond memories of taking down whole QAMs because I was fool enough to click some check boxes in a dialog in the wrong order...)
You can write hideous UI in just about anything, but X seems to have a special place in the ecosystem.
Then TCL/Tk came along and emulated Motif's look and feel, only better because its default color was bisque.
"Bisque is Beautiful"
http://www.ucolick.org/~de/Tcl/pictures/
"The procedure tk_bisque is provided for backward compatibility: it restores the application's colors to the light brown (“bisque”) color scheme used in Tk 3.6 and earlier versions."
https://www.tcl.tk/man/tcl/TkCmd/palette.htm
http://mars.cs.utu.fi/BioInfer/files/doc/public/Tkinter.Misc...
I've written software that uses both and I don't remember thinking that one was significantly easier than the other, I did dislike that they took control of the main loop, Plan9's method of synchronous event polling is much nicer IMO.
And yeah it is heavier than Motif. It does a lot more with it, though. Whether you think those things are valuable or not presumably depends on what software you use and your own sense of aesthetics.
Also when GTK+ was created, Motif was proprietary. There was Lesstif, but if I recall correctly that wasn't all that good, so there was a good incentive to develop a Free Software GUI toolkit.
I still use X display forwarding regularly. Often for something like sending a Firefox window back so I can look at a page on a test network without needing a direct route to it.
There just wasn't very much PEX interoperability between different manufacturers, because of all the different extensions. Only a rare vanilla app could be remoted in a heterogeneous environment.
Some vendors, like E&S, had PEX as the native graphics API. You could not write a purely local app that couldn't be opened remotely, including stereo displays (CrystalEyes) and use of dialbox or spaceball input devices.
And DirectX offers so much more than downgraded OpenGL ES 3.0 (aka WebGL 2.0).
All of this seems to render linux pretty useless for hot-pluggable displays. I'm sure ubuntu has some sort of solution (I never use the desktop version); why can't this be integrated at the level of the X server (or hell, the graphics driver) itself? Is X too firmly baked to adjust to the needs of its users? Will wayland address this?
To annoy X fanatics, Don specifically asked that we include the hyphen after the letter "X,", as well as the plural of the word "Windows," in his chapter title.