summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Prieels <anp@odoo.com>2019-11-18 10:28:59 +0000
committerAntoine Prieels <anp@odoo.com>2019-11-27 14:15:18 +0000
commitad846fcee5b1a548c2b2e1f9ac5cbf131d039042 (patch)
tree48bced3e0e845d4b063af9b8519924156bc79a69
parentc1c4404131bf2d2b913e6ef96106e1ef7754bcaa (diff)
[IMP] iot: Dual screen support for RPI4
We now support the RPI4 which has 2 micro-HDMI outputs, while the prvious driver only supported one display. We add support for a second display. Taskid: 2123511 X-original-commit: 5886c3a864c990fcd7b852baafab752e7da90494
-rwxr-xr-xaddons/hw_drivers/controllers/driver.py20
-rw-r--r--addons/hw_drivers/drivers/DisplayDriver.py23
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf60
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf4
-rwxr-xr-xaddons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh4
-rw-r--r--addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession5
6 files changed, 97 insertions, 19 deletions
diff --git a/addons/hw_drivers/controllers/driver.py b/addons/hw_drivers/controllers/driver.py
index d7982056190..fc61c8ed63e 100755
--- a/addons/hw_drivers/controllers/driver.py
+++ b/addons/hw_drivers/controllers/driver.py
@@ -6,7 +6,7 @@ from usb import core
from gatt import DeviceManager as Gatt_DeviceManager
import subprocess
import json
-from re import sub
+from re import sub, finditer
import urllib3
import os
import socket
@@ -302,14 +302,20 @@ class Manager(Thread):
def get_connected_displays(self):
display_devices = {}
- hdmi = subprocess.check_output(['tvservice', '-n']).decode('utf-8').replace('\n', '')
- if hdmi.find('=') != -1 and hdmi.split('=')[1] != "Unk-Composite dis":
- hdmi_serial = sub('[^a-zA-Z0-9 ]+', '', hdmi.split('=')[1]).replace(' ', '_')
+
+ displays = subprocess.check_output(['tvservice', '-l']).decode()
+ x_screen = 0
+ for match in finditer('Display Number (\d), type HDMI (\d)', displays):
+ display_id, hdmi_id = match.groups()
+ display_name = subprocess.check_output(['tvservice', '-nv', display_id]).decode().rstrip().split('=')[1]
+ display_identifier = sub('[^a-zA-Z0-9 ]+', '', display_name).replace(' ', '_') + "_" + str(hdmi_id)
iot_device = IoTDevice({
- 'identifier': hdmi_serial,
- 'name': hdmi.split('=')[1],
+ 'identifier': display_identifier,
+ 'name': display_name,
+ 'x_screen': str(x_screen),
}, 'display')
- display_devices[hdmi_serial] = iot_device
+ display_devices[display_identifier] = iot_device
+ x_screen += 1
if not len(display_devices):
# No display connected, create "fake" device to be accessed from another computer
diff --git a/addons/hw_drivers/drivers/DisplayDriver.py b/addons/hw_drivers/drivers/DisplayDriver.py
index 67d9f861708..167b485586d 100644
--- a/addons/hw_drivers/drivers/DisplayDriver.py
+++ b/addons/hw_drivers/drivers/DisplayDriver.py
@@ -35,8 +35,9 @@ class DisplayDriver(Driver):
self.event_data = threading.Event()
self.owner = False
self.rendered_html = ''
- self.load_url()
- self.call_xdotools('F11')
+ if self.device_identifier != 'distant_display':
+ self._x_screen = device.get('x_screen', '0')
+ self.load_url()
@property
def device_identifier(self):
@@ -68,20 +69,22 @@ class DisplayDriver(Driver):
event_manager.device_changed(self)
def run(self):
- while True:
+ while self.device_identifier != 'distant_display':
time.sleep(60)
if self.url != 'http://localhost:8069/point_of_sale/display/':
# Refresh the page every minute
self.call_xdotools('F5')
def update_url(self, url=None):
+ os.environ['DISPLAY'] = ":0." + self._x_screen
+ os.environ['XAUTHORITY'] = '/run/lightdm/pi/xauthority'
firefox_env = os.environ.copy()
- firefox_env['HOME'] = '/tmp'
- firefox_env['DISPLAY'] = ':0.0'
- firefox_env['XAUTHORITY'] = '/run/lightdm/pi/xauthority'
+ firefox_env['HOME'] = '/tmp/' + self._x_screen
self.url = url or 'http://localhost:8069/point_of_sale/display/'
- if self.device_identifier != 'distant_display':
- subprocess.Popen(['firefox', self.url], env=firefox_env)
+ new_window = subprocess.call(['xdotool', 'search', '--onlyvisible', '--screen', self._x_screen, '--class', 'Firefox'])
+ subprocess.Popen(['firefox', self.url], env=firefox_env)
+ if new_window:
+ self.call_xdotools('F11')
def load_url(self):
url = None
@@ -101,10 +104,10 @@ class DisplayDriver(Driver):
return self.update_url(url)
def call_xdotools(self, keystroke):
- os.environ['DISPLAY'] = ":0.0"
+ os.environ['DISPLAY'] = ":0." + self._x_screen
os.environ['XAUTHORITY'] = "/run/lightdm/pi/xauthority"
try:
- subprocess.call(['xdotool', 'search', '--sync', '--onlyvisible', '--class', 'Firefox', 'windowactivate', 'key', keystroke])
+ subprocess.call(['xdotool', 'search', '--sync', '--onlyvisible', '--screen', self._x_screen, '--class', 'Firefox', 'key', keystroke])
return "xdotool succeeded in stroking " + keystroke
except:
return "xdotool threw an error, maybe it is not installed on the IoTBox"
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf
new file mode 100644
index 00000000000..b525e583c30
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/X11/xorg.conf
@@ -0,0 +1,60 @@
+Section "Device"
+ Identifier "fbdev0"
+ Driver "fbdev"
+ Option "fbdev" "/dev/fb0"
+EndSection
+
+Section "Device"
+ Identifier "fbdev1"
+ Driver "fbdev"
+ Option "fbdev" "/dev/fb1"
+EndSection
+
+# Dummy device to use Xlib in KeyboardUSBDriver when no monitor is connected
+Section "Device"
+ Identifier "dummy"
+ Driver "dummy"
+EndSection
+
+Section "Monitor"
+ Identifier "Monitor0"
+EndSection
+
+Section "Monitor"
+ Identifier "Monitor1"
+EndSection
+
+Section "Monitor"
+ Identifier "DummyMonitor"
+EndSection
+
+Section "Screen"
+ Identifier "Screen0"
+ Monitor "Monitor0"
+ Device "fbdev0"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "Screen"
+ Identifier "Screen1"
+ Monitor "Monitor1"
+ Device "fbdev1"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "Screen"
+ Identifier "DummyScreen"
+ Monitor "DummyMonitor"
+ Device "dummy"
+ Subsection "Display"
+ EndSubSection
+EndSection
+
+Section "ServerLayout"
+ Identifier "Multihead"
+ Screen 0 "Screen0"
+ Screen 1 "Screen1" rightof "Screen0"
+ Screen 2 "DummyScreen" rightof "Screen1"
+EndSection
diff --git a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
index 977903c1c90..7b487b33ed8 100644
--- a/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
+++ b/addons/point_of_sale/tools/posbox/overwrite_after_init/etc/lightdm/lightdm.conf
@@ -3,6 +3,6 @@
user-authority-in-system-dir=true
[SeatDefaults]
-xserver-command=/usr/bin/X -s 0 dpms -nolisten tcp
+xserver-command=/usr/bin/X -s 0 -layout Multihead dpms -nolisten tcp
greeter-hide-users=false
-autologin-user=pi \ No newline at end of file
+autologin-user=pi
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
index 9f2e8438770..f795d4a8857 100755
--- a/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/etc/init_posbox_image.sh
@@ -50,6 +50,7 @@ PKGS_TO_INSTALL="
xdotool \
unclutter \
x11-utils \
+ xserver-xorg-video-dummy \
openbox \
rpi-update \
adduser \
@@ -159,6 +160,9 @@ systemctl disable hostapd.service
# cf: https://www.raspberrypi.org/documentation/configuration/raspi-config.md
echo "disable_overscan=1" >> /boot/config.txt
+# Separate framebuffers for both screens on RPI4
+sed -i '/dtoverlay/d' /boot/config.txt
+
# exclude /drivers folder from git info to be able to load specific drivers
echo "addons/hw_drivers/drivers/" > /home/pi/odoo/.git/info/exclude
diff --git a/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession
new file mode 100644
index 00000000000..ddbeae99211
--- /dev/null
+++ b/addons/point_of_sale/tools/posbox/overwrite_before_init/home/pi/.xsession
@@ -0,0 +1,5 @@
+# Start Openbox on the second display as described in
+# http://openbox.org/wiki/Help:FAQ > "How do I run Openbox across multiple X screens?"
+
+XAUTHORITY=/run/lightdm/pi/xauthority DISPLAY=:0.1 openbox &
+exec openbox-session