Question

I'm working on a small server program that takes data received from the network and performs various actions. One of these actions is to open a connection with the X server running on the system and simulate key presses. This is fine when my server is started from a terminal inside X, but I want my program to start as a system service with the system boots and then communicate with X when requested by the clients.

The basic problem I have is that a call to XOpenDisplay(NULL) in a process that was not started from inside X fails. As far as I understand, I can't get open an X display from outside of X so the best workaround I can think of is to write a separate program that is started when a user logs in to X that waits for a signal or message from the server and then performs the requested action. It is perfectly okay to assume that the server can send an error back to the client if this helper program isn't running or has failed for some reason.

So question: Is what I described above the best (albeit messy) solution, or is there a better way? Is there, in fact, a way to open an X display from outside of X? Thanks!

Was it helpful?

Solution

It is possible to connect to an X display from any process running on the machine - you need the DISPLAY variable set to indicate which X session you want to connect to, and may need the correct XAuthority token.

However, this would be considered the "messy" solution for your case, since you'd need to essentially guess the display number and work around the authorization issue. You'd also have to handle the case where the X server hasn't started yet when your daemon starts, or when the X server gets restarted while your daemon is running (the X client library isn't really designed to handle the case of the X server going away and coming back again).

The "clean" solution is actually the one you've suggested as a workaround - a client running within the X session that connects to your daemon over a UNIX domain socket or similar.

OTHER TIPS

Being "inside of X" is just a matter of having the DISPLAY environment variable set. You can do this from anywhere.

If the X server in question is being run for a different user, you may need to also deal with authentication tokens such as Xauthority tickets.

However -- for the use case you describe, I'd strongly recommend running your own X server process, independent of the system's actual display hardware. This could be Xvnc if you want to connect to inspect interactively, or a simple headless implementation, or Xvfb if you need no display buffer at all. This approach will also prevent your software from needing to restart when users log in and out, which would otherwise be the case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top