10 ms·
Opening Windows in Linux with sockets, bare hands and 200 lines of C
- pestatije 2y agoX11 Windows, not the obvious Windows
- Narishma 2y agoYes, I don't know why they changed the title to make it confusing.
- yjftsjthsd-h 2y ago> I was very surprised to learn that it is actually just a “regular” network protocol for two parties to communicate like HTTP, FTP, IMAP, SMPT and etc. Typo: Simple Mail Transfer Protocol And I suspect many of us tend to think of those as magical abstractions best dealt with through libraries as well:)
- bandrami 2y agoFor years I checked usenet by just telnetting on port 119
- linuxlizard 2y agoWhen I first started using UNIX (Ultrix on a DECStation), I was floored by the wizardry of "hackers" sending me email from Santa Claus. Mind blown!
- coldpie 2y agoI did some work on a MTA a while back and it was genuinely pretty neat to send legit emails to my real mail accounts by just connecting to a port and typing the raw SMTP commands into it. E.g. https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#SMTP_transport_example https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#... Simpler times, when we thought we could trust everyone on the net :)
- anthk 2y agoUsenet gives full help over telnet, it's nice.
- PlunderBunny 2y agoTo someone that’s reasonably computer savvy (professional developer but Windows and macOS only), what does X11 do? What are the benefits of this approach? What’s the ‘equivalent’ in Windows or macOS (if there is one)?
- erik_seaberg 2y agoA user on any X11 desktop can open a GUI from any X11 app, even one running in a datacenter. It's like a Javascript app in a browser today, but every Unix GUI app knew how to do it on late 1980s hardware, so you didn't even have to buy and admin a complete desktop computer for each user. Windows sort of has this with RDP, but it's tied in with the app's GDI desktop, and I don't know whether it works without buying a bunch of video cards for the headless app server. NeXTSTEP had Display PostScript (remote rendering worked like printing!) but macOS lost support for it.
- IAmLiterallyAB 2y agoSomewhat misleading. Because these days, none of the network transparent primitives are used anymore. All the rendering happens server side, and bitmaps are sent over the wire. It's basically a crappy VNC. And at that point, just use RDP or VNC
- erik_seaberg 2y agoYeah, I have nothing constructive to say about apps and toolkits that choose only local rendering with no hardware, but it's pretty funny to see Javascript apps beating them on performance.
- donio 2y agoThat greatly depends on the type of applications you run and the toolkits and font rendering they use. My most commonly used applications (terminal emulator, Emacs) do their font rendering using the the glyph compositing functionality of the RENDER extension. Server side glyphs are created when a font is loaded and all the compositing is done on the server side based on the client's CompositeGlyphs requests. Same for images (in Emacs) using CreatePixmap and CopyArea.
- leeman2016 2y agoI think the “Windows” in the title should be written with small “w”
- galkk 2y agoeven if this is technical article, the title is very clickbaity.
- p4bl0 2y agoYes, and the first sentence of the post should have "a window" rather than "a Windows", because as is it add to the title's confusion between X windows and MS Windows.
- deleted 2y ago[deleted]
- regularfry 2y agoDefinitely, the actual article doesn't have a capital.
- aidenn0 2y agoI share the author's opinion that xlib is harder to grok than the X11 protocol, because it's the X11 protocol plus a queuing system where you will sometimes receive out-of-band messages, plus a large number of seldom-used utilities.
- toast0 2y agoYeah, I've not been a fan of xlib. xcb is a much better library, IMHO, although it's not much more than talking X11 yourself. With Xlib, it seems like they tried to make things 'easier' by having high level concepts and a lot of synchronous apis, but they don't really fit on top of X, so you're fighting the library. Unfortunately, xcb came later and lots of things were already built on xlib, so lots of software has unnecessary synchronicity that makes things slow when you use the network stuff.
- donio 2y agoWorking with X11 client libraries written in other languages is a revelation in how much nicer an X11 client can be. CLX (Common Lisp) or xgb (Go) are some good examples. (Talking about native implementations here not xlib bindings).
- vidarh 2y agoSame here. My window manager, terminal, (very basic) file manager all use pure Ruby X11 bindings, and the more I looked at where Xlib deviates (wraps, obscures) the protocol, the more places it felt easier to just use the X requests directly. I haven't looked at XCB much, but my understanding is that it's a much more direct binding to the X protocol, so if I were to write an X client in C using a client library, I'd almost certainly look at XCB rather than Xlib.
- BirAdam 2y agoI’d love to check out your Ruby code. Link?
- freedomben 2y agoI'm not GP, but I'm pretty sure this is it: https://github.com/vidarh/rubywm https://github.com/vidarh/rubywm I remember seeing this on HN a few months ago and thought it was super cool. Edit: https://news.ycombinator.com/item?id=39087609 https://news.ycombinator.com/item?id=39087609
- hiccuphippo 2y agoRelated, a talk about replacing Xlib with their own abstraction with zig: https://www.youtube.com/watch?v=aPWFLkHRIAQ https://www.youtube.com/watch?v=aPWFLkHRIAQ
- izoow 2y agoWas just about to mention this. Also, just to add to this, even though it's a zig talk, it's not really the main focus of the talk. I enjoyed it and I don't even know zig.
- bitwize 2y agoOne of the neat things we'll be losing with X11 is the fact that you can do graphics -- fast -- entirely with the wire protocol. It was really a protocol for a sort of smart graphical terminal, so it's like having an Amiga blitter at the other end of the network connection. From a "zero to something on the screen" standpoint, it's fast and convenient, as you don't have to manage your own framebuffer, shaders, dirty rectangle list, or any of that. Of course, as any Gen-Z graphics hacker will tell you, That's Just Not How Things Work Anymore, and rendering is and should be client-side, leaving the compositor to only present the final display. But it was fun while it lasted.
- duskwuff 2y ago> One of the neat things we'll be losing with X11 is the fact that you can do graphics -- fast -- entirely with the wire protocol. As long as you only want to do very basic graphics -- no antialiasing, no color blending, no subpixel coordinates. And it isn't even that fast; everything ends up rendered on the CPU, possibly even all on a single thread, using code paths that haven't seen much optimization in the last 20+ years.
- sprash 2y agoThis is why the XRender extension was introduced. There you have antialiasing, all blending modes you could wish for, subpixel coordinates, advanced drawing operations like gradients and it is fast because it is fully hardware accelerated. All working over a very efficient wire protocol. E.g. Cairo uses Xrender as a backend.
- nly 2y agoIt's not all hardware accelerated though is it. Both the X server and Cairo depend on the pixman library, which is a CPU/SIMD optimized pixel manipulation library. Even xf86-video-intel, the intel X11 driver package, on my system depends on pixman.
- flohofwoe 2y agoNothing on your feature list is incompatible with a client/server approach though. The only downside would be when large data blobs need to be sent over a network each frame. In the end, modern 3D APIs are also just a 'wire protocol': rendering commands are recorded by the CPU into local command buffers and played back by the GPU (which is often connected to the CPU by a comparatively slow bus), the only limiting factor is the amount of data that's communicated between the CPU and GPU - and of course any additional latency that would be added by a network connection.
- throwaway984393 2y ago[dead]
- txdv 2y agoThe X Windowing system is a hackers delight. If you have a remote server with UI, you can set up a X Window server on your Windows/MacOS machine and forward via SSH X messages to use GUI apps on your server, but view the result locally. The Responsiveness of the UI depends on your network capabilities.
- cyberpunk 2y agoMeh we used to have to install oracle databases this way, and the performance was always shit even over direct connections w/cross cables. I don’t think x over ssh is useful for much, can you imagine a browser this way?
- tjoff 2y agox2go is a bit smarter than pure x-forwardning and also allows you to resume a session at a different time (or on a different machine) similar to something like tmux. Much much better performance and does pretty well even on cellular. A bit rough around the edges but brilliant for some usecases.
- SassyBird 2y agoIt’s usually SSH that’s the bottleneck though. If you just expose your local X11 TCP server port and connect to it from the server (X11 client) by setting the DISPLAY env properly, it will be much more responsive. Often indistinguishable from local apps. Secure the port with Wireguard, if you want to be a bit more responsible and still have good performance. Checked with Firefox, which works like a charm this way, but is unusable over SSH.
- guenthert 2y ago> If you just expose your local X11 TCP server port and connect to it from the server (X11 client) by setting the DISPLAY env properly, it will be much more responsive. That's fine on a LAN with low or sub ms latency. If you need to connect to a server on the other side of the country, you'll want a less chatty protocol, e.g. X2GO (which gives additional benefits, e.g. of restartable sessions).
- throwthrow5643 2y agoCan you do the same but in Wayland next?
- odiroot 2y agoI'd like to see exactly that. Hello World in Wayland is so much more complicated.
- stephan-cr 2y agoI think Wayland works similarly, in a sense that you open a Unix domain socket and send and receive bytes, see https://wayland.freedesktop.org/docs/html/ch04.html https://wayland.freedesktop.org/docs/html/ch04.html. But I'm pretty sure it's more complicated than I think. :-)
- mananaysiempre 2y agoThere are some things that are more compilcated, e.g. you need to bring your own libraries for font support and input methods and rasterization and so on, and you need to handle hotplugged input devices and such. But protocol-wise it’s not really more conplicated, no.
- jchw 2y agoI think principally, it's not actually that much worse. However, there are some aspects of Wayland that are much better and much worse for people who prefer to go their own way. With Wayland, the protocols are specified in machine-readable XML files, not unlike how XCB works, and typically a program called a "scanner" would read those XML files and perform code generation. So if you wanted to generate proper Wayland bindings, you'd need to write the scanner. The scanner is not terribly complicated. I did it in Go with around 750 SLOC, not counting the supporting code. It's not released, but here's just the code generation part, if you are curious. Last I used it, it could generate all of the Wayland protocols, and I was successfully using dozens of them from my own Go bindings. https://gist.github.com/jchv/adcb6de1c9dc3d0112dea704d753803c https://gist.github.com/jchv/adcb6de1c9dc3d0112dea704d753803... Of course, if you just want to implement Hello World, you don't need to use code generation, and the resulting amount of work to interface with X11 is ultimately similar to that of Wayland. But there are two huge caveats: - Right now, the EGL interface for Wayland requires that you pass libwayland wl_surface structures. That means to get on-screen hardware accelerated contexts in Wayland, you have to link to libwayland (maybe making compatible structures would work if you're into that kind of thing, but definitely no easy options.) - X11 has many server-side features that Wayland doesn't. Wayland's core protocols don't specify even window decorations or cursor shape, so a Wayland client has to implement drawing window decorations and loading cursor themes to properly support all Wayland compositors... even if they would prefer to use xdg-decoration and cursor-shape-v1. This is on top of things that no Wayland compositor has support for, like an equivalent to XRender or indirect rendering with OpenGL; those things just don't exist. So it's far from perfect. Though, it's also not like X11 was free of cruft or design issues, either. I'm pretty sure with X you also have to implement cursor themes yourself, by virtue of linking to XCURSOR. And while you can use XRender and other server side rendering features, which will be way more efficient for remote usage than simply opening a GL or Vulkan context, most software (GTK, Electron) doesn't do this anymore, and either ships buffers over shared memory or opens a direct hardware accelerated context. Personally, the problem I'd really like to see fixed is the EGL ABI one, but I'm pretty disillusioned by the bullshit in anything RedHat indirectly touches (e.g. Freedesktop.org), so even if there's a chance I could help, at this point, I'd rather spend my time working on other things.
- pantalaimon 2y agoC also has structs, there is no need to assemble data structures in byte arrays.
- pavlov 2y agoWith the caveat that structs are padded by default so that members are aligned on architecture-friendly boundaries. For example, if a struct contains a char a followed by an int b, typically b would be at offset 4, even though sizeof(a) is 1. To get tight packing, you need to explicitly tell the compiler to disable padding.
- pantalaimon 2y agoThat's why where is __attribute__((packed))
- anacrolix 2y agoFound the fresh grad
- hi-v-rocknroll 2y agoWhile under-researched statements aren't good, personal attacks don't help either. Prefer to educate instead. C structs have packing, alignment, and endianness gotchas that can be portably addressed with byte-level de/ser. Example: https://gist.github.com/cd089675a6088b0b8482c005a0e3897a https://gist.github.com/cd089675a6088b0b8482c005a0e3897a
- libcheet 2y agoFrom product C code perspective, this code is of course bad. But here idea was to show data manipulation closer to how it is shown in documentation. Also a lot requests have dynamic size and cannot be as easily packed and serialized to be sent over the "wire". So for example you could put pointer to string into struct, malloc required space, then assign pointer. After when you want to send data you would have to write serialization methods to put it in correct order. It is all fine and should be done when you build bulletproof system to manage X11. But here these techniques just draws too much attention away from X11.
- guenthert 2y ago> I was very surprised to learn that it is actually just a “regular” network protocol for two parties to communicate like HTTP, FTP, IMAP, SMPT and etc. With the important distinction that all those protocols very intentionally use human readable ASCII requests/responses. Of course, for performance sake, ease of debugability was sacrificed. Which increases the value of a standard library to hide the protocol.
- immibis 2y agoYou can run X apps in x11trace which translates commands and responses to ASCII. I assume Wireshark also has a parser.
- bla3 2y agoDoes anyone know of an example like this that shows a bitmap, without external libraries? As far as I know, you have to ask the server for the active bit depth and send bitmap data in a matching way, meaning every client needs to have code to convert to every pixel format under the sun. Maybe that's not true though, I'm not sure.
- jeffrallen 2y agoDude, you lost me at "just use an array and fill it in". Learn about struct packing and let the compiler fill in the "array" for you. Anyway, a good way to learn stuff. Hard mode, FTW!
- libcheet 2y agoYes. For production, struct are obvious choice. But here arrays were similar to how documentation specified data will be on the wire. So for educational purposes (to explain protocol) it seemed like a better choice. But I might be wrong and maybe structs would have been more approachable way to understand.
- hi-v-rocknroll 2y agoC structure packing isn't portable and doesn't account for host/network endianness. Buffer byte-oriented de/ser is the primary way of assembling data in C.