How do I talk to an X server in C without a graphics library? [closed]
Asked Answered
T

2

7

If I wanted to write a C program to talk to an X server on Linux and produce the simplest possible visual result, e.g. setting a single pixel on the display, how would I do it?

I want to use as few libraries as possible, to understand it from the ground up, no matter how inefficient/messy the code is.

Update - by "without a library", I mean basically without any of the helper libraries that are available for X, and without a graphics toolkit.

Update - the answer is "through a unix socket", specifically /tmp/.X11-unix/X0 (on this machine at least, presumably for display 0). Actually drawing a pixel is too complicated to get into in an answer here I think.

Tepic answered 21/11, 2015 at 15:56 Comment(16)
Hardly. You'd at least need part of the C standard library and sockets. And including everything in a single file would be real "fun" debugging.Untaught
You can have a look at the Source Code section at XOrg.Doelling
Yeah, C standard library would be OK. So comm is done with sockets? Is it a unix domain socket? How is it identified - does the socket have a special name or something?Tepic
Please do some research on your own. SO is not a tutorial forum, but a Q&A site. Xorg is open source and everything you need can be found by little search effort.Untaught
@GusHogg-Blake The X server is identified by the DISPLAY environment variable. For how to find the corresponding socket, RTFM.Riviera
I actually have done quite a bit of research on this, read a lot of the relevant docs, although I realise this isn't clear from the question. Everything I've read is too high-level, e.g. examples on how to use graphics toolkits etc, or high level descriptions of the protocol without explaining the mechanics of communication. If I were writing a window manager, for example, what would my init code look like?Tepic
@FUZxxl which manual?Tepic
Are you specifically interested in X? If not, there are other easier and more direct ways of putting pixels on a screen, both with and without Linux's help.Spice
X11 is getting old. Consider WaylandCarbonate
Why do you ask? What is your real motivation?Carbonate
@BasileStarynkevitch I believe OP is trying to understand how all of this works.Riviera
OK so it turns out there is a socket file - /tmp/.X11-unix/X0. It was right there in the manual as you said @FUZxxl. I would have expected it to be higher up, or at least some mention of it to appear in the general intro, as it's the first step for any code that wants to talk to X, but there you go. And you're right - I want to understand specifically how everything fits together, in the sense of what and where are the all the actual connections between the parts (of a linux desktop environment), and thought a practical exercise like this would make it clearer. Thanks for the help :)Tepic
@GusHogg-Blake Normally you wouldn't ever talk to that socket directly, it's an implementation detail most programmers don't care about.Riviera
haha it's about all I care about! I have to know the details.Tepic
Why do you ask, and how many years can you dedicate to understand the details.....?Carbonate
This question is not too broad at all; it's perfectly valid and it shouldn't have been closed. I explain a little bit of how to talk to the X server in this answer, using sockets and assembling packets of bytes yourself, by hand. It's based off code from someone else, though I can't find the link anymore. I'm currently using those routines to draw pixels directly to the screen, not just one, but 2073600 of them (at 250 fps, on my platform).Conte
R
13

If you want to use no library at all, you need to do these steps:

  • Learn assembly for the platform you target
  • Learn how to make a binary without using the libc on your target. This likely involves writing assembly for setting up the initial stack frame
  • Learn how to do system calls without using the libc on your target. This likely involves assembly.
  • Learn and understand network programming and how the POSIX socket API works
  • Learn how to open network connections without using the libc on your target
  • Learn and understand the X11 protocol
  • Implement the subset of the X11 protocol you need
  • Open a network connection to the X server
  • Tell the X server to make a window
  • Negotiate a colour space with the X server
  • Tell the X server to colour a single pixel in the window

If you want to use the libc and the libsocket, then only the following steps (roughly) remain:

  • Learn and understand network programming and how the POSIX socket API works
  • Learn and understand the X11 protocol
  • Implement the subset of the X11 protocol you need
  • Open a network connection to the X server
  • Tell the X server to make a window
  • Negotiate a colour space with the X server
  • Tell the X server to colour a single pixel in the window
Riviera answered 21/11, 2015 at 16:3 Comment(5)
@Olaf I voted to close it as too broad, but I can still write an answer. OP specifically asked about X and “messy details,” so here they are.Riviera
Problem is you encourage such questions by providing an answer. IIRC, there is a meta about this somewhere.Untaught
Ah, it's a bit more complicated than I thought. I had a quick look at the X manual you linked. It still doesn't answer what I suppose is my main question - what "address" do you use for the socket? The most promising information seemed to be in the section on connection setup, but it still just generalised that "any reliable byte stream can be used". Surely this has to be stated more specifically somewhere? There are lots of possible "byte streams" on a linux system at any given time (file descriptors, network sockets, etc).Tepic
@GusHogg-Blake This is something you can find in man Xserver or by asking Google (I typed “where can I find the X server socket”). You need to seriously ramp up your Google foo to complete this task you assigned yourself.Riviera
I posted an answer giving explicit C code that does precisely this (the second part, using libc and no assembly). Fear not, it's not nearly as difficult as people would have you believe!Conte
C
4

X11 is getting old. Consider Wayland and read its FAQ. And there are several X related protocols, read about X11 Core protocol, and also conventions like EWMH.

You'll need to read several thousands of pages. Just understanding the protocols would require several months. OReilly published (in the previous century) a serie of 8 to 10 books related to X11.

You might use a low level X11 library, like XCB -or the older Xlib -, it is used by graphical toolkits like Qt or GTK (or FOX, etc..), which are both free software toolkits so you could study their source code (and Xlib & XCB are also free software).

Notice that today's GUI are usually not displaying fonts using X11 text display requests. They often use Xft (and the font is on the client side, not in the Xorg server). Actually, I heard that most of the graphics rendering practically happens on the client side, and that today most X11 requests are just sending pixmaps to the server (so X11 core protocol requests for drawing lines or circles are barely used today). More generally, the trend in major X11 based toolkits like Qt or GTK is to avoid using the server-side drawing abilities of X11 (e.g. Xlib's XDrawLine or XDrawText), because the toolkit is drawing a pixmap image client side and sending it to the server.

You could consider using a low-level library like libSDL

The important thing to understand is that X11 applications are event driven and based upon an event loop (generally provided by the toolkit) above some multiplexing syscall like poll(2). They are asked by X11 expose or damage events to redraw some screen area (and, of course, keyboard, mouse, and the Xorg server itself are sending events).

See also this answer to a similar question.

Carbonate answered 21/11, 2015 at 16:24 Comment(1)
X is getting old It was getting old 40 years ago. I'd say we're past getting 😅😅Exterritorial

© 2022 - 2024 — McMap. All rights reserved.