Debian – Communicate across X-desktop sessions on same machine

debianmulti-monitorremotex11

I've got a Raspberry Pi running Debian/Raspbian (thus X server) that I'd like to drive two screens with. I'm programming something that will have a public-facing screen and an operator-facing screen. To give an example of the things I'm trying to do, say the operator will have a GUI where he or she can press 'cat' and a fullscreen cat will appear on the other monitor.

The problem is that the Pi only has one HDMI output, making driving two monitors difficult unless you resort to SSH/remote desktop sessions with a second computer (eg a laptop). Now, I've done remote desktop on headless Pis before with very little difficulty. The issue that is brickwalling me right now is that when I remote desktop in, I get a completely independent second desktop than the one that's driving the primary monitor, ergo the monitor is inaccessible to me. How do I make it so that when I remote in, I get control over that monitor, but also screen area for a GUI that will only go on the remote computer? Also, how do I make it so when the program starts up, the public facing display goes fullscreen and the operator gui pops up on the other?

I'd like to keep as much as possible on the Pi so that the only requirement of the remote computer be that it can do remote desktop. In other words, I don't want to divide my software into remote and local executables.

Best Answer

You have essentially two problems:

  1. How do I start a program on a different display?
  2. Once that program is started, how do I talk to it?

(You did not specify your preferred language, so I assumed python.)

#1 is easy. Make a wrapper for your script, and call it startclient.sh

#!/bin/bash
DISPLAY=":0.0"
./client.py

(I'm assuming that the public-facing screen is the HDMI one.)

#2 is a little more tricky. I would make the public side listen for commands using Pyro.

from PyQt4 import QtGui
import Pyro4

daemon=Pyro4.Daemon()                 # make a Pyro daemon
uri=daemon.register(QtGui)

print "Ready. Object uri =", uri      # print the uri so we can use it in the client later
daemon.requestLoop()                  # start the event loop of the server to wait for calls

The operator side:

import Pyro4
import sys

uri=raw_input("What is the Pyro uri of the gui object? ").strip()
QtGui=Pyro4.Proxy(uri)

app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
w.resize(250, 150)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()

This requires PyQt4 and Pyro4. Note that I've not tested this code.

Related Question