Allow Dual Screen Configurations for intel IGPs
improve xrandr_facts.py to match drm and xrandr outputs TODO: use drm.edid_firmware kernel boot parameter to load EDID files on startup
This commit is contained in:
parent
c0dc185952
commit
08ed05594e
1316
Manual.html
1316
Manual.html
File diff suppressed because it is too large
Load Diff
97
Manual.org
97
Manual.org
@ -35,6 +35,26 @@
|
||||
#+LATEX: \defaultfontfeatures{Ligatures=TeX}
|
||||
#+LATEX_HEADER: \usepackage{parskip}
|
||||
# #+LATEX_HEADER_EXTRA:
|
||||
#+BEGIN_SRC latex
|
||||
\newcommand*\justify{%
|
||||
\fontdimen2\font=0.4em% interword space
|
||||
\fontdimen3\font=0.2em% interword stretch
|
||||
\fontdimen4\font=0.1em% interword shrink
|
||||
\fontdimen7\font=0.1em% extra space
|
||||
\hyphenchar\font=`\-% allowing hyphenation
|
||||
}
|
||||
|
||||
\renewcommand{\texttt}[1]{%
|
||||
\begingroup
|
||||
\ttfamily
|
||||
\begingroup\lccode`~=`/\lowercase{\endgroup\def~}{/\discretionary{}{}{}}%
|
||||
\begingroup\lccode`~=`[\lowercase{\endgroup\def~}{[\discretionary{}{}{}}%
|
||||
\begingroup\lccode`~=`.\lowercase{\endgroup\def~}{.\discretionary{}{}{}}%
|
||||
\catcode`/=\active\catcode`[=\active\catcode`.=\active
|
||||
\justify\scantokens{#1\noexpand}%
|
||||
\endgroup
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+EXCLUDE_TAGS: noexport
|
||||
:END:
|
||||
@ -1832,7 +1852,7 @@ ctl.!default {
|
||||
The X-Server is started by using the two systemd units ~xlogin@.service~ and ~x@.service~ provided by the package *xlogin*. The former is enabled (and started) for the vdr user - which results (using the default settings for the user *vdr* with the uid *666*) in the activation of ~xlogin@vdr.service~ when reaching the graphical.target. To simplify starting and stopping the X-server and the desktop session a ~yavdr-xorg.service~ is provided by the package ~yavdr-xorg~, which depends on the two units mentioned before.
|
||||
|
||||
~x@vt7.service~ is started automatically as a dependency of ~xlogin@vdr.service~ and starts the X-server. ~xlogin@vdr.service~ also starts a systemd user session using ~user@666.service~.
|
||||
In order to use the keyboard layout configured during installation for the X-Server the script ~write-x11-keyboard-config~ reads the keyboard configuration from ~/etc/default/keyboard~ when starting ~x@.service~ and writes the file ~/etc/X11/xorg.conf.d/00-keyboard.conf~ (because systemd for Ubuntu (and Debian) has been patched not to create ~/etc/X11/xorg.conf.d/00-keyboard.conf~ according to the ~localectl~ settings).
|
||||
In order to use the keyboard layout configured during installation for the X-Server we are using a script ~write-x11-keyboard-config,~ which reads the keyboard configuration from ~/etc/default/keyboard~ when starting ~x@.service~ and writes the file ~/etc/X11/xorg.conf.d/00-keyboard.conf~ (because systemd for Ubuntu (and Debian) has been patched not to automatically create the configuration file ~/etc/X11/xorg.conf.d/00-keyboard.conf~ according to the ~localectl~ settings).
|
||||
|
||||
To prevent stopping the X-server when vdr is running, additional dependencies are set up - see the drop-in rules created in ~/etc/systemd/system/vdr.service.d/~.
|
||||
|
||||
@ -2336,6 +2356,12 @@ preferred_refreshrates:
|
||||
- '-w alsa-driver-broken'
|
||||
# - '-a pulse' # do we need this with our existing asound.conf?
|
||||
|
||||
- name: vdr-config | use vaapi for softhddevice if we got an intel IGP
|
||||
lineinfile:
|
||||
path: /etc/vdr/conf.avail/softhddevice.conf
|
||||
line: '-v va-pi'
|
||||
state: present if intel_detected else absent
|
||||
|
||||
- name: add a login shell for the user vdr
|
||||
user:
|
||||
name: '{{ vdr.user }}'
|
||||
@ -2704,21 +2730,41 @@ EndSection
|
||||
***** intel graphics xorg.conf snippet
|
||||
#+BEGIN_SRC jinja2 :tangle roles/yavdr-xorg/templates/20-intel.conf.j2
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
{% set output = xorg.primary.connector|replace("-", "") %}
|
||||
{% set primary_output = xorg.primary.connector|replace("-", "") %}
|
||||
{% if xorg.secondary is defined %}
|
||||
{% set secondary_output = xorg.secondary.connector|replace("-", "") %}
|
||||
{% endif %}
|
||||
|
||||
Section "Device"
|
||||
Identifier "Device0"
|
||||
Driver "intel"
|
||||
Option "TearFree" "true"
|
||||
|
||||
Option "UseEDID" "true"
|
||||
Option "CustomEDID" "{{ output }}:{{ xorg.primary.edid }}"
|
||||
{% if xorg.secondary is defined %}
|
||||
Option "ZaphodHeads" "{{ primary_output }}"
|
||||
Screen 0
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Device"
|
||||
Identifier "Device1"
|
||||
Driver "intel"
|
||||
Option "TearFree" "true"
|
||||
Option "ZaphodHeads" "{{ secondary_output }}"
|
||||
Screen 1
|
||||
EndSection
|
||||
|
||||
Section "ServerLayout"
|
||||
Identifier "Layout0"
|
||||
Screen 0 "Screen0" 0 0
|
||||
Screen 1 "Screen1" RightOf "Screen0"
|
||||
EndSection
|
||||
{% endif %}
|
||||
|
||||
Section "Screen"
|
||||
Identifier "Screen0"
|
||||
Device "Device0"
|
||||
Monitor "{{ output }}"
|
||||
Monitor "{{ primary_output }}"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
@ -2729,8 +2775,26 @@ Section "Screen"
|
||||
{% endif %}
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Screen"
|
||||
Identifier "Screen1"
|
||||
Device "Device1"
|
||||
Monitor "{{ secondary_output }}"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
{% if xorg.secondary.mode %}
|
||||
Modes "{{ xorg.secondary.mode }}"
|
||||
{% else %}
|
||||
Modes "1920x1080_50" "1920x1080_60" "1920x1080_24"
|
||||
{% endif %}
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
{% endif %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ output }}"
|
||||
Identifier "{{ primary_output }}"
|
||||
{% if xorg.primary.modelines %}
|
||||
{% for modeline in xorg.primary.modelines %}
|
||||
{{ modeline }}
|
||||
@ -2742,8 +2806,23 @@ Section "Monitor"
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ secondary_output }}"
|
||||
{% if xorg.secondary.modelines %}
|
||||
{% for modeline in xorg.secondary.modelines %}
|
||||
{{ modeline }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
Modeline "1920x1080_24" 74.230 1920 2560 2604 2752 1080 1084 1089 1125 +hsync +vsync
|
||||
Modeline "1920x1080_50" 148.500 1920 2448 2492 2640 1080 1084 1089 1125 +hsync +vsync
|
||||
Modeline "1920x1080_60" 148.500 1920 2008 2056 2200 1080 1084 1089 1125 +hsync +vsync
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% endif %}
|
||||
{% for connector, data in xrandr["Screen 0:"].iteritems() %}
|
||||
{% if not data.is_connected or connector != xorg.primary.connector %}
|
||||
{% if not data.is_connected or connector != xorg.primary.connector or (xorg.secondary is defined and connector != xorg.secondary.connector) %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ connector|replace("-","") }}"
|
||||
Option "Ignore" "true"
|
||||
|
@ -255,33 +255,39 @@ def collect_nvidia_data():
|
||||
raise ValueError
|
||||
|
||||
|
||||
Connector = namedtuple('Connector', "name xrandr_edid")
|
||||
|
||||
|
||||
def find_drm_connectors(primary):
|
||||
def find_drm_connectors(connections):
|
||||
"""
|
||||
takes a namedtuple Connector as the only argument.
|
||||
|
||||
returns a dict with the following schema:
|
||||
returns a dict with the following schema (secondary may be empty):
|
||||
{
|
||||
'primary': {
|
||||
'edid': 'edid.HDMI-1.bin',
|
||||
'drm_connector': 'HDMI-A-1',
|
||||
'xrandr_connector': 'HDMI-1',
|
||||
},
|
||||
'secondary': {
|
||||
'edid': 'edid.eDP-1.bin',
|
||||
'drm_connector': 'eDP-1',
|
||||
'xrandr_connector': 'eDP-1',
|
||||
}
|
||||
'ignored_outputs': ['HDMI-A-2', 'DP-1']
|
||||
}
|
||||
"""
|
||||
STATUS_GLOB = '/sys/class/drm/card0*/status'
|
||||
CONNECTOR_RE = re.compile('card0-(?P<connector>[^/]+)/status')
|
||||
|
||||
try:
|
||||
with open(primary.xrandr_edid, 'rb') as f:
|
||||
xrandr_edid_bytes = f.read()
|
||||
except IOError:
|
||||
xrandr_edid_bytes = b''
|
||||
def read_edid_bytes(edid_file):
|
||||
edid_bytes = b''
|
||||
try:
|
||||
with open(edid_file, 'rb') as f:
|
||||
edid_bytes = f.read()
|
||||
except IOError:
|
||||
pass
|
||||
return edid_bytes
|
||||
|
||||
drm = {'primary': {}, 'ignored_outputs': []}
|
||||
xrandr_edid_bytes = read_edid_bytes(connections.get('primary', {}).get('edid', ""))
|
||||
secondary_xrandr_edid_bytes = read_edid_bytes(connections.get('secondary', {}).get('edid', ''))
|
||||
|
||||
drm = {'primary': {}, 'secondary': {}, 'ignored_outputs': []}
|
||||
for status_p in glob(STATUS_GLOB):
|
||||
match = re.search(CONNECTOR_RE, status_p)
|
||||
if match:
|
||||
@ -295,19 +301,22 @@ def find_drm_connectors(primary):
|
||||
except IOError:
|
||||
continue
|
||||
|
||||
if connected and xrandr_edid_bytes:
|
||||
drm_edid = os.path.join(os.path.dirname(status_p), 'edid')
|
||||
try:
|
||||
with open(drm_edid, 'rb') as f:
|
||||
is_primary = f.read() == xrandr_edid_bytes
|
||||
except IOError:
|
||||
continue
|
||||
else:
|
||||
if is_primary:
|
||||
if connected:
|
||||
edid = read_edid_bytes(os.path.join(
|
||||
os.path.dirname(status_p), 'edid'))
|
||||
if edid:
|
||||
if edid == xrandr_edid_bytes:
|
||||
drm['primary'] = {
|
||||
'edid': os.path.basename(primary.xrandr_edid),
|
||||
'edid': os.path.basename(connections['primary'].get('edid', "")),
|
||||
'drm_connector': drm_connector,
|
||||
'xrandr_connector': primary.name,
|
||||
'xrandr_connector': connections['primary'].get('connector',''),
|
||||
}
|
||||
continue
|
||||
if secondary_xrandr_edid_bytes:
|
||||
drm['secondary'] = {
|
||||
'edid': os.path.basename(connections.get('secondary').get('edid', '')),
|
||||
'drm_connector': drm_connector,
|
||||
'xrandr_connector': connections['secondary'].get('connector',''),
|
||||
}
|
||||
continue
|
||||
drm['ignored_outputs'].append(drm_connector)
|
||||
@ -350,22 +359,24 @@ def output_data(data, write_edids=True):
|
||||
result[name]['bus_id'] = bus_id
|
||||
|
||||
connector_0, resolution_0, refreshrate_0 = max(modes, key=sort_mode)[:3]
|
||||
vendor_0, model_0, modelines_0 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_0))
|
||||
connector_0_edid = '/etc/X11/edid.{}.bin'.format(connector_0)
|
||||
vendor_0, model_0, modelines_0 = parse_edid_data(connector_0_edid)
|
||||
create_entry(result, 'primary', connector_0, resolution_0,
|
||||
refreshrate_0, vendor_0, model_0, modelines_0)
|
||||
|
||||
if write_edids:
|
||||
drm = find_drm_connectors(Connector(connector_0,
|
||||
'/etc/X11/edid.{}.bin'.format(connector_0)))
|
||||
|
||||
# check if additional monitors exist
|
||||
other_modes = [mode for mode in modes if mode[0] != connector_0]
|
||||
if other_modes:
|
||||
connector_1, resolution_1, refreshrate_1 = max(other_modes, key=sort_mode)[:3]
|
||||
vendor_1, model_1, modelines_1 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_1))
|
||||
connector_1_edid = '/etc/X11/edid.{}.bin'.format(connector_1)
|
||||
vendor_1, model_1, modelines_1 = parse_edid_data(connector_1_edid)
|
||||
create_entry(result, 'secondary', connector_1, resolution_1,
|
||||
refreshrate_1, vendor_1, model_1, modelines_1)
|
||||
|
||||
if write_edids:
|
||||
drm = find_drm_connectors(result)
|
||||
|
||||
|
||||
module.exit_json(changed=True if write_edids else False,
|
||||
ansible_facts={'xrandr': data, 'xorg': result, 'drm': drm})
|
||||
|
||||
|
@ -44,6 +44,12 @@
|
||||
- '-w alsa-driver-broken'
|
||||
# - '-a pulse' # do we need this with our existing asound.conf?
|
||||
|
||||
- name: vdr-config | use vaapi for softhddevice if we got an intel IGP
|
||||
lineinfile:
|
||||
path: /etc/vdr/conf.avail/softhddevice.conf
|
||||
line: '-v va-pi'
|
||||
state: present if intel_detected else absent
|
||||
|
||||
- name: add a login shell for the user vdr
|
||||
user:
|
||||
name: '{{ vdr.user }}'
|
||||
|
@ -1,19 +1,39 @@
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
{% set output = xorg.primary.connector|replace("-", "") %}
|
||||
{% set primary_output = xorg.primary.connector|replace("-", "") %}
|
||||
{% if xorg.secondary is defined %}
|
||||
{% set secondary_output = xorg.secondary.connector|replace("-", "") %}
|
||||
{% endif %}
|
||||
|
||||
Section "Device"
|
||||
Identifier "Device0"
|
||||
Driver "intel"
|
||||
Option "TearFree" "true"
|
||||
|
||||
Option "UseEDID" "true"
|
||||
Option "CustomEDID" "{{ output }}:{{ xorg.primary.edid }}"
|
||||
{% if xorg.secondary is defined %}
|
||||
Option "ZaphodHeads" "{{ primary_output }}"
|
||||
Screen 0
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Device"
|
||||
Identifier "Device1"
|
||||
Driver "intel"
|
||||
Option "TearFree" "true"
|
||||
Option "ZaphodHeads" "{{ secondary_output }}"
|
||||
Screen 1
|
||||
EndSection
|
||||
|
||||
Section "ServerLayout"
|
||||
Identifier "Layout0"
|
||||
Screen 0 "Screen0" 0 0
|
||||
Screen 1 "Screen1" RightOf "Screen0"
|
||||
EndSection
|
||||
{% endif %}
|
||||
|
||||
Section "Screen"
|
||||
Identifier "Screen0"
|
||||
Device "Device0"
|
||||
Monitor "{{ output }}"
|
||||
Monitor "{{ primary_output }}"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
@ -24,8 +44,26 @@ Section "Screen"
|
||||
{% endif %}
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Screen"
|
||||
Identifier "Screen1"
|
||||
Device "Device1"
|
||||
Monitor "{{ secondary_output }}"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
{% if xorg.secondary.mode %}
|
||||
Modes "{{ xorg.secondary.mode }}"
|
||||
{% else %}
|
||||
Modes "1920x1080_50" "1920x1080_60" "1920x1080_24"
|
||||
{% endif %}
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
{% endif %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ output }}"
|
||||
Identifier "{{ primary_output }}"
|
||||
{% if xorg.primary.modelines %}
|
||||
{% for modeline in xorg.primary.modelines %}
|
||||
{{ modeline }}
|
||||
@ -37,8 +75,23 @@ Section "Monitor"
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% if xorg.secondary is defined %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ secondary_output }}"
|
||||
{% if xorg.secondary.modelines %}
|
||||
{% for modeline in xorg.secondary.modelines %}
|
||||
{{ modeline }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
Modeline "1920x1080_24" 74.230 1920 2560 2604 2752 1080 1084 1089 1125 +hsync +vsync
|
||||
Modeline "1920x1080_50" 148.500 1920 2448 2492 2640 1080 1084 1089 1125 +hsync +vsync
|
||||
Modeline "1920x1080_60" 148.500 1920 2008 2056 2200 1080 1084 1089 1125 +hsync +vsync
|
||||
{% endif %}
|
||||
EndSection
|
||||
|
||||
{% endif %}
|
||||
{% for connector, data in xrandr["Screen 0:"].iteritems() %}
|
||||
{% if not data.is_connected or connector != xorg.primary.connector %}
|
||||
{% if not data.is_connected or connector != xorg.primary.connector or (xorg.secondary is defined and connector != xorg.secondary.connector) %}
|
||||
Section "Monitor"
|
||||
Identifier "{{ connector|replace("-","") }}"
|
||||
Option "Ignore" "true"
|
||||
|
Loading…
Reference in New Issue
Block a user