diff --git a/Manual.html b/Manual.html index 8aa7e8c..cc60a27 100644 --- a/Manual.html +++ b/Manual.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Ansible Playbooks for yaVDR 0.7 @@ -239,213 +239,213 @@ for the JavaScript code in this tag.

Inhaltsverzeichnis

- -
-

1 User Stories

+
+

1 User Stories

-
-

1.1 yavdr-full

+
+

1.1 yavdr-full

A User wants to install yaVDR without customization and relies on full automation. @@ -478,27 +478,27 @@ Several roles are used to tie everything together:

-
-

1.1.1 Using vdr, pulseaudio and xorg together

+
+

1.1.1 Using vdr, pulseaudio and xorg together

-
-

2 Notes

+
+

2 Notes

:export nil

-
-

2.1 TODO optimize and document data structure for xorg parsing script

+
+

2.1 TODO optimize and document data structure for xorg parsing script

-
-

2.2 TODO xorg.conf templates for intel, nvidia, noveau and radeon drivers

+
+

2.2 TODO xorg.conf templates for intel, nvidia, noveau and radeon drivers

-
-

2.2.1 STARTED BusID für (nvidia) Grafikkarten aus lspci auslesen

+
+

2.2.1 STARTED BusID für (nvidia) Grafikkarten aus lspci auslesen

Format: „%d:%d:%d“ (lspci liefert es als „%04x:%02x:%02x.%x“, domain, bus, device, function) @@ -510,10 +510,10 @@ Format: „%d:%d:%d“ (lspci liefert es als „%04x:%02x:%02x.%x&ld

-
-

2.2.2 NVIDIA-Dokumentation zur BusID:

+
+

2.2.2 NVIDIA-Dokumentation zur BusID:

-
  1. What is the format of a PCI Bus ID?
    +
    1. What is the format of a PCI Bus ID?

      Different tools have different formats for the PCI Bus ID of a PCI device.

      @@ -536,51 +536,51 @@ The lspci(8) utility, in contrast, reports the PCI BusID of a PCI device in the in printf(3) syntax. The „Bus Location“ reported in the /proc/driver/nvidia/gpus/0..N/information files matches the lspci format.

    2. -
    3. Parsen der /proc/driver/nvidia/gpus/*/information Dateien
      +
    4. Parsen der /proc/driver/nvidia/gpus/*/information Dateien
      -
      # read the BusID for nvidia cards and the model name
      -# from the /proc/driver/nvidia/gpus/*/information file(s)
      -from __future__ import print_function
      -import glob
      -import re
      +
      # read the BusID for nvidia cards and the model name
      +# from the /proc/driver/nvidia/gpus/*/information file(s)
      +from __future__ import print_function
      +import glob
      +import re
       
      -BusID_RE = re.compile((
      -    '(?P<domain>[0-9a-fA-F]+)'
      -    ':'
      -    '(?P<bus>[0-9a-fA-F]+)'
      -    ':'
      -    '(?P<device>[0-9a-fA-F]+)'
      -    '\.'
      -    '(?P<function>[0-9a-fA-F]+)'
      +BusID_RE = re.compile((
      +    '(?P<domain>[0-9a-fA-F]+)'
      +    ':'
      +    '(?P<bus>[0-9a-fA-F]+)'
      +    ':'
      +    '(?P<device>[0-9a-fA-F]+)'
      +    '\.'
      +    '(?P<function>[0-9a-fA-F]+)'
       ))
      -Model_RE = re.compile('Model:\s+(.*)')
      +Model_RE = re.compile('Model:\s+(.*)')
       
      -def get_BusIDs():
      -    for gpu_info in glob.glob('/proc/driver/nvidia/gpus/*/information'):
      -        with open(gpu_info) as f:
      -            data = f.read()
      -        match = BusID_RE.search(data)
      -        if match:
      -            BusID = "{:d}@{:d}:{:d}:{:d}".format(*(int(n, 16) for n in match.groups()))
      -            yield BusID, Model_RE.match(data).groups()[0]
      -if __name__ == '__main__':
      -    BusIDs = [BusID for BusID in get_BusIDs()]
      -    print(BusIDs)
      +def get_BusIDs():
      +    for gpu_info in glob.glob('/proc/driver/nvidia/gpus/*/information'):
      +        with open(gpu_info) as f:
      +            data = f.read()
      +        match = BusID_RE.search(data)
      +        if match:
      +            BusID = "{:d}@{:d}:{:d}:{:d}".format(*(int(n, 16) for n in match.groups()))
      +            yield BusID, Model_RE.match(data).groups()[0]
      +if __name__ == '__main__':
      +    BusIDs = [BusID for BusID in get_BusIDs()]
      +    print(BusIDs)
       
-
-

2.3 TODO plan for customization of xorg settings by the user

+
+

2.3 TODO plan for customization of xorg settings by the user

either directly or using a configuration wizard or a web frontend

-
-

2.4 SOMEDAY select best frontend based on GPU

+
+

2.4 SOMEDAY select best frontend based on GPU

intel
softhddevice-vpp
@@ -591,16 +591,16 @@ either directly or using a configuration wizard or a web frontend
-
-

3 Introduction

+
+

3 Introduction

One of the major problems we faced with customized Ubuntu ISO files as installation media for prior yaVDR versions has been the limited hardware support and the time consuming process to create and update them. An interesting alternative to this approach is to enable the user to choose the installation medium himself so point releases, kernel versions and additional drivers can be chosen deliberately. After the basic setup is complete (and a working internet connection is available), a fully customizable install script completes the yaVDR installation.

-
-

4 Installing and configuring yaVDR with Ansible

+
+

4 Installing and configuring yaVDR with Ansible

This is an experimental feature which allows to set up a yaVDR installation based on a normal Ubuntu Server 16.04.x installation using Ansible. @@ -616,96 +616,99 @@ To use this playbook on a Ubuntu Server Installation you need to run the followi

sudo apt-get install git
 git clone https://github.com/yavdr/yavdr-ansible.git
-cd yavdr-ansible
+cd yavdr-ansible
 sudo ./install-yavdr.sh
 
-
-

4.1 Install script for local usage

+
+

4.1 Install script for local usage

-
if (( $EUID != 0 )); then
-    echo "This script must be run using sudo or as root"
-    exit
-fi
+
if (( $EUID != 0 )); then
+    echo "This script must be run using sudo or as root"
+    exit
+fi
 
 apt-get -y install software-properties-common
-# Add repository for ansible
+# Add repository for ansible
 add-apt-repository -y ppa:ansible/ansible
-# update packages
+# update packages
 apt-get update
-# install required packages
+# install required packages
 apt-get -y install ansible
 
-# TODO: run ansible on local host
-ansible-playbook yavdr07.yml -b -i 'localhost_inventory' --connection=local
+# TODO: run ansible on local host
+ansible-playbook yavdr07.yml -b -i 'localhost_inventory' --connection=local --tags=install
 
-
-

5 Playbooks

+
+

5 Playbooks

-
-

5.1 yavdr07.yml

+
+

5.1 yavdr07.yml

The yavdr07.yml playbook sets up a fully-featured yaVDR installation:

-
---
-# file: yavdr07.yml
-# this playbook sets up a complete yaVDR 0.7 installation
+
---
+# file: yavdr07.yml
+# this playbook sets up a complete yaVDR 0.7 installation
 
-- name: set up yaVDR
-  hosts: all
-  become: true
-  roles:
-     - yavdr-common               # install and configure the basic system
-     - autoinstall-ubuntu-drivers # use ubuntu-drivers to install proprietary dirvers
-                                  # (e.g. nvidia, virtualbox)
-     - vdr                        # install vdr and related packages
-     - yavdr-network              # enable network client capabilities
-     - samba-install              # install samba server
-     - samba-config               # configure samba server
-     - nfs-server                 # install nfs server
-     - pulseaudio                 # install pulseaudio
-     - yavdr-xorg                 # graphical session
-     - yavdr-remote               # remote configuration files, services and scripts
-     - autoinstall-satip          # install vdr-plugin-satip if a Sat>IP server has been found
-     - autoinstall-targavfd       # install vdr-plugin-targavfd if display is connected
-     - autoinstall-imonlcd        # install vdr-plugin-imonlcd if a matchind display is connected
-     - autoinstall-pvr350         # install vdr-plugin-pvr350 if a matching card is detected
-     - autoinstall-dvbsddevice    # install vdr-plugin-dvbsddevice if a matching card is detected
+- name: set up yaVDR
+  hosts: all
+  become: true
+  roles:
+     - yavdr-common               # install and configure the basic system
+     - autoinstall-ubuntu-drivers # use ubuntu-drivers to install proprietary dirvers
+                                  # (e.g. nvidia, virtualbox)
+     - vdr                        # install vdr and related packages
+     - yavdr-network              # enable network client capabilities
+     - samba-install              # install samba server
+     - samba-config               # configure samba server
+     - nfs-server                 # install nfs server
+     - pulseaudio                 # install pulseaudio
+     - yavdr-xorg                 # graphical session
+     - yavdr-remote               # remote configuration files, services and scripts
+     - autoinstall-satip          # install vdr-plugin-satip if a Sat>IP server has been found
+     - autoinstall-targavfd       # install vdr-plugin-targavfd if display is connected
+     - autoinstall-imonlcd        # install vdr-plugin-imonlcd if a matchind display is connected
+     - autoinstall-pvr350         # install vdr-plugin-pgvr350 if a matching card is detected
+     - autoinstall-hauppauge-pvr  # install vdr-plugin-pvrinput if a matching card is found
+     - autoinstall-dvbsddevice    # install vdr-plugin-dvbsddevice if a matching card is detected
      - kodi
-     - dvd                        # set up packages and a udev rule to allow kodi and other players
-                                  # to play and eject optical media
-     - grub-config                # configure grub
+     - dvd                        # set up packages and a udev rule to allow kodi and other players
+                                  # to play and eject optical media
+     - grub-config                # configure grub
+  tags:
+     - always
 
-  handlers:
-    - include: handlers/main.yml
+  handlers:
+    - include: handlers/main.yml
 
-
-

5.2 yavdr07-headless.yml

+
+

5.2 yavdr07-headless.yml

For a headless server installation yavdr07-headless.yml is a good choice

-
---
-# file: yavdr07-headless.yml
-# this playbook set up a headless yaVDR 0.7 installation
+
---
+# file: yavdr07-headless.yml
+# this playbook set up a headless yaVDR 0.7 installation
 
-- name: set up a headless yaVDR server
-  hosts: all
-  become: true
-  roles:
+- name: set up a headless yaVDR server
+  hosts: all
+  become: true
+  roles:
     - yavdr-common
     - vdr
     - yavdr-network
@@ -714,133 +717,136 @@ For a headless server installation yavdr07-headless.yml is a good c
     - nfs-server
     - grub-config
     - autoinstall-satip
-  handlers:
-    - include: handlers/main.yml
+  tags:
+    - always
+  handlers:
+    - include: handlers/main.yml
 
-
-

6 Hosts

+
+

6 Hosts

This playbook can either be used to run the installation on the localhost or any other PC in the network that can be accessed via ssh. Simply add the host names or IP addresses to the hosts file in the respective section:

-
[localhost]
-localhost connection=local
+
[localhost]
+localhost connection=local
 
 
-
-

7 Group Variables

+
+

7 Group Variables

-
-

7.1 default text for templates used by ansible

+
+

7.1 default text for templates used by ansible

-
---
-# file: group_vars/all
+
---
+# file: group_vars/all
 
-# this is the standard text to put in templates
-ansible_managed_file: "*** YAVDR: ANSIBLE MANAGED FILE ***"
+# this is the standard text to put in templates
+ansible_managed_file: "*** YAVDR: ANSIBLE MANAGED FILE ***"
 
-
-

7.2 PPAs

+
+

7.2 PPAs

-
branch: unstable
-ppa_owner: 'ppa:yavdr'
-# a list of all package repositories to be added to the installation
-repositories:
-  - '{{ ppa_owner }}/main'
-  - '{{ ppa_owner }}/unstable-main'
-  - '{{ ppa_owner }}/{{branch}}-vdr'
-  - '{{ ppa_owner }}/{{branch}}-yavdr'
-  - '{{ ppa_owner }}/{{branch}}-kodi'
+
branch: unstable
+ppa_owner: 'ppa:yavdr'
+# add the following PPAs
+repositories:
+  - '{{ ppa_owner }}/main'
+  - '{{ ppa_owner }}/unstable-main'
+  - '{{ ppa_owner }}/{{branch}}-vdr'
+  - '{{ ppa_owner }}/{{branch}}-yavdr'
+  - '{{ ppa_owner }}/{{branch}}-kodi'
 
-
-

7.3 VDR user, directories, special configuration and plugins

+
+

7.3 VDR user, directories, special configuration and plugins

-
# properties of the user vdr and vdr-related options
-vdr:
-  user: vdr
-  group: vdr
-  uid: 666
-  gid: 666
-  home: /var/lib/vdr
-  confdir: /var/lib/vdr
-  recdir: /srv/vdr/video
-  hide_first_recording_level: false
-  safe_dirnames: true  # escape characters (useful for windows clients and FAT/NTFS file systems)
-  override_vdr_charset: false
+
# properties of the user vdr and vdr-related options
+vdr:
+  user: vdr
+  group: vdr
+  uid: 666
+  gid: 666
+  home: /var/lib/vdr
+  confdir: /var/lib/vdr
+  recdir: /srv/vdr/video
+  hide_first_recording_level: false
+  safe_dirnames: true  # escape characters (useful for windows clients and FAT/NTFS file systems)
+  override_vdr_charset: false
 
-# add the vdr plugins you want to install
-vdr_plugins:
+# add the vdr plugins you want to install
+vdr_plugins:
   - vdr-plugin-devstatus
   - vdr-plugin-markad
   - vdr-plugin-restfulapi
-  - vdr-plugin-softhddevice
+  - vdr-plugin-softhddevice-vpp
 
 
-
-

7.4 Media directories

+
+

7.4 Media directories

-
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
-media_dirs:
-  audio: /srv/audio
-  video: /srv/audio
-  pictures: /srv/picture
-  files: /srv/files
-  backups: /srv/backups
-  recordings: '{{ vdr.recdir }}'
+
# dictionary of directories for (shared) files. Automatically exported via NFS and Samba if those roles are enabled
+media_dirs:
+  audio: /srv/audio
+  video: /srv/audio
+  pictures: /srv/picture
+  files: /srv/files
+  backups: /srv/backups
+  recordings: '{{ vdr.recdir }}'
 
-
-

7.5 NFS

+
+

7.5 NFS

-
nfs:
-  insecure: false  # set to true for OS X clients or if you plan to use libnfs as unprivileged user (e.g. KODI)
+
nfs:
+  insecure: false  # set to true for OS X clients or if you plan to use libnfs as unprivileged user (e.g. KODI)
 
-
-

7.6 Samba

+
+

7.6 Samba

-
samba:
-  workgroup: YAVDR
-  windows_compatible: '{{ vdr.safe_dirnames }}'  # set to true to disable unix extensions, enable follow symlinks and wide links
+
samba:
+  workgroup: YAVDR
+  windows_compatible: '{{ vdr.safe_dirnames }}'  # set to true to disable unix extensions, enable follow symlinks and wide links
 
-
-

7.7 Additional packages

+
+

7.7 Additional packages

-
# additional packages you want to install
-extra_packages:
+
# additional packages you want to install
+extra_packages:
   - vim
+  - htop
   - tree
   - w-scan
   - bpython
@@ -849,72 +855,73 @@ This playbook can either be used to run the installation on the localhost or any
 
-
-

7.8 System pre-configuration

+
+

7.8 System pre-configuration

-
#system:
-#  shutdown: poweroff
-grub:
-  timeout: 0
-  boot_options: quiet nosplash
+
frontend: vdr
+#system:
+#  shutdown: poweroff
+grub:
+  timeout: 0
+  boot_options: quiet nosplash
 
-
-

8 Roles

+
+

8 Roles

-
-

8.1 install-dependencies

+
+

8.1 install-dependencies

-
-

8.1.1 tasks

+
+

8.1.1 tasks

-
  1. main.yml
    +
    1. main.yml
      -
      ---
      +
      ---
       
      -- name: apt | install packages
      -  apt:
      -    name: '{{ item }}'
      -    state: present
      -    install_recommends: no
      -  with_items:
      -    '{{ packages }}'
      +- name: apt | install packages
      +  apt:
      +    name: '{{ item }}'
      +    state: present
      +    install_recommends: no
      +  with_items:
      +    '{{ packages }}'
       
-
-

8.2 nvidia-381 drivers

+
+

8.2 nvidia-381 drivers

install nvidia-381 from ppa:graphics-drivers/ppa

-
-

8.2.1 tasks

+
+

8.2.1 tasks

-
  1. main.yml
    +
    1. main.yml
      -
      ---
      +
      ---
       
      -- name: add ppa:graphics-drivers/ppa
      -  apt_repository:
      -      repo: 'ppa:graphics-drivers/ppa'
      -      state: present
      -      update_cache: yes
      +- name: add ppa:graphics-drivers/ppa
      +  apt_repository:
      +      repo: 'ppa:graphics-drivers/ppa'
      +      state: present
      +      update_cache: yes
       
      -- name: install nvidia-381 and other required packages
      -  apt:
      -    name: '{{ item }}'
      -    state: present
      -    install_recommends: no
      -  with_items:
      +- name: install nvidia-381 and other required packages
      +  apt:
      +    name: '{{ item }}'
      +    state: present
      +    install_recommends: no
      +  with_items:
           - nvidia-381
           - nvidia-settings
       
      @@ -922,66 +929,65 @@ install nvidia-381 from ppa:graphics-drivers/ppa
-
-

8.3 yavdr-common

+
+

8.3 yavdr-common

This role is used to set up a basic yaVDR installation. It creates the directories, installs the vdr and other useful packages.

-
-

8.3.1 default variables

+
+

8.3.1 default variables

This section is for reference only, please use the files in global_vars for customizations.

-
---
-
-# file: roles/yavdr-common/defaults/main.yml
+
---
+# file: roles/yavdr-common/defaults/main.yml
 
-
  1. Repositories
    +
    1. Repositories

      You can set a list of package repositories which provide the necessary packages. Feel free to use own PPAs if you need special customization to the VDR and it’s plugins.

      -
      branch: unstable
      -repositories:
      -  - 'ppa:yavdr/main'
      -  - 'ppa:yavdr/unstable-main'
      -  - 'ppa:yavdr/{{branch}}-vdr'
      -  - 'ppa:yavdr/{{branch}}-kodi'
      -  - 'ppa:yavdr/{{branch}}-yavdr'
      +
      branch: unstable
      +repositories:
      +  - 'ppa:yavdr/main'
      +  - 'ppa:yavdr/unstable-main'
      +  - 'ppa:yavdr/{{branch}}-vdr'
      +  - 'ppa:yavdr/{{branch}}-kodi'
      +  - 'ppa:yavdr/{{branch}}-yavdr'
       
    2. -
    3. Drivers
      +
    4. Drivers

      Automatically installed drivers can be very useful, but if you know you need a certain driver, you can simply set it’s value to true. If you don’t want a driver to be installed, set it’s value to false.

      -
      drivers:
      -  sundtek: auto
      -  ddvb-dkms: auto
      +
      drivers:
      +  sundtek: auto
      +  ddvb-dkms: auto
       
    5. -
    6. Additional Packages
      +
    7. Additional Packages

      Add additional packages you would like to have on your installation to this list

      -
        extra_packages:
      -      - vim
      -      - tree
      -      - w-scan
      +
      extra_packages:
      +  - vim
      +  - tree
      +  - w-scan
       
    8. -
    9. VDR
      +
    10. VDR

      This section allows you to set the recording directory, the user and group that runs the vdr and it’s home directory.

      @@ -997,93 +1003,93 @@ This section allows you to set the recording directory, the user and group that
      override_vdr_charset
      workaround for channels with weird EPG encodings, e.g. Sky
      -
      vdr:
      -    user: vdr
      -    group: vdr
      -    uid: 666
      -    gid: 666
      -    home: /var/lib/vdr
      -    recdir: /srv/vdr/video
      -    hide_first_recording_level: false
      -    safe_dirnames: true
      -    override_vdr_charset: false
      +
      vdr:
      +    user: vdr
      +    group: vdr
      +    uid: 666
      +    gid: 666
      +    home: /var/lib/vdr
      +    recdir: /srv/vdr/video
      +    hide_first_recording_level: false
      +    safe_dirnames: true
      +    override_vdr_charset: false
       
    -
    -

    8.3.2 tasks

    +
    +

    8.3.2 tasks

    yavdr-common executes the following tasks:

    -
    1. main.yml
      1. Disable default installation of recommended packages
        +
        1. main.yml
          1. Disable default installation of recommended packages

            This task prevents apt to automatically install all recommended dependencies for packages:

            -
            ---
            +
            ---
             
            -- name: apt | prevent automatic installation of recommended packages
            -  template:
            -    src: templates/90-norecommends.j2
            -    dest: /etc/apt/apt.conf.d/90norecommends
            +- name: apt | prevent automatic installation of recommended packages
            +  template:
            +    src: templates/90-norecommends.j2
            +    dest: /etc/apt/apt.conf.d/90norecommends
             
             
          2. -
          3. Use bash instead of dash
            +
          4. Use bash instead of dash
            -
            - name: use bash instead of dash
            -  shell: |
            -    echo "set dash/sh false" | debconf-communicate
            -    dpkg-reconfigure -f noninteractive dash
            +
            - name: use bash instead of dash
            +  shell: |
            +    echo "set dash/sh false" | debconf-communicate
            +    dpkg-reconfigure -f noninteractive dash
             
          5. -
          6. create user vdr
          7. -
          8. Disable release-upgrade notifications
            +
          9. create user vdr
          10. +
          11. Disable release-upgrade notifications
            -
            - name: disable release-upgrade notifications
            -  lineinfile:
            -    dest: /etc/update-manager/release-upgrades
            -    backrefs: yes
            -    state: present
            -    regexp: '^(Prompt=).*$'
            -    line: '\1never'
            +
            - name: disable release-upgrade notifications
            +  lineinfile:
            +    dest: /etc/update-manager/release-upgrades
            +    backrefs: yes
            +    state: present
            +    regexp: '^(Prompt=).*$'
            +    line: '\1never'
             
          12. -
          13. Set up package repositories
            +
          14. Set up package repositories
            -
            - name: add yaVDR PPAs
            -  apt_repository:
            -      repo: '{{ item }}'
            -      state: present
            -      update_cache: yes
            -  with_items: '{{ repositories }}'
            +
            - name: add PPAs
            +  apt_repository:
            +      repo: '{{ item }}'
            +      state: present
            +      update_cache: yes
            +  with_items: '{{ repositories }}'
             
            -- name: upgrade existing packages
            -  apt:
            -      upgrade: dist
            -      update_cache: yes
            +- name: run apt-get dist-upgrade
            +  apt:
            +      upgrade: dist
            +      update_cache: yes
             
          15. -
          16. Install essential packages
            +
          17. Install essential packages
            -
            - name: apt | install basic packages
            -  apt:
            -    name: '{{ item }}'
            -    state: present
            -    install_recommends: no
            -  with_items:
            +
            - name: apt | install basic packages
            +  apt:
            +    name: '{{ item }}'
            +    state: present
            +    install_recommends: no
            +  with_items:
                 - anacron
                 - at
                 - bash-completion
            -    #- biosdevname  # caution: may change device names after a minimal installation!
            +    #- biosdevname  # caution: may change device names after a minimal installation!
                 - debconf-utils
                 - linux-firmware
                 - psmisc
            @@ -1100,179 +1106,176 @@ This task prevents apt to automatically install all recommended dependencies for
             
          18. -
          19. Install additional packages (user defined)
            +
          20. Install additional packages (user defined)
            -
            - name: apt | install extra packages
            -  apt:
            -    name: '{{ item }}'
            -    state: present
            -    install_recommends: no
            -  with_items:
            -      '{{ extra_packages }}'
            +
            - name: apt | install extra packages
            +  apt:
            +    name: '{{ item }}'
            +    state: present
            +    install_recommends: no
            +  with_items:
            +      '{{ extra_packages }}'
             
          21. -
          22. Gather facts with custom modules
            +
          23. Gather facts with custom modules
            -
            - name: get information about usb and pci hardware and loaded kernel modules
            -  hardware_facts:
            -    usb: True
            -    pci: True
            -    modules: True
            -    gpus: True
            -- debug:
            -    var: usb
            -    verbosity: 1
            -- debug:
            -    var: pci
            -    verbosity: 1
            -- debug:
            -    var: modules
            -    verbosity: 1
            -- debug:
            -    var: gpus
            -    verbosity: 1
            +
            - name: get information about usb and pci hardware and loaded kernel modules
            +  hardware_facts:
            +    usb: True
            +    pci: True
            +    modules: True
            +    gpus: True
            +    
            +- debug:
            +    var: '{{ item }}'
            +    verbosity: 1
            +  with_items:
            +    - usb
            +    - pci
            +    - gpus
            +    - modules
             
          24. -
          25. create media directories
        +
      2. create media directories
    -
    -

    8.3.3 templates

    +
    +

    8.3.3 templates

    -
    {{ ansible_managed_file | comment('c') }}
    -// Recommends are as of now still abused in many packages
    -APT::Install-Recommends "0";
    -APT::Install-Suggests "0";
    +
    {{ ansible_managed_file | comment('c') }}
    +// Recommends are as of now still abused in many packages
    +APT::Install-Recommends "0";
    +APT::Install-Suggests "0";
     
    -
    -

    8.4 vdr

    +
    +

    8.4 vdr

    -
    -

    8.4.1 tasks

    +
    +

    8.4.1 tasks

    -
    1. install the basic vdr packages
      +
      1. install the basic vdr packages
        -
        ---
        -# file: roles/vdr/tasks/main.yml
        +
        ---
        +# file: roles/vdr/tasks/main.yml
         
        -- name: apt | install basic vdr packages
        -  apt:
        -    name: '{{ item }}'
        -    state: present
        -    install_recommends: no
        -  with_items:
        +- name: apt | install basic vdr packages
        +  apt:
        +    name: '{{ item }}'
        +    state: present
        +    install_recommends: no
        +  with_items:
             - vdr
             - vdrctl
             - vdr-plugin-dbus2vdr
         
      2. -
      3. Add svdrp/svdrp-disc to /etc/services
        +
      4. Add svdrp/svdrp-disc to /etc/services
        -
        - name: add svdrp and svdrp-disc to /etc/services
        -  lineinfile:
        -    dest: /etc/services
        -    state: present
        -    line: "{{ item }}"
        -  with_items:
        -    - "svdrp            6419/tcp"
        -    - "svdrp-disc       6419/udp"
        +
        - name: add svdrp and svdrp-disc to /etc/services
        +  lineinfile:
        +    dest: /etc/services
        +    state: present
        +    line: "{{ item }}"
        +  with_items:
        +    - "svdrp            6419/tcp"
        +    - "svdrp-disc       6419/udp"
         
      5. -
      6. Set up the recording directory for the vdr user
        +
      7. Set up the recording directory for the vdr user
        -
        - name: create vdr recdir
        -  file:
        -    state: directory
        -    owner: '{{ vdr.user }}'
        -    group: '{{ vdr.group }}'
        -    mode: 0775
        -    dest: '{{ vdr.recdir }}'
        +
        - name: create vdr recdir
        +  file:
        +    state: directory
        +    owner: '{{ vdr.user }}'
        +    group: '{{ vdr.group }}'
        +    mode: 0775
        +    dest: '{{ vdr.recdir }}'
         
        -- name: set option to use hide-first-recording-level patch
        -  blockinfile:
        -    dest: /etc/vdr/conf.d/04-vdr-hide-first-recordinglevel.conf
        -    create: true
        -    block: |
        -      [vdr]
        -      --hide-first-recording-level
        -  when:
        +- name: set option to use hide-first-recording-level patch
        +  blockinfile:
        +    dest: /etc/vdr/conf.d/04-vdr-hide-first-recordinglevel.conf
        +    create: true
        +    block: |
        +      [vdr]
        +      --hide-first-recording-level
        +  when:
             vdr.hide_first_recording_level
         
        -- name: create local dir in recdir
        -  file:
        -    state: directory
        -    owner: '{{ vdr.user }}'
        -    group: '{{ vdr.group }}'
        -    mode: '0775'
        -    dest: '{{ vdr.recdir }}/local'
        -  when:
        +- name: create local dir in recdir
        +  file:
        +    state: directory
        +    owner: '{{ vdr.user }}'
        +    group: '{{ vdr.group }}'
        +    mode: '0775'
        +    dest: '{{ vdr.recdir }}/local'
        +  when:
             vdr.hide_first_recording_level
         
        -# TODO: set recdir, user etc. in /etc/vdr/conf.d/
        +# TODO: set recdir, user etc. in /etc/vdr/conf.d/
         
      8. -
      9. Install additional vdr plugins
        +
      10. Install additional vdr plugins

        The additional plugins to install can be set in the variable {{vdr_plugins}} in the group variables

        -
        - name: apt | install additional vdr plugins
        -  apt:
        -    name: '{{ item }}'
        -    state: present
        -    install_recommends: no
        -  with_items:
        -    '{{ vdr_plugins | default({}) }}'
        -  notify: [ 'Restart VDR' ]
        +
        - name: apt | install additional vdr plugins
        +  apt:
        +    name: '{{ item }}'
        +    state: present
        +    install_recommends: no
        +  with_items:
        +    '{{ vdr_plugins | default({}) }}'
        +  notify: [ 'Restart VDR' ]
         
      11. -
      12. copy vdr configuration files (if they don’t exist yet)
        +
      13. copy vdr configuration files (if they don’t exist yet)
        -
        - name: ensure vdr is stopped
        -  systemd:
        -    name: vdr.service
        -    state: stopped
        -  notify: [ 'Start VDR' ]
        +
        - name: ensure vdr is stopped
        +  systemd:
        +    name: vdr.service
        +    state: stopped
        +  notify: [ 'Start VDR' ]
         
        -- name: "vdr configuration | copy remote.conf if it doesn't exist yet"
        -  copy:
        -    src: files/remote.conf
        -    dest: '{{ vdr.confdir }}/remote.conf'
        -    owner: '{{ vdr.user }}'
        -    group: '{{ vdr.group }}'
        -    mode: 0644
        -    force: no
        +- name: "vdr configuration | copy remote.conf if it doesn't exist yet"
        +  copy:
        +    src: files/remote.conf
        +    dest: '{{ vdr.confdir }}/remote.conf'
        +    owner: '{{ vdr.user }}'
        +    group: '{{ vdr.group }}'
        +    mode: 0644
        +    force: no
         
        -- name: "vdr configuration | copy keymacros.conf if it doesn't exist yet"
        -  copy:
        -    src: files/keymacros.conf
        -    dest: '{{ vdr.confdir }}/keymacros.conf'
        -    owner: '{{ vdr.user }}'
        -    group: '{{ vdr.group }}'
        -    mode: 0644
        -    force: no
        +- name: "vdr configuration | copy keymacros.conf if it doesn't exist yet"
        +  copy:
        +    src: files/keymacros.conf
        +    dest: '{{ vdr.confdir }}/keymacros.conf'
        +    owner: '{{ vdr.user }}'
        +    group: '{{ vdr.group }}'
        +    mode: 0644
        +    force: no
         
    -
    -

    8.4.2 templates

    +
    +

    8.4.2 templates

    -
    -

    8.4.3 files

    +
    +

    8.4.3 files

    -
    1. remote.conf
      +
      1. remote.conf
        LIRC.Up KEY_UP
         LIRC.Down KEY_DOWN
        @@ -1405,16 +1408,16 @@ XKeySym.Next       XF86AudioNext
         
      2. -
      3. keymacros.conf
        +
      4. keymacros.conf
        -
        # Remote control key macros for VDR
        -#
        -# Format:
        -#
        -# macrokey  key1 key2 key3...
        -# macrokey  @plugin key1 key2 key3...
        -#
        -# See man vdr(5)
        +
        # Remote control key macros for VDR
        +#
        +# Format:
        +#
        +# macrokey  key1 key2 key3...
        +# macrokey  @plugin key1 key2 key3...
        +#
        +# See man vdr(5)
         
         Red       Recordings
         Green     Schedule
        @@ -1428,696 +1431,380 @@ User0     @osdteletext
         
    -
    -

    8.5 STARTED yavdr-network

    +
    +

    8.5 STARTED yavdr-network

    -
    -

    8.5.1 default variables

    +
    +

    8.5.1 default variables

    -
    install_avahi: true
    +
    install_avahi: true
     
    -
    -

    8.5.2 tasks

    +
    +

    8.5.2 tasks

    -
    ---
    -# this playbook sets up network services for a yaVDR installation
    +
    ---
    +# this playbook sets up network services for a yaVDR installation
     
    -- name: apt |install packages for network services
    -  apt:
    -      name: '{{ item }}'
    -      state: present
    -      install_recommends: no
    -  with_items:
    +- name: apt |install packages for network services
    +  apt:
    +      name: '{{ item }}'
    +      state: present
    +      install_recommends: no
    +  with_items:
           - avahi-daemon
           - avahi-utils
    -      - biosdevname
    +      #- biosdevname # caution: this may change device names after a minimal installation!
           - ethtool
           - nfs-common
           - vdr-addon-avahi-linker
           - wakeonlan
     
    -# Does this really work? We need a way to check if an interface supports WOL - Python Skript?
    -# - name: check WOL capabilities of network interfaces
    -#   shell: 'ethtool {{ item }} | grep -Po "(?<=Supports\sWake-on:\s).*$"'
    -#   register: wol
    -#   with_items: '{% for interface in ansible_interfaces if interface != 'lo' and interface != 'bond0' %}'
    +# Does this really work? We need a way to check if an interface supports WOL - Python Skript?
    +# - name: check WOL capabilities of network interfaces
    +#   shell: 'ethtool {{ item }} | grep -Po "(?<=Supports\sWake-on:\s).*$"'
    +#   register: wol
    +#   with_items: '{% for interface in ansible_interfaces if interface != 'lo' and interface != 'bond0' %}'
       
    -- name: restart autofs if running
    -  systemd:
    -    name: autofs
    -    state: restarted
    -    enabled: yes
    -    masked: no
    +- name: restart autofs if running
    +  systemd:
    +    name: autofs
    +    state: restarted
    +    enabled: yes
    +    masked: no
     
    -- name: ensure autofs is running
    -  systemd:
    -    name: autofs
    -    state: started
    -    enabled: yes
    -    masked: no
    +- name: ensure autofs is running
    +  systemd:
    +    name: autofs
    +    state: started
    +    enabled: yes
    +    masked: no
     
    -- name: restart avahi-linker if running
    -  systemd:
    -    name: avahi-linker
    -    state: restarted
    -    enabled: yes
    -    masked: no
    +- name: restart avahi-linker if running
    +  systemd:
    +    name: avahi-linker
    +    state: restarted
    +    enabled: yes
    +    masked: no
     
    -- name: start avahi-linker
    -  systemd:
    -    name: avahi-linker
    -    state: started
    -    enabled: yes
    -    masked: no
    +- name: start avahi-linker
    +  systemd:
    +    name: avahi-linker
    +    state: started
    +    enabled: yes
    +    masked: no
    +
    +- name: enable and start additional services for avahi-linker
    +  systemd:
    +    name: '{{ item }}'
    +    state: started
    +    enabled: yes
    +    masked: no
    +  with_items:
    +    - vdr-net-monitor
    +    - vdr-update-monitor
    +    - prevent-umount-on-pause
     
    -
    -

    8.6 nfs-server

    +
    +

    8.6 nfs-server

    -
    -

    8.6.1 TODO avahi-services für NFS beim Stoppen des nfs-kernel-servers depublizieren, beim Start wieder announcen

    +
    +

    8.6.1 TODO avahi-services für NFS beim Stoppen des nfs-kernel-servers depublizieren, beim Start wieder announcen

    -
    -

    8.6.2 tasks

    +
    +

    8.6.2 tasks

    -
    ---
    +
    ---
     
    -- name: install nfs server packages
    -  apt:
    -    name: '{{ item }}'
    -    state: present
    -    install_recommends: no
    -  with_items:
    +- name: install nfs server packages
    +  apt:
    +    name: '{{ item }}'
    +    state: present
    +    install_recommends: no
    +  with_items:
         - nfs-kernel-server
         - nfs-common
     
    -- name: create /etc/exports
    -  template:
    -    src: templates/nfs-exports.j2
    -    dest: /etc/exports
    -  notify: [ 'Restart NFS Kernel Server' ]
    +- name: create /etc/exports
    +  template:
    +    src: templates/nfs-exports.j2
    +    dest: /etc/exports
    +  notify: [ 'Restart NFS Kernel Server' ]
     
    -- name: populate /etc/avahi/services
    -  template:
    -    src: templates/avahi/service.j2
    -    dest: '/etc/avahi/services/yavdr-{{ item.key }}.service'
    -  with_dict: '{{ media_dirs }}'
    +- name: populate /etc/avahi/services
    +  template:
    +    src: templates/avahi/service.j2
    +    dest: '/etc/avahi/services/yavdr-{{ item.key }}.service'
    +  with_dict: '{{ media_dirs }}'
     
    -
    -

    8.6.3 templates

    +
    +

    8.6.3 templates

    -
    1. /etc/exports
      +
      1. /etc/exports
        -
        /srv *(rw,fsid=0,sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }})
        +
        /srv *(rw,fsid=0,sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }})
         {% for name, path in media_dirs.iteritems() %}
        -{{ path }} *(rw,fsid={{ loop.index }},sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }}{{ ',insecure' if nfs.insecure else '' }})
        +{{ path }} *(rw,fsid={{ loop.index }},sync,no_subtree_check,all_squash,anongid={{ vdr.gid }},anonuid={{ vdr.uid }}{{ ',insecure' if nfs.insecure else '' }})
         {% endfor %}
         
      2. -
      3. avahi services
        +
      4. avahi services
        -
        <?xml version="1.0" standalone='no'?>
        -<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
        -<service-group>
        -<name replace-wildcards="yes">{{ item.key|capitalize }} on %h</name> ## Name
        -<service>
        -       <type>_nfs._tcp</type>
        -       <port>2049</port>
        -       <txt-record>path={{ item.value }}</txt-record> ## path to shared Folder
        -       <txt-record>subtype={{ 'vdr' if item.key == 'recordings' else item.key }}</txt-record> ## subtype
        -</service>
        -</service-group>
        +
        <?xml version="1.0" standalone='no'?>
        +<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
        +<service-group>
        +<name replace-wildcards="yes">{{ item.key|capitalize }} on %h</name> ## Name
        +<service>
        +       <type>_nfs._tcp</type>
        +       <port>2049</port>
        +       <txt-record>path={{ item.value }}</txt-record> ## path to shared Folder
        +       <txt-record>subtype={{ 'vdr' if item.key == 'recordings' else item.key }}</txt-record> ## subtype
        +</service>
        +</service-group>
         
    -
    -

    8.7 TODO yavdr-remote

    +
    +

    8.7 STARTED yavdr-remote

    -
    -

    8.7.1 default variables

    +
    +

    8.7.1 default variables

    -
    -

    8.7.2 tasks

    +
    +

    8.7.2 tasks

    -
    ---
    -# This role is used to set up the yaVDR remote control configuration.
    +
    ---
    +# This role is used to set up the yaVDR remote control configuration.
     
    -- name: apt | install yavdr-remote
    -  apt:
    -    name: yavdr-remote
    -    state: present
    +- name: apt | install yavdr-remote
    +  apt:
    +    name: yavdr-remote
    +    state: present
     
    -- name: apt | install eventlircd
    -  apt:
    -    name: eventlircd
    -    state: present
    -  when:
    -      install_eventlircd is defined and install_eventlircd
    +- name: apt | install eventlircd
    +  apt:
    +    name: eventlircd
    +    state: present
     
    -- name: apt | install lirc
    -  apt:
    -    name: lircd
    -    state: present
    -  when:
    -    - install_lircd is defined and install_lircd
    +- name: apt | install lirc
    +  apt:
    +    name: lirc
    +    state: present
     
    -- name: stop, mask and disable lircd.socket and lircd.service # (the default lirc configuration conflicts with eventlircd)
    -  systemd:
    -    name: '{{ item }}'
    -    enabled: no
    -    state: stopped
    -    masked: yes
    -  with_items:
    +- name: stop, mask and disable lircd.socket, lircd.service and lircd-uinput.service # (the default lirc configuration conflicts with eventlircd)
    +  systemd:
    +    name: '{{ item }}'
    +    enabled: no
    +    state: stopped
    +    masked: yes
    +  with_items:
         - lircd.service
         - lircd.socket
    -  ignore_errors: yes
    +    - lircd-uinput.service
    +  ignore_errors: yes
     
    -# TODO: upload lircd2uinput package to PPA
    -#- name: install lircd2uinput
    -#  tag: install
    -#  apt:
    -#      name: lircd2uinput
    -#      state: present
    -#  when:
    -#      install_eventlircd is defined and install_eventlircd
    +- name: configure vdr to read from a lircd-compatible socket
    +  template:
    +    src: templates/03-vdr-lirc.conf.j2
    +    dest: /etc/vdr/conf.d/03-vdr-lirc.conf
    +  notify: ['Restart VDR']
    +
    +# TODO: upload lircd2uinput package to PPA
    +#- name: install lircd2uinput
    +#  tag: install
    +#  apt:
    +#      name: lircd2uinput
    +#      state: present
    +#  when:
    +#      install_eventlircd is defined and install_eventlircd
     
    -
    -

    8.7.3 templates

    +
    +

    8.7.3 templates

    +
    +
    +
    {% if frontend != 'kodi' %}
    +[vdr]
    +--lirc=/var/run/lirc/lircd
    +{% endif %}
    +
    -
    -

    8.7.4 files

    +
    +
    +
    +

    8.7.4 files

    -
    -

    8.8 pulseaudio

    +
    +

    8.8 pulseaudio

    -
    -

    8.8.1 tasks

    +
    +

    8.8.1 tasks

    -
    ---
    +
    ---
     
    -- name: apt | install pulseaudio and pavucontrol
    -  apt:
    -    name: '{{ item }}'
    -    state: present
    -    install_recommends: no
    -  with_items:
    +- name: apt | install pulseaudio and pavucontrol
    +  apt:
    +    name: '{{ item }}'
    +    state: present
    +    install_recommends: no
    +  with_items:
         - pulseaudio
         - pavucontrol
     
    -- name: create /etc/asound.conf with pulseaudio as default device
    -  template:
    -    src: templates/alsa/asound.conf.j2
    -    dest: /etc/asound.conf
    +- name: create /etc/asound.conf with pulseaudio as default device
    +  template:
    +    src: templates/alsa/asound.conf.j2
    +    dest: /etc/asound.conf
     
    -
    -

    8.8.2 templates

    +
    +

    8.8.2 templates

    -
    # Use PulseAudio by default
    -pcm.!default {
    +
    # Use PulseAudio by default
    +pcm.!default {
       type pulse
    -  fallback "sysdefault"
    -  hint {
    +  fallback "sysdefault"
    +  hint {
         show on
    -    description "Default ALSA Output (currently PulseAudio Sound Server)"
    +    description "Default ALSA Output (currently PulseAudio Sound Server)"
       }
     }
     
    -ctl.!default {
    +ctl.!default {
       type pulse
    -  fallback "sysdefault"
    +  fallback "sysdefault"
     }
     
    -
    -

    8.9 yavdr-xorg

    +
    +

    8.9 yavdr-xorg

    -
    -

    8.9.1 TODO automatic X-server configuration

    +
    +

    8.9.1 About the GUI session

    -
      -
    • [X] detect connected display
    • -
    • [X] read EDID from displays
    • -
    • [ ] create a xorg.conf for nvidia/intel/amd gpus
    • -
    +

    +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. +

    + +

    +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. +

    + +

    +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/. +

    + +

    +Basic Services like the session DBus, pulseaudio etc. are started for the default.target of the session. +The openbox autostart script is used to update the systemd session with the needed session variables. It creates a file ~/.session-env which is used as an environment file by vdr.service (so the vdr knows the DISPLAY and can access pulseaudio). +

    + +

    +The autostart script then enables all services to be pulled in by yavdr-desktop.target. As the last step yavdr-desktop.target is startet, which results in staring yavdr-frontend.service and additional Units for a second display (openbox and a browser for osd2eb, if available). +

    + +

    +In order to achive a clean shutdown of the session, x@t7.service is set as a dependency of the systemd unit instance user@666.service and all processes within the session must be shutdown properly when stopping xlogin@vdr.service. If systemd units are used within the user session, they must stop their process(es) successfully (you should set them up to accept expected exit codes appropriately). The window manager openbox is started using the ~/.xinitrc and stopped using the systemd unit exit-wm.service (which runs on stopping the jobs pulled in by the default.target of the session). +

    - -
    1. HOLD Nvidia-GPUs:read EDID:
      -
      -
      $ nvidia-xconfig --extract-edids-from-file=/var/log/Xorg.0.log --extract-edids-output-file=/tmp/edid.bin.0
      -
      -Found 2 EDIDs in "/var/log/Xorg.0.log".
      -  Wrote EDID for "DELL 2407WFP (CRT-1)" to "/tmp/edid.bin.0.0" (128 bytes).
      -  Wrote EDID for "ADI A715 (DFP-1)" to "/tmp/edid.bin.0.1" (128 bytes).
      -
      -$ xrandr -q
      -Screen 0: minimum 8 x 8, current 3200 x 1200, maximum 8192 x 8192
      -DVI-I-0 disconnected primary (normal left inverted right x axis y axis)
      -VGA-0 connected 1920x1200+1280+0 (normal left inverted right x axis y axis) 519mm x 324mm
      -   1920x1200     59.95*+
      -   1680x1050     59.95  
      -   1280x1024     75.02    60.02  
      -   1152x864      75.00  
      -   1024x768      75.03    60.00  
      -   800x600       75.00    60.32  
      -   640x480       75.00    59.94  
      -DVI-I-1 disconnected (normal left inverted right x axis y axis)
      -HDMI-0 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
      -   1280x1024     60.02*+
      -   1024x768      60.00  
      -   800x600       60.32  
      -   640x480       59.95    59.94
      -
      -$ parse-edid < /tmp/edid.bin.0.1
      -Checksum Correct
      -
      -Section "Monitor"
      -    Identifier "ADI A715"
      -    ModelName "ADI A715"
      -    VendorName "ADI"
      -    # Monitor Manufactured week 15 of 2003
      -    # EDID version 1.3
      -    # Digital Display
      -    DisplaySize 330 270
      -    Gamma 2.20
      -    Option "DPMS" "true"
      -    #Not giving standard mode: 640x480, 60Hz
      -    #Not giving standard mode: 800x600, 60Hz
      -    #Not giving standard mode: 1024x768, 60Hz
      -    #Not giving standard mode: 1280x1024, 60Hz
      -    Modeline    "Mode 0" 108.00 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync 
      -    Modeline    "Mode 1" 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync 
      -EndSection
      -
      -$ parse-edid < /tmp/edid.bin.0.0
      -Checksum Correct
      -
      -Section "Monitor"
      -    Identifier "DELL 2407WFP"
      -    ModelName "DELL 2407WFP"
      -    VendorName "DEL"
      -    # Monitor Manufactured week 24 of 2007
      -    # EDID version 1.3
      -    # Analog Display
      -    Option "SyncOnGreen" "true"
      -    DisplaySize 520 330
      -    Gamma 2.20
      -    Option "DPMS" "true"
      -    Horizsync 30-83
      -    VertRefresh 56-76
      -    # Maximum pixel clock is 170MHz
      -    #Not giving standard mode: 1280x1024, 60Hz
      -    #Not giving standard mode: 1600x1200, 60Hz
      -    #Not giving standard mode: 1152x864, 75Hz
      -    #Not giving standard mode: 1680x1050, 60Hz
      -    Modeline    "Mode 0" 154.00 1920 1968 2000 2080 1200 1203 1209 1235 +hsync -vsync 
      -EndSection
      -
      -
      -
    2. -
    3. DONE Start X-server with debug-output
      -
      -
      # /etc/systemd/system/x-debug@.service
      -[Unit]
      -Description=X with verbose logging on %I
      -Wants=graphical.target
      -Before=graphical.target
      -Conflicts=xlogin@vdr.service x@vt7.service
      -
      -[Service]
      -Type=forking
      -ExecStart=/usr/bin/x-daemon -logverbose 6 -noreset %I -config xdiscover.conf
      -
      +
      +

      8.9.2 default variables

      - -
      -
      # /etc/X11/xdiscover.conf
      -Section "Device"
      -        Identifier "nvidia"
      -        Driver  "nvidia"
      -        Option  "NoLogo"              "true"
      -        Option  "DynamicTwinView"     "true"
      -        Option  "NoFlip"              "false"
      -#        Option  "FlatPanelProperties" "Scaling = Native"
      -#        Option  "ModeValidation"      "NoVesaModes, NoXServerModes"
      -#        Option  "ModeDebug"           "true"
      -#        Option  "HWCursor"            "false"
      -EndSection
      -
      -Section "Screen"
      -        Identifier      "screen"
      -        Device          "nvidia"
      -EndSection
      -
      -Section "Extensions"
      -        Option  "Composite"           "false"
      -EndSection
      -
      -
      -
      -
    4. - -
    5. DONE python-script for parsing xrandr –verbose output
      1. Example output
        -
        -
        $ xrandr --verbose
        -Screen 0: minimum 8 x 8, current 1280 x 720, maximum 8192 x 8192
        -VGA-0 disconnected primary (normal left inverted right x axis y axis)
        -    Identifier: 0x1c4
        -    Timestamp:  18571
        -    Subpixel:   unknown
        -    Clones:    
        -    CRTCs:      0 1
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 0 0 0 0 
        -        range: (0, 65535)
        -    SignalFormat: VGA 
        -        supported: VGA
        -    ConnectorType: VGA 
        -    ConnectorNumber: 0 
        -    _ConnectorLocation: 1 
        -HDMI-0 connected 1280x720+0+0 (0x1cb) normal (normal left inverted right x axis y axis) 885mm x 498mm
        -    Identifier: 0x1c5
        -    Timestamp:  18571
        -    Subpixel:   unknown
        -    Gamma:      1.0:1.0:1.0
        -    Brightness: 1.0
        -    Clones:    
        -    CRTC:       0
        -    CRTCs:      0 1fg
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    EDID: 
        -        00ffffffffffff004c2d800100000000
        -        2c0e01038059328c0ae2bda15b4a9824
        -        15474a20000001010101010101010101
        -        010101010101011d007251d01e206e28
        -        550075f23100001e011d00bc52d01e20
        -        b828554075f23100001e000000fd0032
        -        3d0f2e08000a202020202020000000fc
        -        0053414d53554e470a20202020200181
        -        02031971468413051403122309070783
        -        01000065030c001000011d8018711c16
        -        20582c250075f23100009e011d80d072
        -        1c1620102c258075f23100009e8c0ad0
        -        8a20e02d10103e960075f2310000188c
        -        0ad090204031200c40550075f2310000
        -        18000000000000000000000000000000
        -        000000000000000000000000000000ca
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 39 24 41 21 
        -        range: (0, 65535)
        -    SignalFormat: TMDS 
        -        supported: TMDS
        -    ConnectorType: HDMI 
        -    ConnectorNumber: 1 
        -    _ConnectorLocation: 2 
        -  1280x720 (0x1c6)   74.2MHz +HSync +VSync +preferred
        -        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock   45.0KHz
        -        v: height  720 start  725 end  730 total  750           clock   60.0Hz
        -  1920x1080 (0x1c7)   74.2MHz +HSync +VSync Interlace
        -        h: width  1920 start 2008 e#nd 2052 total 2200 skew    0 clock   33.8KHz
        -        v: height 1080 start 1084 end 1094 total 1124           clock   60.1Hz
        -  1920x1080 (0x1c8)   74.2MHz +HSync +VSync Interlace
        -        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock   33.7KHz
        -        v: height 1080 start 1084 end 1094 total 1124           clock   60.0Hz
        -  1920x1080 (0x1c9)   74.2MHz +HSync +VSync Interlace
        -        h: width  1920 start 2448 end 2492 total 2640 skew    0 clock   28.1KHz
        -        v: height 1080 start 1084 end 1094 total 1124           clock   50.0Hz
        -  1280x720 (0x1ca)   74.2MHz +HSync +VSync
        -        h: width  1280 start 1390 end 1430 total 1650 skew    0 clock   45.0KHz
        -        v: height  720 start  725 end  730 total  750           clock   59.9Hz
        -  1280x720 (0x1cb)   74.2MHz +HSync +VSync *current
        -        h: width  1280 start 1720 end 1760 total 1980 skew    0 clock   37.5KHz
        -        v: height  720 start  725 end  730 total  750           clock   50.0Hz
        -  800x600 (0x1cc)   40.0MHz +HSync +VSync
        -        h: width   800 start  840 end  968 total 1056 skew    0 clock   37.9KHz
        -        v: height  600 start  601 end  605 total  628           clock   60.3Hz
        -  800x600 (0x1cd)   36.0MHz +HSync +VSync
        -        h: width   800 start  824 end  896 total 1024 skew    0 clock   35.2KHz
        -        v: height  600 start  601 end  603 total  625           clock   56.2Hz
        -  720x576 (0x1ce)   27.0MHz -HSync -VSync
        -        h: width   720 start  732 end  796 total  864 skew    0 clock   31.2KHz
        -        v: height  576 start  581 end  586 total  625           clock   50.0Hz
        -  720x480 (0x1cf)   27.0MHz -HSync -VSync
        -        h: width   720 start  736 end  798 total  858 skew    0 clock   31.5KHz
        -        v: height  480 start  489 end  495 total  525           clock   59.9Hz
        -  640x480 (0x1d0)   25.2MHz -HSync -VSync
        -        h: width   640 start  656 end  752 total  800 skew    0 clock   31.5KHz
        -        v: height  480 start  490 end  492 total  525           clock   59.9Hz
        -  320x240 (0x1d1)   12.6MHz -HSync -VSync DoubleScan
        -        h: width   320 start  328 end  376 total  400 skew    0 clock   31.5KHz
        -        v: height  240 start  245 end  246 total  262           clock   60.1Hz
        -
        -
        - -
        -
        $ xrandr --verbose
        -Screen 0: minimum 8 x 8, current 3200 x 1200, maximum 8192 x 8192
        -DVI-I-0 disconnected primary (normal left inverted right x axis y axis)
        -    Identifier: 0x1c4
        -    Timestamp:  641679
        -    Subpixel:   unknown
        -    Clones:    
        -    CRTCs:      0 1
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 0 0 0 0 
        -        range: (0, 65535)
        -    SignalFormat: VGA 
        -        supported: VGA
        -    ConnectorType: DVI-I 
        -    ConnectorNumber: 0 
        -    _ConnectorLocation: 0 
        -VGA-0 connected 1920x1200+1280+0 (0x1c6) normal (normal left inverted right x axis y axis) 519mm x 324mm
        -    Identifier: 0x1c5
        -    Timestamp:  641679
        -    Subpixel:   unknown
        -    Gamma:      1.0:1.0:1.0
        -    Brightness: 1.0
        -    Clones:    
        -    CRTC:       1
        -    CRTCs:      0 1
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    EDID: 
        -        00ffffffffffff0010ac16a0534b4431
        -        181101030e342178eeee91a3544c9926
        -        0f5054a54b008180a940714fb3000101
        -        010101010101283c80a070b023403020
        -        360007442100001a000000ff00555935
        -        343537364531444b5320000000fc0044
        -        454c4c20323430375746500a000000fd
        -        00384c1e5311000a20202020202000f1
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 0 0 0 0 
        -        range: (0, 65535)
        -    SignalFormat: VGA 
        -        supported: VGA
        -    ConnectorType: VGA 
        -    ConnectorNumber: 2 
        -    _ConnectorLocation: 2 
        -  1920x1200 (0x1c6) 154.000MHz +HSync -VSync *current +preferred
        -        h: width  1920 start 1968 end 2000 total 2080 skew    0 clock  74.04KHz
        -        v: height 1200 start 1203 end 1209 total 1235           clock  59.95Hz
        -  1680x1050 (0x1c7) 146.250MHz -HSync +VSync
        -        h: width  1680 start 1784 end 1960 total 2240 skew    0 clock  65.29KHz
        -        v: height 1050 start 1053 end 1059 total 1089           clock  59.95Hz
        -  1280x1024 (0x1c8) 135.000MHz +HSync +VSync
        -        h: width  1280 start 1296 end 1440 total 1688 skew    0 clock  79.98KHz
        -        v: height 1024 start 1025 end 1028 total 1066           clock  75.02Hz
        -  1280x1024 (0x1c9) 108.000MHz +HSync +VSync
        -        h: width  1280 start 1328 end 1440 total 1688 skew    0 clock  63.98KHz
        -        v: height 1024 start 1025 end 1028 total 1066           clock  60.02Hz
        -  1152x864 (0x1ca) 108.000MHz +HSync +VSync
        -        h: width  1152 start 1216 end 1344 total 1600 skew    0 clock  67.50KHz
        -        v: height  864 start  865 end  868 total  900           clock  75.00Hz
        -  1024x768 (0x1cb) 78.750MHz +HSync +VSync
        -        h: width  1024 start 1040 end 1136 total 1312 skew    0 clock  60.02KHz
        -        v: height  768 start  769 end  772 total  800           clock  75.03Hz
        -  1024x768 (0x1cc) 65.000MHz -HSync -VSync
        -        h: width  1024 start 1048 end 1184 total 1344 skew    0 clock  48.36KHz
        -        v: height  768 start  771 end  777 total  806           clock  60.00Hz
        -  800x600 (0x1cd) 49.500MHz +HSync +VSync
        -        h: width   800 start  816 end  896 total 1056 skew    0 clock  46.88KHz
        -        v: height  600 start  601 end  604 total  625           clock  75.00Hz
        -  800x600 (0x1ce) 40.000MHz +HSync +VSync
        -        h: width   800 start  840 end  968 total 1056 skew    0 clock  37.88KHz
        -        v: height  600 start  601 end  605 total  628           clock  60.32Hz
        -  640x480 (0x1cf) 31.500MHz -HSync -VSync
        -        h: width   640 start  656 end  720 total  840 skew    0 clock  37.50KHz
        -        v: height  480 start  481 end  484 total  500           clock  75.00Hz
        -  640x480 (0x1d0) 25.175MHz -HSync -VSync
        -        h: width   640 start  656 end  752 total  800 skew    0 clock  31.47KHz
        -        v: height  480 start  490 end  492 total  525           clock  59.94Hz
        -DVI-I-1 disconnected (normal left inverted right x axis y axis)
        -    Identifier: 0x1d1
        -    Timestamp:  641679
        -    Subpixel:   unknown
        -    Clones:    
        -    CRTCs:      0 1
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 0 0 0 0 
        -        range: (0, 65535)
        -    SignalFormat: TMDS 
        -        supported: TMDS
        -    ConnectorType: DVI-I 
        -    ConnectorNumber: 0 
        -    _ConnectorLocation: 0 
        -HDMI-0 connected 1280x1024+0+0 (0x1c9) normal (normal left inverted right x axis y axis) 338mm x 270mm
        -    Identifier: 0x1d2
        -    Timestamp:  641679
        -    Subpixel:   unknown
        -    Gamma:      1.0:1.0:1.0
        -    Brightness: 1.0
        -    Clones:    
        -    CRTC:       0
        -    CRTCs:      0 1
        -    Transform:  1.000000 0.000000 0.000000
        -                0.000000 1.000000 0.000000
        -                0.000000 0.000000 1.000000
        -               filter: 
        -    EDID: 
        -        00ffffffffffff0004895d2320090000
        -        0f0d0103e0211b782ac5c6a3574a9c23
        -        124f5421080031404540614081800101
        -        010101010101302a009851002a403070
        -        1300520e1100001ea00f200031581c20
        -        28801400520e1100001e000000ff0033
        -        31355430324530323333360a000000fc
        -        0041444920413731350a20202020002b
        -    BorderDimensions: 4 
        -        supported: 4
        -    Border: 0 0 0 0 
        -        range: (0, 65535)
        -    SignalFormat: TMDS 
        -        supported: TMDS
        -    ConnectorType: HDMI 
        -    ConnectorNumber: 1 
        -    _ConnectorLocation: 1 
        -  1280x1024 (0x1c9) 108.000MHz +HSync +VSync *current +preferred
        -        h: width  1280 start 1328 end 1440 total 1688 skew    0 clock  63.98KHz
        -        v: height 1024 start 1025 end 1028 total 1066           clock  60.02Hz
        -  1024x768 (0x1cc) 65.000MHz -HSync -VSync
        -        h: width  1024 start 1048 end 1184 total 1344 skew    0 clock  48.36KHz
        -        v: height  768 start  771 end  777 total  806           clock  60.00Hz
        -  800x600 (0x1ce) 40.000MHz +HSync +VSync
        -        h: width   800 start  840 end  968 total 1056 skew    0 clock  37.88KHz
        -        v: height  600 start  601 end  605 total  628           clock  60.32Hz
        -  640x480 (0x1d3) 25.180MHz -HSync -VSync
        -        h: width   640 start  648 end  744 total  800 skew    0 clock  31.48KHz
        -        v: height  480 start  482 end  484 total  525           clock  59.95Hz
        -  640x480 (0x1d0) 25.175MHz -HSync -VSync
        -        h: width   640 start  656 end  752 total  800 skew    0 clock  31.47KHz
        -        v: height  480 start  490 end  492 total  525           clock  59.94Hz
        -
        -
        -
        -
      2. - -
      3. parse hex-strings
        -
        -
        >>> import binascii
        ->>> s = "deadbeef"
        ->>> binascii.a2b_hex(s)
        -b'\xde\xad\xbe\xef'
        -
        -
        -
    -
    -
    -

    8.9.2 default variables

    -
    -
    -

    8.9.3 tasks

    +
    +

    8.9.3 tasks

    -
    ---
    -# file: roles/yavdr-xorg/tasks/main.yml
    +
    ---
    +# file: roles/yavdr-xorg/tasks/main.yml
    +- include: setup-xorg.yml tags=install,update
    +- include: detect-xorg.yml tags=xorg:detect,install
    +- include: desktop-session.yml tags=install,update
    +
    +
    -# TODO: use hooks or requirements instead -- name: Stop VDR - systemd: - name: vdr.service - state: stopped - enabled: yes - notify: ['Start VDR'] +
    +
    ---
    +# file: roles/yavdr-xorg/tasks/setup-xorg.yml
    +- name: create directories for systemd drop-in files
    +  file:
    +    dest: '{{ item }}'
    +    state: directory
    +  with_items:
    +    - /etc/systemd/system/x@.service.d/
    +    - /etc/systemd/system/vdr.service.d/
    +    - '/etc/systemd/system/user@{{ vdr.uid }}.service.d/'
     
    -- name: create directory /etc/systemd/system/vdr.service.d/
    -  file:
    -    dest: /etc/systemd/system/vdr.service.d/
    -    state: directory
    +- name: add dependency to X-server for vdr.service using a drop-in
    +  template:
    +    src: templates/vdr-xorg.conf
    +    dest: /etc/systemd/system/vdr.service.d/vdr-xorg.conf
     
    -- name: add environment file for vdr.service
    -  template:
    -    src: templates/systemd/vdr-environ.j2
    -    dest: /etc/systemd/system/vdr.service.d/load-environ.conf
    +- name: start x@.service before xlogin@.service
    +  template:
    +    src: templates/x@service.d/xlogin.conf.j2
    +    dest: /etc/systemd/system/x@.service.d/xlogin.conf
     
    -- name: Stop xlogin
    -  systemd:
    -    name: xlogin@vdr.service
    -    state: stopped
    -    enabled: yes
    +- name: load environment file for vdr.service
    +  template:
    +    src: templates/systemd/vdr-environ.j2
    +    dest: /etc/systemd/system/vdr.service.d/load-environ.conf
     
    -- name: Stop x
    -  systemd:
    -    name: x@vt7.service
    -    state: stopped
    +- name: user@{{ vdr.uid }}.service depends on x@vt7.service
    +  template:
    +    src: templates/user@666.service.d/x-dependency.conf.j2
    +    dest: '/etc/systemd/system/user@{{ vdr.uid }}.service.d/x-dependency.conf'
     
    -- name: install packages for xorg
    -  apt:
    -    name: '{{ item }}'
    -    state: present
    -  with_items:
    +- name: start softhddevice detached and set audio to pulseaudio
    +  lineinfile:
    +    path: /etc/vdr/conf.avail/softhddevice.conf
    +    line: '{{ item }}'
    +  with_items:
    +      - '-D'
    +      # - '-a pulse' # do we need this with our existing asound.conf?
    +
    +- name: set a login shell for the user vdr
    +  user:
    +      name: '{{ vdr.user }}'
    +      shell: '/bin/bash'
    +      state: present
    +      uid: '{{ vdr.uid }}'
    +      groups: '{{ vdr.group }}'
    +      append: yes
    +
    +- name: install packages for xorg
    +  apt:
    +    name: '{{ item }}'
    +    state: present
    +  with_items:
         - xorg
         - xserver-xorg-video-all
         - xserver-xorg-input-all
    @@ -2127,313 +1814,357 @@ b'\xde\xad\xbe\xef'
         - tmux
         - kiosk-browser
         - read-edid
    -    #- yavdr-xorg
    +    - python3-dbus2vdr
    +    - python3-yavdrfrontend
    +    - vdr-plugin-desktop
    +    #- yavdr-xorg
    +
    +
    -- name: "stop x@vt7.service" - systemd: - name: "x@vt7.service" - state: stopped +
    +
    ---
    +# file: roles/yavdr-xorg/tasks/detect-xorg.yml
     
    -- name: "expand template for x-verbose@.service"
    -  template:
    -    src: "templates/systemd/system/x-verbose@.service.j2"
    -    dest: "/etc/systemd/system/x-verbose@.service"
    +- name: "expand template for x-verbose@.service"
    +  template:
    +    src: "templates/systemd/system/x-verbose@.service.j2"
    +    dest: "/etc/systemd/system/x-verbose@.service"
     
    -- name: "expand template for xorg-verbose.conf"
    -  template:
    -    src: "templates/xorg-verbose.conf.j2"
    -    dest: "/etc/X11/xorg-verbose.conf"
    +- name: "expand template for xorg-verbose.conf"
    +  template:
    +    src: "templates/xorg-verbose.conf.j2"
    +    dest: "/etc/X11/xorg-verbose.conf"
     
    -- name: "start x-verbose@.service"
    -  systemd:
    -    name: "x-verbose@vt7.service"
    -    state: started
    -    enabled: false
    -    masked: false
    -    daemon_reload: true
    +- name: Stop VDR
    +  systemd:
    +    name: vdr.service
    +    state: stopped
    +    enabled: yes
    +  notify: ['Start VDR']
     
    -- name: "wait a little bit, so X has some time to start up (needed?)"
    -  wait_for:
    -    timeout: 3
    +- name: Stop xlogin
    +  systemd:
    +    name: 'xlogin@{{ vdr.user }}.service'
    +    state: stopped
     
    -- name: "detect xorg configuration"
    -  action: xrandr_facts
    +- name: Stop x
    +  systemd:
    +    name: x@vt7.service
    +    state: stopped
     
    -- debug:
    -    var: xorg.primary
    +- name: "start x-verbose@.service"
    +  systemd:
    +    name: "x-verbose@vt7.service"
    +    state: started
    +    enabled: false
    +    masked: false
    +    daemon_reload: true
     
    -- debug:
    -    var: xorg.secondary
    -  when: xorg.secondary is defined
    +- name: "wait a little bit, so X has some time to start up (needed?)"
    +  wait_for:
    +    timeout: 3
     
    -- name: "stop x-verbose@vt7.service"
    -  systemd:
    -    name: "x-verbose@vt7.service"
    -    state: stopped
    -    enabled: false
    -    masked: true
    +- name: "detect xorg configuration"
    +  action: xrandr_facts
     
    -# TODO: expand template for xorg.conf (or snippets)
    -#       with respect for the available graphics card driver
    -#       nvidia, noveau, intel, radeon
    +- debug:
    +    var: xorg.primary
     
    -- name: create xorg.conf (for nvidia driver)
    -  template:
    -    src: templates/xorg.conf.j2
    -    dest: /etc/X11/xorg.conf
    -    backup: yes
    +- debug:
    +    var: xorg.secondary
    +  when: xorg.secondary is defined
     
    -- name: create folders for user session
    -  file:
    -    state: directory
    -    dest: '{{ item }}'
    -    mode: '0775'
    -    owner: '{{ vdr.user }}'
    -    group: '{{ vdr.group }}'
    -  with_items:
    -    - '{{ vdr.home }}/.config/systemd/user'
    -    - '{{ vdr.home }}/.config/openbox/'
    +- name: "stop x-verbose@vt7.service"
    +  systemd:
    +    name: "x-verbose@vt7.service"
    +    state: stopped
    +    enabled: false
    +    masked: true
     
    -- name: create folder for customizations of vdr.service
    -  file:
    -    state: directory
    -    dest: /etc/systemd/system/vdr.service.d
    -    mode: '0775'
    +# TODO: expand template for xorg.conf (or snippets)
    +#       with respect for the available graphics card driver
    +#       nvidia, noveau, intel, radeon
    +- name: create xorg.conf (for nvidia driver)
    +  template:
    +    src: templates/xorg.conf.j2
    +    dest: /etc/X11/xorg.conf
    +    backup: yes
    +
    +
    -- name: add dependency to X-server for vdr.service using a drop-in - template: - src: templates/vdr-xorg.conf - dest: /etc/systemd/system/vdr.service.d/ +
    +
    ---
    +# file: roles/yavdr-xorg/tasks/desktop-session.yml
     
    -- name: create folders for user configuration files
    -  file:
    -    state: directory
    -    dest: '{{ item }}'
    -    mode: '0775'
    -    owner: '{{ vdr.user }}'
    -    group: '{{ vdr.group }}'
    -  with_items:
    -    - '{{ vdr.home }}/.config/systemd/user'
    -    - '{{ vdr.home }}/.config/openbox'
    -    - '{{ vdr.home }}/.config/pulse'
    +- name: create folders for user configuration files
    +  file:
    +    state: directory
    +    dest: '{{ item }}'
    +    mode: '0775'
    +    owner: '{{ vdr.user }}'
    +    group: '{{ vdr.group }}'
    +  with_items:
    +    - '{{ vdr.home }}/.config/systemd/user'
    +    - '{{ vdr.home }}/.config/openbox'
    +    - '{{ vdr.home }}/.config/pulse'
     
    -- name: expand template for .xinitrc for vdr user
    -  template:
    -      src: 'templates/.xinitrc.j2'
    -      dest: '{{ vdr.home }}/.xinitrc'
    -      mode: 0755
    -      owner: '{{ vdr.user }}'
    -      group: '{{ vdr.group }}'
    +- name: expand template for .xinitrc for vdr user
    +  template:
    +      src: 'templates/.xinitrc.j2'
    +      dest: '{{ vdr.home }}/.xinitrc'
    +      mode: 0755
    +      owner: '{{ vdr.user }}'
    +      group: '{{ vdr.group }}'
     
    -- name: expand template for openbox autostart
    -  template:
    -      src: 'templates/openbox/autostart.j2'
    -      dest: '{{ vdr.home }}/.config/openbox/autostart'
    -      mode: 0755
    -      owner: '{{ vdr.user }}'
    -      group: '{{ vdr.group }}'
    +- name: expand template for openbox autostart
    +  template:
    +      src: 'templates/openbox/autostart.j2'
    +      dest: '{{ vdr.home }}/.config/openbox/autostart'
    +      mode: 0755
    +      owner: '{{ vdr.user }}'
    +      group: '{{ vdr.group }}'
     
    -- name: expand rc.xml for openbox
    -  template:
    -      src: 'templates/openbox/rc.xml.j2'
    -      dest: '{{ vdr.home }}/.config/openbox/rc.xml'
    -      mode: 0755
    -      owner: '{{ vdr.user }}'
    -      group: '{{ vdr.group }}'
    +- name: expand rc.xml for openbox
    +  template:
    +      src: 'templates/openbox/rc.xml.j2'
    +      dest: '{{ vdr.home }}/.config/openbox/rc.xml'
    +      mode: 0644
    +      owner: '{{ vdr.user }}'
    +      group: '{{ vdr.group }}'
     
    -- name: create yavdr-desktop.target for the user session
    -  template:
    -      src: 'templates/systemd/user/yavdr-desktop.target.j2'
    -      dest: '{{ vdr.home }}/.config/systemd/user/yavdr-desktop.target'
    -      mode: 0755
    -      owner: '{{ vdr.user }}'
    -      group: '{{ vdr.group }}'
    +- name: create yavdr-desktop.target for the user session
    +  template:
    +      src: 'templates/systemd/user/yavdr-desktop.target.j2'
    +      dest: '{{ vdr.home }}/.config/systemd/user/yavdr-desktop.target'
    +      mode: 0644
    +      owner: '{{ vdr.user }}'
    +      group: '{{ vdr.group }}'
     
    -- name: disable pulseaudio autospawning
    -  lineinfile:
    -    path: '{{ vdr.home }}/.config/pulse/client.conf'
    -    line: 'autospawn = no'
    -    create: yes
    -    state: present
    -    owner: '{{ vdr.user }}'
    -    group: '{{ vdr.group }}'
    +- name: disable pulseaudio autospawning
    +  lineinfile:
    +    path: '{{ vdr.home }}/.config/pulse/client.conf'
    +    line: 'autospawn = no'
    +    create: yes
    +    state: present
    +    owner: '{{ vdr.user }}'
    +    group: '{{ vdr.group }}'
     
    -- name: set a login shell for the user vdr
    -  user:
    -      name: '{{ vdr.user }}'
    -      shell: '/bin/bash'
    -      state: present
    -      uid: '{{ vdr.uid }}'
    -      groups: '{{ vdr.group }}'
    -      append: yes
    +- name: create tmux.service for the session
    +  template:
    +    src: roles/yavdr-xorg/templates/systemd/user/tmux.service.j2
    +    dest: '{{ vdr.home }}/.config/systemd/user/tmux.service'
     
    -- name: create tmux.service for the session
    -  template:
    -    src: roles/yavdr-xorg/templates/systemd/user/tmux.service.j2
    -    dest: '{{ vdr.home }}/.config/systemd/user/tmux.service'
    +- name: create wm-exit.service for the session
    +  template:
    +    src: roles/yavdr-xorg/templates/systemd/user/wm-exit.service.j2
    +    dest: '{{ vdr.home }}/.config/systemd/user/wm-exit.service'
     
    -- name: enable and start xlogin for the user vdr
    -  systemd:
    -    daemon_reload: yes
    -    name: 'xlogin@{{ vdr.user }}'
    -    enabled: yes
    -    state: started
    +- name: create detect-second-display.service for the session
    +  template:
    +    src: templates/systemd/user/detect-second-display.service.j2
    +    dest: '{{ vdr.home }}/.config/systemd/user/detect-second-display.service'
    +
    +- name: create openbox-second.service for the session
    +  template:
    +    src: templates/systemd/user/openbox-second.service.j2
    +    dest: '{{ vdr.home }}/.config/systemd/user/openbox-second.service'
    +
    +- name: create osd2web.service for the session
    +  template:
    +    src: templates/systemd/user/osd2web.service.j2
    +    dest: '{{ vdr.home }}/.config/systemd/user/osd2web.service'
    +
    +- name: link /usr/bin/start-desktop to /var/lib/vdr/plugins/desktop/starter
    +  file:
    +    src: /usr/bin/start-desktop
    +    dest: /var/lib/vdr/plugins/desktop/starter
    +    state: link
    +  
    +- name: enable and start xlogin for the vdr user
    +  systemd:
    +    daemon_reload: yes
    +    name: 'xlogin@{{ vdr.user }}'
    +    enabled: yes
    +    state: started
     
    -
    -

    8.9.4 templates

    +
    +

    8.9.4 templates

    -
    1. xorg
      1. x-verbose@.service
        +
        1. xorg
          1. x-verbose@.service
            -
            [Unit]
            -Description=X with verbose logging on %I
            -Wants=graphical.target
            -Before=graphical.target
            +
            ---
            +# file: roles/yavdr-xorg/templates/systemd/system/x-verbose@.service.j2
            +[Unit]
            +Description=X with verbose logging on %I
            +Wants=graphical.target
            +Before=graphical.target
             
            -[Service]
            -Type=forking
            -ExecStart=/usr/bin/x-daemon -logverbose 6 -noreset %I -config /etc/X11/xorg-debug.conf
            +[Service]
            +Type=forking
            +ExecStart=/usr/bin/x-daemon -logverbose 6 -noreset %I -config /etc/X11/xorg-debug.conf
             
          2. -
          3. Drop-in snippet for vdr.service
            +
          4. Drop-in snippet for x@.service
            -
            # file: roles/yavdr-xorg/templates/vdr-xorg.conf
            -# {{ ansible_managed_file }}
            -
            -[Unit]
            -After=x@vt7.service
            -Wants=x@vt7.service
            -#BindsTo=x@vt7.service
            +
            [Unit]
            +Before=xlogin@{{ vdr.user }}
             
            +
            -
            #!/bin/bash
            -# {{ ansible_managed_file }}
            -exec openbox-session
            +
            [Unit]
            +Wants=x@vt7.service
            +After=x@vt7.service
            +
            +[Service]
            +TimeoutStopSec=20
            +KillMode=mixed
             
          5. -
          6. xorg.conf
            + +
          7. Drop-in snippet for vdr.service
            -
            Section "Device"
            -        Identifier "nvidia"
            -        Driver  "nvidia"
            -        Option  "NoLogo"              "true"
            -        Option  "DynamicTwinView"     "true"
            -        Option  "NoFlip"              "false"
            -#        Option  "FlatPanelProperties" "Scaling = Native"
            -#        Option  "ModeValidation"      "NoVesaModes, NoXServerModes"
            -#        Option  "ModeDebug"           "true"
            -#        Option  "HWCursor"            "false"
            +
            # file: roles/yavdr-xorg/templates/vdr-xorg.conf
            +# {{ ansible_managed_file }}
            +[Unit]
            +After=x@vt7.service
            +Wants=x@vt7.service
            +#BindsTo=x@vt7.service
            +
            +
            +
          8. +
          9. .xinitrc
            +
            +
            #!/bin/bash
            +# {{ ansible_managed_file }}
            +exec openbox-session
            +
            +
            +
          10. +
          11. xorg.conf
            +
            +
            Section "Device"
            +        Identifier "nvidia"
            +        Driver  "nvidia"
            +        Option  "NoLogo"              "true"
            +        Option  "DynamicTwinView"     "true"
            +        Option  "NoFlip"              "false"
            +#        Option  "FlatPanelProperties" "Scaling = Native"
            +#        Option  "ModeValidation"      "NoVesaModes, NoXServerModes"
            +#        Option  "ModeDebug"           "true"
            +#        Option  "HWCursor"            "false"
             EndSection
             
            -Section "Screen"
            -        Identifier      "screen"
            -        Device          "nvidia"
            +Section "Screen"
            +        Identifier      "screen"
            +        Device          "nvidia"
             EndSection
             
            -Section "Extensions"
            -        Option  "Composite"           "false"
            +Section "Extensions"
            +        Option  "Composite"           "false"
             EndSection
             
            {{ ansible_managed_file | comment }}
             
            -Section "ServerLayout"
            -    Identifier     "Layout0"
            -    Screen         0  "Screen0"
            +Section "ServerLayout"
            +    Identifier     "Layout0"
            +    Screen         0  "Screen0" 0 0
             {% if xorg.secondary is defined %}
            -    Screen         1  "Screen1" RightOf "Screen0"
            +    Screen         1  "Screen1" RightOf "Screen0"
             {% endif %}
            -    #InputDevice    "Keyboard0" "CoreKeyboard"
            -    #InputDevice    "Mouse0" "CorePointer"
            +    #InputDevice    "Keyboard0" "CoreKeyboard"
            +    #InputDevice    "Mouse0" "CorePointer"
            +    Option         "Xinerama" "0"
             EndSection
             
            -Section "InputClass"
            -    Identifier "exclude eventlircd devices"
            -    MatchTag   "eventlircd"
            -    Option     "Ignore"    "True"
            +Section "InputClass"
            +    Identifier "exclude eventlircd devices"
            +    MatchTag   "eventlircd"
            +    Option     "Ignore"    "True"
             EndSection
             
            -Section "Monitor"
            -    Identifier     "Monitor0"
            -    VendorName     "{{ xorg.primary.vendor }}"
            -    ModelName      "{{ xorg.primary.model }}"
            -    Option         "DPMS"
            -    Option         "ExactModeTimingsDVI" "True"
            +Section "Monitor"
            +    Identifier     "Monitor0"
            +    VendorName     "{{ xorg.primary.vendor }}"
            +    ModelName      "{{ xorg.primary.model }}"
            +    Option         "DPMS"
            +    Option         "ExactModeTimingsDVI" "True"
             EndSection
             
            -Section "Device"
            -    Identifier     "Device0"
            -    Driver         "nvidia"
            -    VendorName     "NVIDIA Corporation"
            -    Option  "NoLogo"              "true"
            +Section "Device"
            +    Identifier     "Device0"
            +    Driver         "nvidia"
            +    VendorName     "NVIDIA Corporation"
            +    Option         "NoLogo"              "true"
             {% if xorg.primary.bus_id is defined %}
            -    BoardName      "{{ xorg.primary.gpu_name }}"
            -    BusID          "{{ xorg.primary.bus_id }}"
            +    BoardName      "{{ xorg.primary.gpu_name }}"
            +    BusID          "{{ xorg.primary.bus_id }}"
             {% else %}
            -    BoardName      "Unknown"
            +    BoardName      "Unknown"
             {% endif %}
                 Screen          0
             EndSection
             
            -Section "Screen"
            -    Identifier     "Screen0"
            -    Device         "Device0"
            -    Monitor        "Monitor0"
            +Section "Screen"
            +    Identifier     "Screen0"
            +    Device         "Device0"
            +    Monitor        "Monitor0"
                 DefaultDepth    24
            -    Option         "nvidiaXineramaInfoOrder" "{{ xorg.primary.connector }}"
            -    Option         "ConnectedMonitor" "{{ xorg.primary.connector }}"
            -    Option         "UseDisplayDevice" "{{ xorg.primary.connector }}"
            -    Option         "CustomEDID" "{{ xorg.primary.connector }}:/etc/X11/edid.{{ xorg.primary.connector }}.bin"
            -    Option         "metamodes" "{{ xorg.primary.connector }}: {{ xorg.primary.mode }} +0+0"
            -    Option         "SLI" "Off"
            -    Option         "MultiGPU" "Off"
            -    Option         "BaseMosaic" "off"
            -    SubSection     "Display"
            +    Option         "nvidiaXineramaInfoOrder" "{{ xorg.primary.connector }}"
            +    Option         "ConnectedMonitor" "{{ xorg.primary.connector }}{% if xorg.secondary is defined %}, {{ xorg.secondary.connector }}{% endif %}"
            +    Option         "UseDisplayDevice" "{{ xorg.primary.connector }}"
            +    Option         "CustomEDID" "{{ xorg.primary.connector }}:/etc/X11/edid.{{ xorg.primary.connector }}.bin"
            +    Option         "metamodes" "{{ xorg.primary.connector }}: {{ xorg.primary.mode }} +0+0"
            +    Option         "SLI" "Off"
            +    Option         "MultiGPU" "Off"
            +    Option         "BaseMosaic" "off"
            +    SubSection     "Display"
                     Depth       24
                 EndSubSection
             EndSection
             
             {% if xorg.secondary is defined %}
            -Section "Device"
            -    Identifier     "Device1"
            -    Driver         "nvidia"
            -    VendorName     "NVIDIA Corporation"
            -    Option  "NoLogo"              "true"
            +Section "Device"
            +    Identifier     "Device1"
            +    Driver         "nvidia"
            +    VendorName     "NVIDIA Corporation"
            +    Option  "NoLogo"              "true"
             {% if xorg.secondary.bus_id is defined %}
            -    BoardName      "{{ xorg.primary.gpu_name }}"
            -    BusID          "{{ xorg.primary.bus_id }}"
            +    BoardName      "{{ xorg.primary.gpu_name }}"
            +    BusID          "{{ xorg.primary.bus_id }}"
             {% else %}
            -    BoardName      "Unknown"
            +    BoardName      "Unknown"
             {% endif %}
                 Screen          1
             EndSection
             
            -Section "Monitor"
            -    Identifier     "Monitor1"
            -    VendorName     "{{ xorg.secondary.vendor }}"
            -    ModelName      "{{ xorg.secondary.model }}"
            +Section "Monitor"
            +    Identifier     "Monitor1"
            +    VendorName     "{{ xorg.secondary.vendor }}"
            +    ModelName      "{{ xorg.secondary.model }}"
             EndSection
             
            -Section "Screen"
            -    Identifier     "Screen1"
            -    Device         "Device1"
            -    Monitor        "Monitor1"
            +Section "Screen"
            +    Identifier     "Screen1"
            +    Device         "Device1"
            +    Monitor        "Monitor1"
                 DefaultDepth    24
            -    Option         "nvidiaXineramaInfoOrder" "{{ xorg.secondary.connector }}"
            -    Option         "ConnectedMonitor" "{{ xorg.secondary.connector }}"
            -    Option         "UseDisplayDevice" "{{ xorg.secondary.connector }}"
            -    Option         "CustomEDID" "{{ xorg.secondary.connector }}:/etc/X11/edid.{{ xorg.secondary.connector }}.bin"
            -    Option         "metamodes" "{{ xorg.secondary.connector }}: {{ xorg.secondary.mode }} +0+0"
            -    Option         "SLI" "Off"
            -    Option         "MultiGPU" "Off"
            -    Option         "BaseMosaic" "off"
            -    SubSection     "Display"
            +    Option         "nvidiaXineramaInfoOrder" "{{ xorg.secondary.connector }}"
            +    Option         "ConnectedMonitor" "{{ xorg.secondary.connector }}"
            +    Option         "UseDisplayDevice" "{{ xorg.secondary.connector }}"
            +    Option         "CustomEDID" "{{ xorg.secondary.connector }}:/etc/X11/edid.{{ xorg.secondary.connector }}.bin"
            +    Option         "metamodes" "{{ xorg.secondary.connector }}: {{ xorg.secondary.mode }} +0+0"
            +    Option         "SLI" "Off"
            +    Option         "MultiGPU" "Off"
            +    Option         "BaseMosaic" "off"
            +    SubSection     "Display"
                     Depth       24
                 EndSubSection
             EndSection
            @@ -2444,1133 +2175,1154 @@ EndSection
             
            {{ ansible_managed_file | comment }}
             
            -Section "ServerLayout"
            -    Identifier     "Layout0"
            -    Screen      0  "Screen0"
            +Section "ServerLayout"
            +    Identifier     "Layout0"
            +    Screen      0  "Screen0"
                 {% if xorg.best_tv_mode.secondary is defined %}
            -    Screen      1  "Screen1" RightOf "Screen0"
            +    Screen      1  "Screen1" RightOf "Screen0"
                 {% endif %}
            -    InputDevice    "Keyboard0" "CoreKeyboard"
            -    InputDevice    "Mouse0" "CorePointer"
            +    InputDevice    "Keyboard0" "CoreKeyboard"
            +    InputDevice    "Mouse0" "CorePointer"
             EndSection
             
            -Section "InputDevice"
            -    # generated from default
            -    Identifier     "Mouse0"
            -    Driver         "mouse"
            -    Option         "Protocol" "auto"
            -    Option         "Device" "/dev/psaux"
            -    Option         "Emulate3Buttons" "no"
            -    Option         "ZAxisMapping" "4 5"
            +Section "InputDevice"
            +    # generated from default
            +    Identifier     "Mouse0"
            +    Driver         "mouse"
            +    Option         "Protocol" "auto"
            +    Option         "Device" "/dev/psaux"
            +    Option         "Emulate3Buttons" "no"
            +    Option         "ZAxisMapping" "4 5"
             EndSection
             
            -# ignore devices with eventlircd tag 
            -# ENV{ID_INPUT.tags}+="eventlircd"
            -# must be set by an udev rule
            -Section "InputClass"
            -    Identifier "ignore eventlircd devices"
            -    MatchTag "eventlircd"
            -    Option "Ignore" "True"
            +# ignore devices with eventlircd tag 
            +# ENV{ID_INPUT.tags}+="eventlircd"
            +# must be set by an udev rule
            +Section "InputClass"
            +    Identifier "ignore eventlircd devices"
            +    MatchTag "eventlircd"
            +    Option "Ignore" "True"
             EndSection
             
             
             
            -Section "InputDevice"
            -    # generated from default
            -    Identifier     "Keyboard0"
            -    Driver         "kbd"
            +Section "InputDevice"
            +    # generated from default
            +    Identifier     "Keyboard0"
            +    Driver         "kbd"
             EndSection
             
             
            -Section "Monitor"
            -    Identifier     "Monitor0"
            -    VendorName     "Unknown"
            -    ModelName      "Unknown"
            -{# TODO: VGA2SCART support (if needed)
            -{% if system.x11.display.0.default == "VGA2Scart_4_3" or system.x11.display.0.default == "VGA2Scart_16_9" %}
            +Section "Monitor"
            +    Identifier     "Monitor0"
            +    VendorName     "Unknown"
            +    ModelName      "Unknown"
            +{# TODO: VGA2SCART support (if needed)
            +{% if system.x11.display.0.default == "VGA2Scart_4_3" or system.x11.display.0.default == "VGA2Scart_16_9" %}
                 HorizSync       14-17
                 VertRefresh     49-61
            -    {% if system.x11.display.0.default == "VGA2Scart_4_3" %}
            -    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
            -    {% elif system.x11.display.0.default == "VGA2Scart_16_9" %}
            -    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
            +    {% if system.x11.display.0.default == "VGA2Scart_4_3" %}
            +    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
            +    {% elif system.x11.display.0.default == "VGA2Scart_16_9" %}
            +    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
                 {% endif %}
             {% endif %}
            -#}
            -    Option         "DPMS"
            -    Option         "ExactModeTimingsDVI" "True"
            +#}
            +    Option         "DPMS"
            +    Option         "ExactModeTimingsDVI" "True"
             EndSection
             
             
             {% if xrandr.best_tv_mode.secondary is defined %}
            -Section "Monitor"
            -    Identifier     "Monitor1"
            -    VendorName     "Unknown"
            -    ModelName      "Unknown"
            +Section "Monitor"
            +    Identifier     "Monitor1"
            +    VendorName     "Unknown"
            +    ModelName      "Unknown"
             {#
            -{% if system.x11.display.1.default in ("VGA2Scart_4_3",  "VGA2Scart_16_9") %}
            +{% if system.x11.display.1.default in ("VGA2Scart_4_3",  "VGA2Scart_16_9") %}
                 HorizSync       14-17
                 VertRefresh     49-61
            -    {% if system.x11.display.1.default == "VGA2Scart_4_3" %}
            -    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
            -    {% elif system.x11.display.1.default == "VGA2Scart_16_9" %}
            -    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
            +    {% if system.x11.display.1.default == "VGA2Scart_4_3" %}
            +    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
            +    {% elif system.x11.display.1.default == "VGA2Scart_16_9" %}
            +    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
                 {% endif %}
            -    Option         "DPMS"
            -    Option         "ExactModeTimingsDVI" "True"
            +    Option         "DPMS"
            +    Option         "ExactModeTimingsDVI" "True"
             {% endif %}
            -#}
            +#}
             EndSection
             {% endif %}
             
            -Section "Device"
            -    Identifier     "Device0"
            +Section "Device"
            +    Identifier     "Device0"
             {% if system.hardware.nvidia.detected %}
            -    Driver         "nvidia"
            -    VendorName     "NVIDIA Corporation"
            +    Driver         "nvidia"
            +    VendorName     "NVIDIA Corporation"
             {% endif %}
                 Screen          0
            -    Option         "DPI" "100x100"
            +    Option         "DPI" "100x100"
             {% if system.hardware.nvidia.busid is defined and system.hardware.busid %}
            -    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
            +    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
             {% endif %}
            -    Option         "NoLogo" "True"
            -    Option         "UseEvents" "True"
            -    Option         "TripleBuffer" "False"
            -    Option         "AddARGBGLXVisuals" "True"
            -    Option         "TwinView" "0"
            -    Option         "DynamicTwinView" "0"
            -    Option         "OnDemandVBlankinterrupts" "on"
            -    Option         "FlatPanelProperties" "Scaling = Native"
            +    Option         "NoLogo" "True"
            +    Option         "UseEvents" "True"
            +    Option         "TripleBuffer" "False"
            +    Option         "AddARGBGLXVisuals" "True"
            +    Option         "TwinView" "0"
            +    Option         "DynamicTwinView" "0"
            +    Option         "OnDemandVBlankinterrupts" "on"
            +    Option         "FlatPanelProperties" "Scaling = Native"
             EndSection
             
             {% if xrandr.best_tv_mode.secondary is defined %}
            -Section "Device"
            -    Identifier     "Device1"
            +Section "Device"
            +    Identifier     "Device1"
                 {% if system.hardware.nvidia.detected %}
            -    Driver         "nvidia"
            -    VendorName     "NVIDIA Corporation"
            +    Driver         "nvidia"
            +    VendorName     "NVIDIA Corporation"
                 {% endif %}
                 Screen          1
                 {% if system.hardware.nvidia.busid is defined and system.hardware.nvidia.busid %}
            -    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
            +    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
                 {% endif %}
            -    Option         "NoLogo" "True"
            -    Option         "UseEvents" "True"
            -    Option         "TripleBuffer" "False"
            -    Option         "AddARGBGLXVisuals" "True"
            -    Option         "TwinView" "0"
            -    Option         "DynamicTwinView" "0"
            +    Option         "NoLogo" "True"
            +    Option         "UseEvents" "True"
            +    Option         "TripleBuffer" "False"
            +    Option         "AddARGBGLXVisuals" "True"
            +    Option         "TwinView" "0"
            +    Option         "DynamicTwinView" "0"
             EndSection
             {% endif %}
             
             
            -Section "Screen"
            -    Identifier     "Screen0"
            -    Device         "Device0"
            -    Monitor        "Monitor0"
            +Section "Screen"
            +    Identifier     "Screen0"
            +    Device         "Device0"
            +    Monitor        "Monitor0"
                 DefaultDepth    24
            -    SubSection     "Display"
            +    SubSection     "Display"
                     Depth       24
             {% if xrandr.best_tv_mode.primary is defined %}
            -        Modes      "{{ xrandr.best_tv_mode.primary.mode }}"{#{% for mode in xrandr %}{% if mode != system.x11.display.0.default %} "{{ mode }}"{% endif %}{% endfor %}#} nvidia-auto-select
            +        Modes      "{{ xrandr.best_tv_mode.primary.mode }}"{#{% for mode in xrandr %}{% if mode != system.x11.display.0.default %} "{{ mode }}"{% endif %}{% endfor %}#} nvidia-auto-select
             
             {% elif system.hardware.nvidia.detected == 1 %}
            -        Modes      "nvidia-auto-select"
            +        Modes      "nvidia-auto-select"
             {% endif %}
                 EndSubSection
             {% if system.x11.display.0.default or system.x11.default %}
                 {% if system.x11.display.0.device is definded and system.x11.display.0.device %}
            -    Option         "ConnectedMonitor" {{ system.x11.display.0.device }}
            +    Option         "ConnectedMonitor" {{ system.x11.display.0.device }}
                 {% else %}
            -    Option         "ConnectedMonitor" {{ system.x11.default }}
            +    Option         "ConnectedMonitor" {{ system.x11.default }}
                 {% endif %}
            -    #     Option         "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
            -    #Option         "ConnectedMonitor"
            -    "<?cs if:(?system.x11.display.0.device) ?>
            -          <?cs call:fix_display_name(system.x11.display.0.device) ?>
            -     <?cs else ?>
            -          <?cs var:system.x11.default ?>
            -     <?cs /if ?>
            -     <?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
            -#     Option         "UseDisplayDevice" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?>"
            -# <?cs /if ?>
            -# <?cs if:(?system.hardware.nvidia.0.edid && system.hardware.nvidia.0.edid == "1") ?>
            -#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.0.device) ?>:/etc/X11/edid.0.yavdr"
            -# <?cs /if ?>
            -# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.0.device) ?>
            -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:system.x11.display.0.default ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"
            -# <?cs each:mode = system.x11.display.0.mode ?><?cs if:(mode != system.x11.display.0.default) ?>
            -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?> 
            +    #     Option         "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
            +    #Option         "ConnectedMonitor"
            +    "<?cs if:(?system.x11.display.0.device) ?>
            +          <?cs call:fix_display_name(system.x11.display.0.device) ?>
            +     <?cs else ?>
            +          <?cs var:system.x11.default ?>
            +     <?cs /if ?>
            +     <?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
            +#     Option         "UseDisplayDevice" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?>"
            +# <?cs /if ?>
            +# <?cs if:(?system.hardware.nvidia.0.edid && system.hardware.nvidia.0.edid == "1") ?>
            +#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.0.device) ?>:/etc/X11/edid.0.yavdr"
            +# <?cs /if ?>
            +# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.0.device) ?>
            +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:system.x11.display.0.default ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"
            +# <?cs each:mode = system.x11.display.0.mode ?><?cs if:(mode != system.x11.display.0.default) ?>
            +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?> 
             {% endif %}
             EndSection
             
            -{% if system.x11.dualhead.enabled == "1" %}
            -Section "Screen"
            +{% if system.x11.dualhead.enabled == "1" %}
            +Section "Screen"
             
            -     Identifier     "Screen1"
            -     Device         "Device1"
            -     Monitor        "Monitor1"
            +     Identifier     "Screen1"
            +     Device         "Device1"
            +     Monitor        "Monitor1"
                  DefaultDepth    24
            -     SubSection     "Display"
            +     SubSection     "Display"
                      Depth       24
             {% if system.x11.display.0.default is defined and system.x11.display.0.default %}
            -         Modes      "{{ system.x11.display.1.default }}"{% for mode in system.x11.display.1.mode %}{% if mode != system.x11.display.1.default %} "{{ mode }}"{% endif %}{% endfor %}
            +         Modes      "{{ system.x11.display.1.default }}"{% for mode in system.x11.display.1.mode %}{% if mode != system.x11.display.1.default %} "{{ mode }}"{% endif %}{% endfor %}
             
            -{% elif system.hardware.nvidia.detected == "1" %}
            -         Modes      "nvidia-auto-select"
            +{% elif system.hardware.nvidia.detected == "1" %}
            +         Modes      "nvidia-auto-select"
             {% endif %}
                   EndSubSection
             
            -# <?cs if:(?system.x11.display.1.default && system.x11.display.1.default != "" && system.x11.display.1.default != "disabled") ?>
            -#     Option         "UseDisplayDevice" "<?cs call:fix_display_name(system.x11.display.1.device) ?>"
            -# <?cs /if ?>
            -# <?cs if:(?system.hardware.nvidia.1.edid && system.hardware.nvidia.1.edid == "1") ?>
            -#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.1.device) ?>:/etc/X11/edid.1.yavdr"
            -# <?cs /if ?>
            -# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.1.device) ?>
            -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:system.x11.display.1.default ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"
            -# <?cs each:mode = system.x11.display.1.mode ?><?cs if:(mode != system.x11.display.1.default) ?>
            -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?>
            -# <?cs /if ?>
            +# <?cs if:(?system.x11.display.1.default && system.x11.display.1.default != "" && system.x11.display.1.default != "disabled") ?>
            +#     Option         "UseDisplayDevice" "<?cs call:fix_display_name(system.x11.display.1.device) ?>"
            +# <?cs /if ?>
            +# <?cs if:(?system.hardware.nvidia.1.edid && system.hardware.nvidia.1.edid == "1") ?>
            +#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.1.device) ?>:/etc/X11/edid.1.yavdr"
            +# <?cs /if ?>
            +# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.1.device) ?>
            +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:system.x11.display.1.default ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"
            +# <?cs each:mode = system.x11.display.1.mode ?><?cs if:(mode != system.x11.display.1.default) ?>
            +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?>
            +# <?cs /if ?>
             EndSection
             {% endif %}
             
        2. -
        3. vdr
          +
        4. vdr
          -
          [Service]
          -EnvironmentFile=-/var/lib/vdr/.session-env
          +
          [Service]
          +Environment=XDG_RUNTIME_DIR=/run/user/{{ vdr.uid }}/
          +EnvironmentFile=-/var/lib/vdr/.session-env
           
        5. -
        6. Systemd User Session
          1. yavdr-desktop.target
            +
          2. Systemd User Session
            1. yavdr-desktop.target
              [Unit]
              -Description=yaVDR Desktop
              -Requires=default.target
              -After=default.target pulseaudio.service
              -Wants=dbus.service pulseaudio.service
              -AllowIsolate=yes
              +Description=yaVDR Desktop
              +Requires=default.target
              +After=default.target pulseaudio.service
              +Wants=dbus.service pulseaudio.service
              +AllowIsolate=yes
               
            2. -
            3. detect-second-display
              +
            4. detect-second-display
              -
              [Unit]
              -Description=Detect second DISPLAY using xrandr
              +
              [Unit]
              +Description=Detect second DISPLAY using xrandr
               
              -[Service]
              -Type=oneshot
              -ExecStart=/bin/bash -c 'export DISPLAY=$DISPLAY.1; xrandr -q | grep "connected" && echo "DISPLAY=$DISPLAY" > ~/.second_display || rm -f ~/.second_display'
              +[Service]
              +Type=oneshot
              +ExecStart=/bin/bash -c 'export DISPLAY=$DISPLAY.1; xrandr -q | grep "connected" && echo "DISPLAY=$DISPLAY" > ~/.second_display || rm -f ~/.second_display'
               
              -[Install]
              -WantedBy=yavdr-desktop.target
              +[Install]
              +WantedBy=yavdr-desktop.target
               
            5. -
            6. openbox-second.service
              +
            7. openbox-second.service
              -
              [Unit]
              -Description=Start openbox on the second DISPLAY if it exists
              -After=detect-second-display.service
              -Wants=detect-second-display.service
              -Before=yavdr-frontend.service
              -ConditionFileNotEmpty=%h/.second_display
              +
              [Unit]
              +Description=Start openbox on the second DISPLAY if it exists
              +After=detect-second-display.service
              +Wants=detect-second-display.service
              +Before=yavdr-frontend.service
              +ConditionFileNotEmpty=%h/.second_display
               
              -[Service]
              -PassEnvironment=XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
              -EnvironmentFile=%h/.second_display
              -ExecStart=/usr/bin/openbox --config-file %h/.config/openbox/rc.xml
              +[Service]
              +PassEnvironment=XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
              +EnvironmentFile=%h/.second_display
              +ExecStart=/usr/bin/openbox --config-file %h/.config/openbox/rc.xml
               
              -[Install]
              -WantedBy=yavdr-desktop.target
              +[Install]
              +WantedBy=yavdr-desktop.target
               
            8. -
            9. osd2web.service
              +
            10. osd2web.service
              -
              [Unit]
              -Description=Start a kiosk browser on the second DISPLAY if it exists
              -After=detect-second-display.service openbox-second.service
              -Wants=detect-second-display.service openbox-second.service
              -ConditionFileNotEmpty=%h/.second_display
              +
              [Unit]
              +Description=Start a kiosk browser on the second DISPLAY if it exists
              +After=detect-second-display.service openbox-second.service
              +Wants=detect-second-display.service openbox-second.service
              +ConditionFileNotEmpty=%h/.second_display
               
              -[Service]
              -EnvironmentFile=%h/.second_display
              -PassEnvironment=XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
              -ExecStart=/usr/bin/on_vdr -o -c 'kiosk-browser "http://localhost:4444/skins/horchiTft/index.html?theme=blue&onlyView=1"'
              +[Service]
              +EnvironmentFile=%h/.second_display
              +PassEnvironment=XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
              +ExecStart=/usr/bin/on_vdr -o -c 'kiosk-browser "http://localhost:4444/skins/horchiTft/index.html?theme=blue&onlyView=1"'
              +KillSignal=SIGINT
               
              -[Install]
              -WantedBy=yavdr-desktop.target
              +[Install]
              +WantedBy=yavdr-desktop.target
               
            11. -
            12. tmux.service
              +
            13. tmux.service
              -
              [Unit]
              -Description=Start tmux in detached session
              +
              [Unit]
              +Description=Start tmux in detached session
               
              -[Service]
              -EnvironmentFile=-%h/.session-env
              -Type=forking
              -ExecStart=/usr/bin/tmux new-session -s use-session -d
              -ExecStop=/usr/bin/tmux kill-session -t %u
              -Restart=always
              +[Service]
              +EnvironmentFile=-%h/.session-env
              +Type=forking
              +ExecStart=/usr/bin/tmux new-session -s use-session -d
              +ExecStop=/usr/bin/tmux kill-session -t %u
              +Restart=always
               
              -[Install]
              -WantedBy=default.target
              +[Install]
              +WantedBy=default.target
              +
              +
              +
            14. +
            15. wm-exit.service
              +
              +
              [Unit]
              +Description=exit window manager gracefully
              +
              +[Service]
              +ExecStart=/bin/true
              +ExecStop=/usr/bin/openbox --exit
              +RemainAfterExit=True
              +
              +[Install]
              +WantedBy=default.target
               
          3. -
          4. openbox
            1. autostart
              +
            2. openbox
              1. autostart
                -
                # forward environment variables to an environment file and the systemd user session
                -env | grep "DISPLAY\|DBUS_SESSION_BUS_ADDRESS\|XDG_RUNTIME_DIR" > ~/.session-env
                +
                # forward environment variables to an environment file and the systemd user session
                +env | grep "DISPLAY\|DBUS_SESSION_BUS_ADDRESS\|XDG_RUNTIME_DIR" > ~/.session-env
                 systemctl --user import-environment DISPLAY XAUTHORITY XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
                 
                -enabled_services=("tmux.service" "detect-second-display.service" "openbox-second.service" "osd2web.service")
                -disabled_services=()
                +enabled_services=(
                +    "tmux.service" "detect-second-display.service"
                +    "openbox-second.service" "osd2web.service"
                +    "yavdr-frontend.service" "pulseaudio.socket"
                +    "pulseaudio.service" "wm-exit.service")
                +disabled_services=()
                 
                -# enable configured services for the user session
                -for service in "${enabled_services[@]}"; do
                -  systemctl --user enable "$service"
                -done
                +# enable configured services for the user session
                +for service in "${enabled_services[@]}"; do
                +  systemctl --user enable "$service"
                +done
                 
                -# disable unwanted services for the user session
                -for service in "${disabled_services[@]}"; do
                -  systemctl --user disable "$service"
                -done
                +# disable unwanted services for the user session
                +for service in "${disabled_services[@]}"; do
                +  systemctl --user disable "$service"
                +done
                 
                -if which dbus-update-activation-environment >/dev/null 2>&1; then
                +if which dbus-update-activation-environment >/dev/null 2>&1; then
                         dbus-update-activation-environment DISPLAY XAUTHORITY XDG_RUNTIME_DIR
                -fi
                +fi
                 
                -# start systemd units for the yavdr user session
                +# start systemd units for the yavdr user session
                 systemctl --user isolate yavdr-desktop.target
                 
              2. -
              3. rc.xml
                +
              4. rc.xml
                -
                <?xml version="1.0" encoding="UTF-8"?>
                -<openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude">
                -<!-- Do not edit this file, it will be overwritten on install.
                -        Copy the file to $HOME/.config/openbox/ instead. -->
                -  <resistance>
                -    <strength>10</strength>
                -    <screen_edge_strength>20</screen_edge_strength>
                -  </resistance>
                -  <focus>
                -    <focusNew>yes</focusNew>
                -    <!-- always try to focus new windows when they appear. other rules do
                -       apply -->
                -    <followMouse>no</followMouse>
                -    <!-- move focus to a window when you move the mouse into it -->
                -    <focusLast>yes</focusLast>
                -    <!-- focus the last used window when changing desktops, instead of the one
                -       under the mouse pointer. when followMouse is enabled -->
                -    <underMouse>no</underMouse>
                -    <!-- move focus under the mouse, even when the mouse is not moving -->
                -    <focusDelay>200</focusDelay>
                -    <!-- when followMouse is enabled, the mouse must be inside the window for
                -       this many milliseconds (1000 = 1 sec) before moving focus to it -->
                -    <raiseOnFocus>no</raiseOnFocus>
                -    <!-- when followMouse is enabled, and a window is given focus by moving the
                -       mouse into it, also raise the window -->
                -  </focus>
                -  <placement>
                -    <policy>Smart</policy>
                -    <!-- 'Smart' or 'UnderMouse' -->
                -    <center>yes</center>
                -    <!-- whether to place windows in the center of the free area found or
                -       the top left corner -->
                -    <monitor>Active</monitor>
                -    <!-- with Smart placement on a multi-monitor system, try to place new windows
                -       on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
                -       the active window is, 'Primary' - only on the primary monitor -->
                -    <primaryMonitor>Active</primaryMonitor>
                -    <!-- The monitor where Openbox should place popup dialogs such as the
                -       focus cycling popup, or the desktop switch popup.  It can be an index
                -       from 1, specifying a particular monitor.  Or it can be one of the
                -       following: 'Mouse' - where the mouse is, or
                -                  'Active' - where the active window is -->
                -  </placement>
                -  <theme>
                -    <name>Onyx</name>
                -    <titleLayout>NLIMC</titleLayout>
                -    <!--
                -      available characters are NDSLIMC, each can occur at most once.
                -      N: window icon
                -      L: window label (AKA title).
                -      I: iconify
                -      M: maximize
                -      C: close
                -      S: shade (roll up/down)
                -      D: omnipresent (on all desktops).
                -  -->
                -    <keepBorder>yes</keepBorder>
                -    <animateIconify>yes</animateIconify>
                -    <font place="ActiveWindow">
                -      <name>sans</name>
                -      <size>8</size>
                -      <!-- font size in points -->
                -      <weight>bold</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -    <font place="InactiveWindow">
                -      <name>sans</name>
                -      <size>8</size>
                -      <!-- font size in points -->
                -      <weight>bold</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -    <font place="MenuHeader">
                -      <name>sans</name>
                -      <size>9</size>
                -      <!-- font size in points -->
                -      <weight>normal</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -    <font place="MenuItem">
                -      <name>sans</name>
                -      <size>9</size>
                -      <!-- font size in points -->
                -      <weight>normal</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -    <font place="ActiveOnScreenDisplay">
                -      <name>sans</name>
                -      <size>9</size>
                -      <!-- font size in points -->
                -      <weight>bold</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -    <font place="InactiveOnScreenDisplay">
                -      <name>sans</name>
                -      <size>9</size>
                -      <!-- font size in points -->
                -      <weight>bold</weight>
                -      <!-- 'bold' or 'normal' -->
                -      <slant>normal</slant>
                -      <!-- 'italic' or 'normal' -->
                -    </font>
                -  </theme>
                -  <desktops>
                -    <!-- this stuff is only used at startup, pagers allow you to change them
                -       during a session
                +
                <?xml version="1.0" encoding="UTF-8"?>
                +<openbox_config xmlns="http://openbox.org/3.4/rc" xmlns:xi="http://www.w3.org/2001/XInclude">
                +<!-- Do not edit this file, it will be overwritten on install.
                +        Copy the file to $HOME/.config/openbox/ instead. -->
                +  <resistance>
                +    <strength>10</strength>
                +    <screen_edge_strength>20</screen_edge_strength>
                +  </resistance>
                +  <focus>
                +    <focusNew>yes</focusNew>
                +    <!-- always try to focus new windows when they appear. other rules do
                +       apply -->
                +    <followMouse>no</followMouse>
                +    <!-- move focus to a window when you move the mouse into it -->
                +    <focusLast>yes</focusLast>
                +    <!-- focus the last used window when changing desktops, instead of the one
                +       under the mouse pointer. when followMouse is enabled -->
                +    <underMouse>no</underMouse>
                +    <!-- move focus under the mouse, even when the mouse is not moving -->
                +    <focusDelay>200</focusDelay>
                +    <!-- when followMouse is enabled, the mouse must be inside the window for
                +       this many milliseconds (1000 = 1 sec) before moving focus to it -->
                +    <raiseOnFocus>no</raiseOnFocus>
                +    <!-- when followMouse is enabled, and a window is given focus by moving the
                +       mouse into it, also raise the window -->
                +  </focus>
                +  <placement>
                +    <policy>Smart</policy>
                +    <!-- 'Smart' or 'UnderMouse' -->
                +    <center>yes</center>
                +    <!-- whether to place windows in the center of the free area found or
                +       the top left corner -->
                +    <monitor>Active</monitor>
                +    <!-- with Smart placement on a multi-monitor system, try to place new windows
                +       on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
                +       the active window is, 'Primary' - only on the primary monitor -->
                +    <primaryMonitor>Active</primaryMonitor>
                +    <!-- The monitor where Openbox should place popup dialogs such as the
                +       focus cycling popup, or the desktop switch popup.  It can be an index
                +       from 1, specifying a particular monitor.  Or it can be one of the
                +       following: 'Mouse' - where the mouse is, or
                +                  'Active' - where the active window is -->
                +  </placement>
                +  <theme>
                +    <name>Onyx</name>
                +    <titleLayout>NLIMC</titleLayout>
                +    <!--
                +      available characters are NDSLIMC, each can occur at most once.
                +      N: window icon
                +      L: window label (AKA title).
                +      I: iconify
                +      M: maximize
                +      C: close
                +      S: shade (roll up/down)
                +      D: omnipresent (on all desktops).
                +  -->
                +    <keepBorder>yes</keepBorder>
                +    <animateIconify>yes</animateIconify>
                +    <font place="ActiveWindow">
                +      <name>sans</name>
                +      <size>8</size>
                +      <!-- font size in points -->
                +      <weight>bold</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +    <font place="InactiveWindow">
                +      <name>sans</name>
                +      <size>8</size>
                +      <!-- font size in points -->
                +      <weight>bold</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +    <font place="MenuHeader">
                +      <name>sans</name>
                +      <size>9</size>
                +      <!-- font size in points -->
                +      <weight>normal</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +    <font place="MenuItem">
                +      <name>sans</name>
                +      <size>9</size>
                +      <!-- font size in points -->
                +      <weight>normal</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +    <font place="ActiveOnScreenDisplay">
                +      <name>sans</name>
                +      <size>9</size>
                +      <!-- font size in points -->
                +      <weight>bold</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +    <font place="InactiveOnScreenDisplay">
                +      <name>sans</name>
                +      <size>9</size>
                +      <!-- font size in points -->
                +      <weight>bold</weight>
                +      <!-- 'bold' or 'normal' -->
                +      <slant>normal</slant>
                +      <!-- 'italic' or 'normal' -->
                +    </font>
                +  </theme>
                +  <desktops>
                +    <!-- this stuff is only used at startup, pagers allow you to change them
                +       during a session
                 
                -       these are default values to use when other ones are not already set
                -       by other applications, or saved in your session
                +       these are default values to use when other ones are not already set
                +       by other applications, or saved in your session
                 
                -       use obconf if you want to change these without having to log out
                -       and back in -->
                -    <number>2</number>
                -    <firstdesk>1</firstdesk>
                -    <names>
                -      <!-- set names up here if you want to, like this:
                -    <name>desktop 1</name>
                -    <name>desktop 2</name>
                -    -->
                -    </names>
                -    <popupTime>875</popupTime>
                -    <!-- The number of milliseconds to show the popup for when switching
                -       desktops.  Set this to 0 to disable the popup. -->
                -  </desktops>
                -  <resize>
                -    <drawContents>yes</drawContents>
                -    <popupShow>Nonpixel</popupShow>
                -    <!-- 'Always', 'Never', or 'Nonpixel' (xterms and such) -->
                -    <popupPosition>Center</popupPosition>
                -    <!-- 'Center', 'Top', or 'Fixed' -->
                -    <popupFixedPosition>
                -      <!-- these are used if popupPosition is set to 'Fixed' -->
                -      <x>10</x>
                -      <!-- positive number for distance from left edge, negative number for
                -         distance from right edge, or 'Center' -->
                -      <y>10</y>
                -      <!-- positive number for distance from top edge, negative number for
                -         distance from bottom edge, or 'Center' -->
                -    </popupFixedPosition>
                -  </resize>
                -  <!-- You can reserve a portion of your screen where windows will not cover when
                -     they are maximized, or when they are initially placed.
                -     Many programs reserve space automatically, but you can use this in other
                -     cases. -->
                -  <margins>
                -    <top>0</top>
                -    <bottom>0</bottom>
                -    <left>0</left>
                -    <right>0</right>
                -  </margins>
                -  <dock>
                -    <position>TopLeft</position>
                -    <!-- (Top|Bottom)(Left|Right|)|Top|Bottom|Left|Right|Floating -->
                -    <floatingX>0</floatingX>
                -    <floatingY>0</floatingY>
                -    <noStrut>no</noStrut>
                -    <stacking>Above</stacking>
                -    <!-- 'Above', 'Normal', or 'Below' -->
                -    <direction>Vertical</direction>
                -    <!-- 'Vertical' or 'Horizontal' -->
                -    <autoHide>no</autoHide>
                -    <hideDelay>300</hideDelay>
                -    <!-- in milliseconds (1000 = 1 second) -->
                -    <showDelay>300</showDelay>
                -    <!-- in milliseconds (1000 = 1 second) -->
                -    <moveButton>Middle</moveButton>
                -    <!-- 'Left', 'Middle', 'Right' -->
                -  </dock>
                -  <keyboard>
                -    <chainQuitKey>C-g</chainQuitKey>
                -    <!-- Keybindings for desktop switching -->
                -    <keybind key="C-A-Left">
                -      <action name="GoToDesktop">
                -        <to>left</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="C-A-Right">
                -      <action name="GoToDesktop">
                -        <to>right</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="C-A-Up">
                -      <action name="GoToDesktop">
                -        <to>up</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="C-A-Down">
                -      <action name="GoToDesktop">
                -        <to>down</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="S-A-Left">
                -      <action name="SendToDesktop">
                -        <to>left</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="S-A-Right">
                -      <action name="SendToDesktop">
                -        <to>right</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="S-A-Up">
                -      <action name="SendToDesktop">
                -        <to>up</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="S-A-Down">
                -      <action name="SendToDesktop">
                -        <to>down</to>
                -        <wrap>no</wrap>
                -      </action>
                -    </keybind>
                -    <keybind key="W-F1">
                -      <action name="GoToDesktop">
                -        <to>1</to>
                -      </action>
                -    </keybind>
                -    <keybind key="W-F2">
                -      <action name="GoToDesktop">
                -        <to>2</to>
                -      </action>
                -    </keybind>
                -    <keybind key="W-F3">
                -      <action name="GoToDesktop">
                -        <to>3</to>
                -      </action>
                -    </keybind>
                -    <keybind key="W-F4">
                -      <action name="GoToDesktop">
                -        <to>4</to>
                -      </action>
                -    </keybind>
                -    <keybind key="W-d">
                -      <action name="ToggleShowDesktop"/>
                -    </keybind>
                -    <!-- Keybindings for windows -->
                -    <keybind key="A-F4">
                -      <action name="Close"/>
                -    </keybind>
                -    <keybind key="A-Escape">
                -      <action name="Lower"/>
                -      <action name="FocusToBottom"/>
                -      <action name="Unfocus"/>
                -    </keybind>
                -    <keybind key="A-space">
                -      <action name="ShowMenu">
                -        <menu>client-menu</menu>
                -      </action>
                -    </keybind>
                -    <!-- Take a screenshot of the current window with scrot when Alt+Print are pressed -->
                -    <keybind key="A-Print">
                -      <action name="Execute">
                -        <command>scrot -s</command>
                -      </action>
                -    </keybind>
                -    <!-- Keybindings for window switching -->
                -    <keybind key="A-Tab">
                -      <action name="NextWindow">
                -        <finalactions>
                -          <action name="Focus"/>
                -          <action name="Raise"/>
                -          <action name="Unshade"/>
                -        </finalactions>
                -      </action>
                -    </keybind>
                -    <keybind key="A-S-Tab">
                -      <action name="PreviousWindow">
                -        <finalactions>
                -          <action name="Focus"/>
                -          <action name="Raise"/>
                -          <action name="Unshade"/>
                -        </finalactions>
                -      </action>
                -    </keybind>
                -    <keybind key="C-A-Tab">
                -      <action name="NextWindow">
                -        <panels>yes</panels>
                -        <desktop>yes</desktop>
                -        <finalactions>
                -          <action name="Focus"/>
                -          <action name="Raise"/>
                -          <action name="Unshade"/>
                -        </finalactions>
                -      </action>
                -    </keybind>
                -    <!-- Keybindings for window switching with the arrow keys -->
                -    <keybind key="W-S-Right">
                -      <action name="DirectionalCycleWindows">
                -        <direction>right</direction>
                -      </action>
                -    </keybind>
                -    <keybind key="W-S-Left">
                -      <action name="DirectionalCycleWindows">
                -        <direction>left</direction>
                -      </action>
                -    </keybind>
                -    <keybind key="W-S-Up">
                -      <action name="DirectionalCycleWindows">
                -        <direction>up</direction>
                -      </action>
                -    </keybind>
                -    <keybind key="W-S-Down">
                -      <action name="DirectionalCycleWindows">
                -        <direction>down</direction>
                -      </action>
                -    </keybind>
                -    <!-- Keybindings for running applications -->
                -    <keybind key="W-e">
                -      <action name="Execute">
                -        <startupnotify>
                -          <enabled>true</enabled>
                -          <name>Konqueror</name>
                -        </startupnotify>
                -        <command>kfmclient openProfile filemanagement</command>
                -      </action>
                -    </keybind>
                -    <!-- Launch scrot when Print is pressed -->
                -    <keybind key="Print">
                -      <action name="Execute">
                -        <command>scrot</command>
                -      </action>
                -    </keybind>
                -  </keyboard>
                -  <mouse>
                -    <dragThreshold>1</dragThreshold>
                -    <!-- number of pixels the mouse must move before a drag begins -->
                -    <doubleClickTime>500</doubleClickTime>
                -    <!-- in milliseconds (1000 = 1 second) -->
                -    <screenEdgeWarpTime>400</screenEdgeWarpTime>
                -    <!-- Time before changing desktops when the pointer touches the edge of the
                -       screen while moving a window, in milliseconds (1000 = 1 second).
                -       Set this to 0 to disable warping -->
                -    <screenEdgeWarpMouse>false</screenEdgeWarpMouse>
                -    <!-- Set this to TRUE to move the mouse pointer across the desktop when
                -       switching due to hitting the edge of the screen -->
                -    <context name="Frame">
                -      <mousebind button="A-Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="A-Left" action="Click">
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="A-Left" action="Drag">
                -        <action name="Move"/>
                -      </mousebind>
                -      <mousebind button="A-Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="A-Right" action="Drag">
                -        <action name="Resize"/>
                -      </mousebind>
                -      <mousebind button="A-Middle" action="Press">
                -        <action name="Lower"/>
                -        <action name="FocusToBottom"/>
                -        <action name="Unfocus"/>
                -      </mousebind>
                -      <mousebind button="A-Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="C-A-Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="C-A-Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-S-Up" action="Click">
                -        <action name="SendToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-S-Down" action="Click">
                -        <action name="SendToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Titlebar">
                -      <mousebind button="Left" action="Drag">
                -        <action name="Move"/>
                -      </mousebind>
                -      <mousebind button="Left" action="DoubleClick">
                -        <action name="ToggleMaximize"/>
                -      </mousebind>
                -      <mousebind button="Up" action="Click">
                -        <action name="if">
                -          <shaded>no</shaded>
                -          <then>
                -            <action name="Shade"/>
                -            <action name="FocusToBottom"/>
                -            <action name="Unfocus"/>
                -            <action name="Lower"/>
                -          </then>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Down" action="Click">
                -        <action name="if">
                -          <shaded>yes</shaded>
                -          <then>
                -            <action name="Unshade"/>
                -            <action name="Raise"/>
                -          </then>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Titlebar Top Right Bottom Left TLCorner TRCorner BRCorner BLCorner">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Middle" action="Press">
                -        <action name="Lower"/>
                -        <action name="FocusToBottom"/>
                -        <action name="Unfocus"/>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="ShowMenu">
                -          <menu>client-menu</menu>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Top">
                -      <mousebind button="Left" action="Drag">
                -        <action name="Resize">
                -          <edge>top</edge>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Left">
                -      <mousebind button="Left" action="Drag">
                -        <action name="Resize">
                -          <edge>left</edge>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Right">
                -      <mousebind button="Left" action="Drag">
                -        <action name="Resize">
                -          <edge>right</edge>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Bottom">
                -      <mousebind button="Left" action="Drag">
                -        <action name="Resize">
                -          <edge>bottom</edge>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="ShowMenu">
                -          <menu>client-menu</menu>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="TRCorner BRCorner TLCorner BLCorner">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Drag">
                -        <action name="Resize"/>
                -      </mousebind>
                -    </context>
                -    <context name="Client">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="Middle" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -    </context>
                -    <context name="Icon">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -        <action name="ShowMenu">
                -          <menu>client-menu</menu>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="ShowMenu">
                -          <menu>client-menu</menu>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="AllDesktops">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Click">
                -        <action name="ToggleOmnipresent"/>
                -      </mousebind>
                -    </context>
                -    <context name="Shade">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Click">
                -        <action name="ToggleShade"/>
                -      </mousebind>
                -    </context>
                -    <context name="Iconify">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Click">
                -        <action name="Iconify"/>
                -      </mousebind>
                -    </context>
                -    <context name="Maximize">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Middle" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Click">
                -        <action name="ToggleMaximize"/>
                -      </mousebind>
                -      <mousebind button="Middle" action="Click">
                -        <action name="ToggleMaximize">
                -          <direction>vertical</direction>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Right" action="Click">
                -        <action name="ToggleMaximize">
                -          <direction>horizontal</direction>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="Close">
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -        <action name="Unshade"/>
                -      </mousebind>
                -      <mousebind button="Left" action="Click">
                -        <action name="Close"/>
                -      </mousebind>
                -    </context>
                -    <context name="Desktop">
                -      <mousebind button="Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="C-A-Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="C-A-Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Left" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="Focus"/>
                -        <action name="Raise"/>
                -      </mousebind>
                -    </context>
                -    <context name="Root">
                -      <!-- Menus -->
                -      <mousebind button="Middle" action="Press">
                -        <action name="ShowMenu">
                -          <menu>client-list-combined-menu</menu>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Right" action="Press">
                -        <action name="ShowMenu">
                -          <menu>root-menu</menu>
                -        </action>
                -      </mousebind>
                -    </context>
                -    <context name="MoveResize">
                -      <mousebind button="Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-Up" action="Click">
                -        <action name="GoToDesktop">
                -          <to>previous</to>
                -        </action>
                -      </mousebind>
                -      <mousebind button="A-Down" action="Click">
                -        <action name="GoToDesktop">
                -          <to>next</to>
                -        </action>
                -      </mousebind>
                -    </context>
                -  </mouse>
                -  <menu>
                -    <!-- You can specify more than one menu file in here and they are all loaded,
                -       just don't make menu ids clash or, well, it'll be kind of pointless -->
                -    <!-- default menu file (or custom one in $HOME/.config/openbox/) -->
                -    <!-- system menu files on Debian systems -->
                -    <file>/var/lib/openbox/debian-menu.xml</file>
                -    <file>menu.xml</file>
                -    <hideDelay>200</hideDelay>
                -    <!-- if a press-release lasts longer than this setting (in milliseconds), the
                -       menu is hidden again -->
                -    <middle>no</middle>
                -    <!-- center submenus vertically about the parent entry -->
                -    <submenuShowDelay>100</submenuShowDelay>
                -    <!-- time to delay before showing a submenu after hovering over the parent
                -       entry.
                -       if this is a negative value, then the delay is infinite and the
                -       submenu will not be shown until it is clicked on -->
                -    <submenuHideDelay>400</submenuHideDelay>
                -    <!-- time to delay before hiding a submenu when selecting another
                -       entry in parent menu
                -       if this is a negative value, then the delay is infinite and the
                -       submenu will not be hidden until a different submenu is opened -->
                -    <showIcons>yes</showIcons>
                -    <!-- controls if icons appear in the client-list-(combined-)menu -->
                -    <manageDesktops>yes</manageDesktops>
                -    <!-- show the manage desktops section in the client-list-(combined-)menu -->
                -  </menu>
                -    <!--
                -  # this is an example with comments through out. use these to make your
                -  # own rules, but without the comments of course.
                -  # you may use one or more of the name/class/role/title/type rules to specify
                -  # windows to match
                +       use obconf if you want to change these without having to log out
                +       and back in -->
                +    <number>2</number>
                +    <firstdesk>1</firstdesk>
                +    <names>
                +      <!-- set names up here if you want to, like this:
                +    <name>desktop 1</name>
                +    <name>desktop 2</name>
                +    -->
                +    </names>
                +    <popupTime>875</popupTime>
                +    <!-- The number of milliseconds to show the popup for when switching
                +       desktops.  Set this to 0 to disable the popup. -->
                +  </desktops>
                +  <resize>
                +    <drawContents>yes</drawContents>
                +    <popupShow>Nonpixel</popupShow>
                +    <!-- 'Always', 'Never', or 'Nonpixel' (xterms and such) -->
                +    <popupPosition>Center</popupPosition>
                +    <!-- 'Center', 'Top', or 'Fixed' -->
                +    <popupFixedPosition>
                +      <!-- these are used if popupPosition is set to 'Fixed' -->
                +      <x>10</x>
                +      <!-- positive number for distance from left edge, negative number for
                +         distance from right edge, or 'Center' -->
                +      <y>10</y>
                +      <!-- positive number for distance from top edge, negative number for
                +         distance from bottom edge, or 'Center' -->
                +    </popupFixedPosition>
                +  </resize>
                +  <!-- You can reserve a portion of your screen where windows will not cover when
                +     they are maximized, or when they are initially placed.
                +     Many programs reserve space automatically, but you can use this in other
                +     cases. -->
                +  <margins>
                +    <top>0</top>
                +    <bottom>0</bottom>
                +    <left>0</left>
                +    <right>0</right>
                +  </margins>
                +  <dock>
                +    <position>TopLeft</position>
                +    <!-- (Top|Bottom)(Left|Right|)|Top|Bottom|Left|Right|Floating -->
                +    <floatingX>0</floatingX>
                +    <floatingY>0</floatingY>
                +    <noStrut>no</noStrut>
                +    <stacking>Above</stacking>
                +    <!-- 'Above', 'Normal', or 'Below' -->
                +    <direction>Vertical</direction>
                +    <!-- 'Vertical' or 'Horizontal' -->
                +    <autoHide>no</autoHide>
                +    <hideDelay>300</hideDelay>
                +    <!-- in milliseconds (1000 = 1 second) -->
                +    <showDelay>300</showDelay>
                +    <!-- in milliseconds (1000 = 1 second) -->
                +    <moveButton>Middle</moveButton>
                +    <!-- 'Left', 'Middle', 'Right' -->
                +  </dock>
                +  <keyboard>
                +    <chainQuitKey>C-g</chainQuitKey>
                +    <!-- Keybindings for desktop switching -->
                +    <keybind key="C-A-Left">
                +      <action name="GoToDesktop">
                +        <to>left</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="C-A-Right">
                +      <action name="GoToDesktop">
                +        <to>right</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="C-A-Up">
                +      <action name="GoToDesktop">
                +        <to>up</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="C-A-Down">
                +      <action name="GoToDesktop">
                +        <to>down</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="S-A-Left">
                +      <action name="SendToDesktop">
                +        <to>left</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="S-A-Right">
                +      <action name="SendToDesktop">
                +        <to>right</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="S-A-Up">
                +      <action name="SendToDesktop">
                +        <to>up</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="S-A-Down">
                +      <action name="SendToDesktop">
                +        <to>down</to>
                +        <wrap>no</wrap>
                +      </action>
                +    </keybind>
                +    <keybind key="W-F1">
                +      <action name="GoToDesktop">
                +        <to>1</to>
                +      </action>
                +    </keybind>
                +    <keybind key="W-F2">
                +      <action name="GoToDesktop">
                +        <to>2</to>
                +      </action>
                +    </keybind>
                +    <keybind key="W-F3">
                +      <action name="GoToDesktop">
                +        <to>3</to>
                +      </action>
                +    </keybind>
                +    <keybind key="W-F4">
                +      <action name="GoToDesktop">
                +        <to>4</to>
                +      </action>
                +    </keybind>
                +    <keybind key="W-d">
                +      <action name="ToggleShowDesktop"/>
                +    </keybind>
                +    <!-- Keybindings for windows -->
                +    <keybind key="A-F4">
                +      <action name="Close"/>
                +    </keybind>
                +    <keybind key="A-Escape">
                +      <action name="Lower"/>
                +      <action name="FocusToBottom"/>
                +      <action name="Unfocus"/>
                +    </keybind>
                +    <keybind key="A-space">
                +      <action name="ShowMenu">
                +        <menu>client-menu</menu>
                +      </action>
                +    </keybind>
                +    <!-- Take a screenshot of the current window with scrot when Alt+Print are pressed -->
                +    <keybind key="A-Print">
                +      <action name="Execute">
                +        <command>scrot -s</command>
                +      </action>
                +    </keybind>
                +    <!-- Keybindings for window switching -->
                +    <keybind key="A-Tab">
                +      <action name="NextWindow">
                +        <finalactions>
                +          <action name="Focus"/>
                +          <action name="Raise"/>
                +          <action name="Unshade"/>
                +        </finalactions>
                +      </action>
                +    </keybind>
                +    <keybind key="A-S-Tab">
                +      <action name="PreviousWindow">
                +        <finalactions>
                +          <action name="Focus"/>
                +          <action name="Raise"/>
                +          <action name="Unshade"/>
                +        </finalactions>
                +      </action>
                +    </keybind>
                +    <keybind key="C-A-Tab">
                +      <action name="NextWindow">
                +        <panels>yes</panels>
                +        <desktop>yes</desktop>
                +        <finalactions>
                +          <action name="Focus"/>
                +          <action name="Raise"/>
                +          <action name="Unshade"/>
                +        </finalactions>
                +      </action>
                +    </keybind>
                +    <!-- Keybindings for window switching with the arrow keys -->
                +    <keybind key="W-S-Right">
                +      <action name="DirectionalCycleWindows">
                +        <direction>right</direction>
                +      </action>
                +    </keybind>
                +    <keybind key="W-S-Left">
                +      <action name="DirectionalCycleWindows">
                +        <direction>left</direction>
                +      </action>
                +    </keybind>
                +    <keybind key="W-S-Up">
                +      <action name="DirectionalCycleWindows">
                +        <direction>up</direction>
                +      </action>
                +    </keybind>
                +    <keybind key="W-S-Down">
                +      <action name="DirectionalCycleWindows">
                +        <direction>down</direction>
                +      </action>
                +    </keybind>
                +    <!-- Keybindings for running applications -->
                +    <keybind key="W-e">
                +      <action name="Execute">
                +        <startupnotify>
                +          <enabled>true</enabled>
                +          <name>Konqueror</name>
                +        </startupnotify>
                +        <command>kfmclient openProfile filemanagement</command>
                +      </action>
                +    </keybind>
                +    <!-- Launch scrot when Print is pressed -->
                +    <keybind key="Print">
                +      <action name="Execute">
                +        <command>scrot</command>
                +      </action>
                +    </keybind>
                +  </keyboard>
                +  <mouse>
                +    <dragThreshold>1</dragThreshold>
                +    <!-- number of pixels the mouse must move before a drag begins -->
                +    <doubleClickTime>500</doubleClickTime>
                +    <!-- in milliseconds (1000 = 1 second) -->
                +    <screenEdgeWarpTime>400</screenEdgeWarpTime>
                +    <!-- Time before changing desktops when the pointer touches the edge of the
                +       screen while moving a window, in milliseconds (1000 = 1 second).
                +       Set this to 0 to disable warping -->
                +    <screenEdgeWarpMouse>false</screenEdgeWarpMouse>
                +    <!-- Set this to TRUE to move the mouse pointer across the desktop when
                +       switching due to hitting the edge of the screen -->
                +    <context name="Frame">
                +      <mousebind button="A-Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="A-Left" action="Click">
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="A-Left" action="Drag">
                +        <action name="Move"/>
                +      </mousebind>
                +      <mousebind button="A-Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="A-Right" action="Drag">
                +        <action name="Resize"/>
                +      </mousebind>
                +      <mousebind button="A-Middle" action="Press">
                +        <action name="Lower"/>
                +        <action name="FocusToBottom"/>
                +        <action name="Unfocus"/>
                +      </mousebind>
                +      <mousebind button="A-Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="C-A-Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="C-A-Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-S-Up" action="Click">
                +        <action name="SendToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-S-Down" action="Click">
                +        <action name="SendToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Titlebar">
                +      <mousebind button="Left" action="Drag">
                +        <action name="Move"/>
                +      </mousebind>
                +      <mousebind button="Left" action="DoubleClick">
                +        <action name="ToggleMaximize"/>
                +      </mousebind>
                +      <mousebind button="Up" action="Click">
                +        <action name="if">
                +          <shaded>no</shaded>
                +          <then>
                +            <action name="Shade"/>
                +            <action name="FocusToBottom"/>
                +            <action name="Unfocus"/>
                +            <action name="Lower"/>
                +          </then>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Down" action="Click">
                +        <action name="if">
                +          <shaded>yes</shaded>
                +          <then>
                +            <action name="Unshade"/>
                +            <action name="Raise"/>
                +          </then>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Titlebar Top Right Bottom Left TLCorner TRCorner BRCorner BLCorner">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Middle" action="Press">
                +        <action name="Lower"/>
                +        <action name="FocusToBottom"/>
                +        <action name="Unfocus"/>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="ShowMenu">
                +          <menu>client-menu</menu>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Top">
                +      <mousebind button="Left" action="Drag">
                +        <action name="Resize">
                +          <edge>top</edge>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Left">
                +      <mousebind button="Left" action="Drag">
                +        <action name="Resize">
                +          <edge>left</edge>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Right">
                +      <mousebind button="Left" action="Drag">
                +        <action name="Resize">
                +          <edge>right</edge>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Bottom">
                +      <mousebind button="Left" action="Drag">
                +        <action name="Resize">
                +          <edge>bottom</edge>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="ShowMenu">
                +          <menu>client-menu</menu>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="TRCorner BRCorner TLCorner BLCorner">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Drag">
                +        <action name="Resize"/>
                +      </mousebind>
                +    </context>
                +    <context name="Client">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="Middle" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +    </context>
                +    <context name="Icon">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +        <action name="ShowMenu">
                +          <menu>client-menu</menu>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="ShowMenu">
                +          <menu>client-menu</menu>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="AllDesktops">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Click">
                +        <action name="ToggleOmnipresent"/>
                +      </mousebind>
                +    </context>
                +    <context name="Shade">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Click">
                +        <action name="ToggleShade"/>
                +      </mousebind>
                +    </context>
                +    <context name="Iconify">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Click">
                +        <action name="Iconify"/>
                +      </mousebind>
                +    </context>
                +    <context name="Maximize">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Middle" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Click">
                +        <action name="ToggleMaximize"/>
                +      </mousebind>
                +      <mousebind button="Middle" action="Click">
                +        <action name="ToggleMaximize">
                +          <direction>vertical</direction>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Right" action="Click">
                +        <action name="ToggleMaximize">
                +          <direction>horizontal</direction>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="Close">
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +        <action name="Unshade"/>
                +      </mousebind>
                +      <mousebind button="Left" action="Click">
                +        <action name="Close"/>
                +      </mousebind>
                +    </context>
                +    <context name="Desktop">
                +      <mousebind button="Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="C-A-Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="C-A-Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Left" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="Focus"/>
                +        <action name="Raise"/>
                +      </mousebind>
                +    </context>
                +    <context name="Root">
                +      <!-- Menus -->
                +      <mousebind button="Middle" action="Press">
                +        <action name="ShowMenu">
                +          <menu>client-list-combined-menu</menu>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Right" action="Press">
                +        <action name="ShowMenu">
                +          <menu>root-menu</menu>
                +        </action>
                +      </mousebind>
                +    </context>
                +    <context name="MoveResize">
                +      <mousebind button="Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-Up" action="Click">
                +        <action name="GoToDesktop">
                +          <to>previous</to>
                +        </action>
                +      </mousebind>
                +      <mousebind button="A-Down" action="Click">
                +        <action name="GoToDesktop">
                +          <to>next</to>
                +        </action>
                +      </mousebind>
                +    </context>
                +  </mouse>
                +  <menu>
                +    <!-- You can specify more than one menu file in here and they are all loaded,
                +       just don't make menu ids clash or, well, it'll be kind of pointless -->
                +    <!-- default menu file (or custom one in $HOME/.config/openbox/) -->
                +    <!-- system menu files on Debian systems -->
                +    <file>/var/lib/openbox/debian-menu.xml</file>
                +    <file>menu.xml</file>
                +    <hideDelay>200</hideDelay>
                +    <!-- if a press-release lasts longer than this setting (in milliseconds), the
                +       menu is hidden again -->
                +    <middle>no</middle>
                +    <!-- center submenus vertically about the parent entry -->
                +    <submenuShowDelay>100</submenuShowDelay>
                +    <!-- time to delay before showing a submenu after hovering over the parent
                +       entry.
                +       if this is a negative value, then the delay is infinite and the
                +       submenu will not be shown until it is clicked on -->
                +    <submenuHideDelay>400</submenuHideDelay>
                +    <!-- time to delay before hiding a submenu when selecting another
                +       entry in parent menu
                +       if this is a negative value, then the delay is infinite and the
                +       submenu will not be hidden until a different submenu is opened -->
                +    <showIcons>yes</showIcons>
                +    <!-- controls if icons appear in the client-list-(combined-)menu -->
                +    <manageDesktops>yes</manageDesktops>
                +    <!-- show the manage desktops section in the client-list-(combined-)menu -->
                +  </menu>
                +    <!--
                +  # this is an example with comments through out. use these to make your
                +  # own rules, but without the comments of course.
                +  # you may use one or more of the name/class/role/title/type rules to specify
                +  # windows to match
                 
                -  <application name="the window's _OB_APP_NAME property (see obxprop)"
                -              class="the window's _OB_APP_CLASS property (see obxprop)"
                -          groupname="the window's _OB_APP_GROUP_NAME property (see obxprop)"
                -         groupclass="the window's _OB_APP_GROUP_CLASS property (see obxprop)"
                -               role="the window's _OB_APP_ROLE property (see obxprop)"
                -              title="the window's _OB_APP_TITLE property (see obxprop)"
                -               type="the window's _OB_APP_TYPE property (see obxprob)..
                -                      (if unspecified, then it is 'dialog' for child windows)">
                -  # you may set only one of name/class/role/title/type, or you may use more
                -  # than one together to restrict your matches.
                +  <application name="the window's _OB_APP_NAME property (see obxprop)"
                +              class="the window's _OB_APP_CLASS property (see obxprop)"
                +          groupname="the window's _OB_APP_GROUP_NAME property (see obxprop)"
                +         groupclass="the window's _OB_APP_GROUP_CLASS property (see obxprop)"
                +               role="the window's _OB_APP_ROLE property (see obxprop)"
                +              title="the window's _OB_APP_TITLE property (see obxprop)"
                +               type="the window's _OB_APP_TYPE property (see obxprob)..
                +                      (if unspecified, then it is 'dialog' for child windows)">
                +  # you may set only one of name/class/role/title/type, or you may use more
                +  # than one together to restrict your matches.
                 
                -  # the name, class, role, and title use simple wildcard matching such as those
                -  # used by a shell. you can use * to match any characters and ? to match
                -  # any single character.
                +  # the name, class, role, and title use simple wildcard matching such as those
                +  # used by a shell. you can use * to match any characters and ? to match
                +  # any single character.
                 
                -  # the type is one of: normal, dialog, splash, utility, menu, toolbar, dock,
                -  #    or desktop
                +  # the type is one of: normal, dialog, splash, utility, menu, toolbar, dock,
                +  #    or desktop
                 
                -  # when multiple rules match a window, they will all be applied, in the
                -  # order that they appear in this list
                +  # when multiple rules match a window, they will all be applied, in the
                +  # order that they appear in this list
                 
                 
                -    # each rule element can be left out or set to 'default' to specify to not 
                -    # change that attribute of the window
                +    # each rule element can be left out or set to 'default' to specify to not 
                +    # change that attribute of the window
                 
                -    <decor>yes</decor>
                -    # enable or disable window decorations
                +    <decor>yes</decor>
                +    # enable or disable window decorations
                 
                -    <shade>no</shade>
                -    # make the window shaded when it appears, or not
                +    <shade>no</shade>
                +    # make the window shaded when it appears, or not
                 
                -    <position force="no">
                -      # the position is only used if both an x and y coordinate are provided
                -      # (and not set to 'default')
                -      # when force is "yes", then the window will be placed here even if it
                -      # says you want it placed elsewhere.  this is to override buggy
                -      # applications who refuse to behave
                -      <x>center</x>
                -      # a number like 50, or 'center' to center on screen. use a negative number
                -      # to start from the right (or bottom for <y>), ie -50 is 50 pixels from
                -      # the right edge (or bottom). use 'default' to specify using value
                -      # provided by the application, or chosen by openbox, instead.
                -      <y>200</y>
                -      <monitor>1</monitor>
                -      # specifies the monitor in a xinerama setup.
                -      # 1 is the first head, or 'mouse' for wherever the mouse is
                -    </position>
                +    <position force="no">
                +      # the position is only used if both an x and y coordinate are provided
                +      # (and not set to 'default')
                +      # when force is "yes", then the window will be placed here even if it
                +      # says you want it placed elsewhere.  this is to override buggy
                +      # applications who refuse to behave
                +      <x>center</x>
                +      # a number like 50, or 'center' to center on screen. use a negative number
                +      # to start from the right (or bottom for <y>), ie -50 is 50 pixels from
                +      # the right edge (or bottom). use 'default' to specify using value
                +      # provided by the application, or chosen by openbox, instead.
                +      <y>200</y>
                +      <monitor>1</monitor>
                +      # specifies the monitor in a xinerama setup.
                +      # 1 is the first head, or 'mouse' for wherever the mouse is
                +    </position>
                 
                -    <size>
                -      # the size to make the window.
                -      <width>20</width>
                -      # a number like 20, or 'default' to use the size given by the application.
                -      # you can use fractions such as 1/2 or percentages such as 75% in which
                -      # case the value is relative to the size of the monitor that the window
                -      # appears on.
                -      <height>30%</height>
                -    </size>
                +    <size>
                +      # the size to make the window.
                +      <width>20</width>
                +      # a number like 20, or 'default' to use the size given by the application.
                +      # you can use fractions such as 1/2 or percentages such as 75% in which
                +      # case the value is relative to the size of the monitor that the window
                +      # appears on.
                +      <height>30%</height>
                +    </size>
                 
                -    <focus>yes</focus>
                -    # if the window should try be given focus when it appears. if this is set
                -    # to yes it doesn't guarantee the window will be given focus. some
                -    # restrictions may apply, but Openbox will try to
                +    <focus>yes</focus>
                +    # if the window should try be given focus when it appears. if this is set
                +    # to yes it doesn't guarantee the window will be given focus. some
                +    # restrictions may apply, but Openbox will try to
                 
                -    <desktop>1</desktop>
                -    # 1 is the first desktop, 'all' for all desktops
                +    <desktop>1</desktop>
                +    # 1 is the first desktop, 'all' for all desktops
                 
                -    <layer>normal</layer>
                -    # 'above', 'normal', or 'below'
                +    <layer>normal</layer>
                +    # 'above', 'normal', or 'below'
                 
                -    <iconic>no</iconic>
                -    # make the window iconified when it appears, or not
                +    <iconic>no</iconic>
                +    # make the window iconified when it appears, or not
                 
                -    <skip_pager>no</skip_pager>
                -    # asks to not be shown in pagers
                +    <skip_pager>no</skip_pager>
                +    # asks to not be shown in pagers
                 
                -    <skip_taskbar>no</skip_taskbar>
                -    # asks to not be shown in taskbars. window cycling actions will also
                -    # skip past such windows
                +    <skip_taskbar>no</skip_taskbar>
                +    # asks to not be shown in taskbars. window cycling actions will also
                +    # skip past such windows
                 
                -    <fullscreen>yes</fullscreen>
                -    # make the window in fullscreen mode when it appears
                +    <fullscreen>yes</fullscreen>
                +    # make the window in fullscreen mode when it appears
                 
                -    <maximized>true</maximized>
                -    # 'Horizontal', 'Vertical' or boolean (yes/no)
                -  </application>
                +    <maximized>true</maximized>
                +    # 'Horizontal', 'Vertical' or boolean (yes/no)
                +  </application>
                 
                -  # end of the example
                --->
                -  <applications>
                -    <application title="softhddevice">
                -      <decor>no</decor>
                -      <maximized>true</maximized>
                -      <!--<skip_pager>yes</skip_pager>-->
                -      <skip_taskbar>no</skip_taskbar>
                -    </application>
                -    <application title="browser">
                -      <decor>no</decor>
                -      <maximized>true</maximized>
                -      <!--<skip_pager>yes</skip_pager>-->
                -      <skip_taskbar>yes</skip_taskbar>
                -    </application>
                -    <application title="osd2Web">
                -      <decor>no</decor>
                -      <maximized>true</maximized>
                -      <!--<skip_pager>yes</skip_pager>-->
                -      <skip_taskbar>yes</skip_taskbar>
                -    </application>
                -  </applications>
                -</openbox_config>
                +  # end of the example
                +-->
                +  <applications>
                +    <application title="softhddevice">
                +      <decor>no</decor>
                +      <maximized>true</maximized>
                +      <!--<skip_pager>yes</skip_pager>-->
                +      <skip_taskbar>no</skip_taskbar>
                +    </application>
                +    <application title="browser">
                +      <decor>no</decor>
                +      <maximized>true</maximized>
                +      <!--<skip_pager>yes</skip_pager>-->
                +      <skip_taskbar>yes</skip_taskbar>
                +    </application>
                +    <application title="osd2Web">
                +      <decor>no</decor>
                +      <maximized>true</maximized>
                +      <!--<skip_pager>yes</skip_pager>-->
                +      <skip_taskbar>yes</skip_taskbar>
                +    </application>
                +  </applications>
                +</openbox_config>
                 
                 
                @@ -3578,22 +3330,22 @@ systemctl --user isolate yavdr-desktop.target
    -
    -

    8.10 samba-install

    +
    +

    8.10 samba-install

    -
    -

    8.10.1 tasks

    +
    +

    8.10.1 tasks

    -
    ---
    -# file: roles/samba-install/tasks/main.yml
    +
    ---
    +# file: roles/samba-install/tasks/main.yml
     
    -- name: install samba server
    -  apt:
    -    name: '{{ item }}'
    -    state: present
    -    install_recommends: no
    -  with_items:
    +- name: install samba server
    +  apt:
    +    name: '{{ item }}'
    +    state: present
    +    install_recommends: no
    +  with_items:
         - samba
         - samba-common
         - samba-common-bin
    @@ -3604,115 +3356,115 @@ systemctl --user isolate yavdr-desktop.target
     
    -
    -

    8.11 samba-config

    +
    +

    8.11 samba-config

    -
    -

    8.11.1 tasks

    +
    +

    8.11.1 tasks

    -
    ---
    -# file: roles/samba-config/tasks/main.yml
    +
    ---
    +# file: roles/samba-config/tasks/main.yml
     
    -# TODO:
    -# - name: divert original smbd.conf
    +# TODO:
    +# - name: divert original smbd.conf
     
    -- name: touch smb.conf.custom
    -  file:
    -    state: touch
    -    dest: '/etc/samba/smb.conf.custom'
    -  notify: [ 'Restart Samba' ]
    +- name: touch smb.conf.custom
    +  file:
    +    state: touch
    +    dest: '/etc/samba/smb.conf.custom'
    +  notify: [ 'Restart Samba' ]
         
    -- name: expand template for smb.conf
    -  template:
    -    src: 'templates/smb.conf.j2'
    -    dest: '/etc/samba/smb.conf'
    -    #validate: 'testparm -s %s'
    -  notify: [ 'Restart Samba' ]
    +- name: expand template for smb.conf
    +  template:
    +    src: 'templates/smb.conf.j2'
    +    dest: '/etc/samba/smb.conf'
    +    #validate: 'testparm -s %s'
    +  notify: [ 'Restart Samba' ]
     
    -
    -

    8.11.2 templates

    +
    +

    8.11.2 templates

    -
    1. smb.conf
      1. global settings
        +
        1. smb.conf
          1. global settings
            {{ ansible_managed_file | comment }}
             
            -#======================= Global Settings =======================
            +#======================= Global Settings =======================
             
             [global]
             
            -## Browsing/Identification ###
            +## Browsing/Identification ###
             
            -# Change this to the workgroup/NT-domain name your Samba server will part of
            +# Change this to the workgroup/NT-domain name your Samba server will part of
                workgroup = {{ samba.workgroup }}
             
            -# server string is the equivalent of the NT Description field
            +# server string is the equivalent of the NT Description field
                server string = %h server (Samba, Ubuntu)
             
            -# This will prevent nmbd to search for NetBIOS names through DNS.
            +# This will prevent nmbd to search for NetBIOS names through DNS.
                dns proxy = no
             
            -#### Debugging/Accounting ####
            +#### Debugging/Accounting ####
             
            -# This tells Samba to use a separate log file for each machine
            -# that connects
            +# This tells Samba to use a separate log file for each machine
            +# that connects
                log file = /var/log/samba/log.%m
             
            -# Cap the size of the individual log files (in KiB).
            +# Cap the size of the individual log files (in KiB).
                max log size = 1000
             
            -# We want Samba to log a minimum amount of information to syslog. Everything
            -# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
            -# through syslog you should set the following parameter to something higher.
            +# We want Samba to log a minimum amount of information to syslog. Everything
            +# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
            +# through syslog you should set the following parameter to something higher.
                syslog = 0
             
            -# Do something sensible when Samba crashes: mail the admin a backtrace
            +# Do something sensible when Samba crashes: mail the admin a backtrace
                panic action = /usr/share/samba/panic-action %d
             
             
            -####### Authentication #######
            +####### Authentication #######
             
            -# "security = user" is always a good idea. This will require a Unix account
            -# in this server for every user accessing the server. See
            -# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
            -# in the samba-doc package for details.
            -#   security = user
            +# "security = user" is always a good idea. This will require a Unix account
            +# in this server for every user accessing the server. See
            +# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
            +# in the samba-doc package for details.
            +#   security = user
             
            -# You may wish to use password encryption.  See the section on
            -# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
            +# You may wish to use password encryption.  See the section on
            +# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
                encrypt passwords = true
             
            -# If you are using encrypted passwords, Samba will need to know what
            -# password database type you are using.  
            +# If you are using encrypted passwords, Samba will need to know what
            +# password database type you are using.  
                passdb backend = tdbsam
             
                obey pam restrictions = yes
             
            -# This boolean parameter controls whether Samba attempts to sync the Unix
            -# password with the SMB password when the encrypted SMB password in the
            -# passdb is changed.
            +# This boolean parameter controls whether Samba attempts to sync the Unix
            +# password with the SMB password when the encrypted SMB password in the
            +# passdb is changed.
                unix password sync = yes
             
            -# For Unix password sync to work on a Debian GNU/Linux system, the following
            -# parameters must be set (thanks to Ian Kahan <<kahan@informatik.tu-muenchen.de> for
            -# sending the correct chat script for the passwd program in Debian Sarge).
            +# For Unix password sync to work on a Debian GNU/Linux system, the following
            +# parameters must be set (thanks to Ian Kahan <<kahan@informatik.tu-muenchen.de> for
            +# sending the correct chat script for the passwd program in Debian Sarge).
                passwd program = /usr/bin/passwd %u
            -   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
            +   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
             
            -# This boolean controls whether PAM will be used for password changes
            -# when requested by an SMB client instead of the program listed in
            -# 'passwd program'. The default is 'no'.
            +# This boolean controls whether PAM will be used for password changes
            +# when requested by an SMB client instead of the program listed in
            +# 'passwd program'. The default is 'no'.
                pam password change = yes
             
            -# This option controls how unsuccessful authentication attempts are mapped 
            -# to anonymous connections
            +# This option controls how unsuccessful authentication attempts are mapped 
            +# to anonymous connections
                map to guest = bad user
             
             {% if samba.windows_compatible %}
            -# disable unix extensions and enable following symlinks
            +# disable unix extensions and enable following symlinks
                unix extensions = no
                follow symlinks= yes
                wide links= yes
            @@ -3720,7 +3472,7 @@ systemctl --user isolate yavdr-desktop.target
             
          2. -
          3. media directories
            +
          4. media directories
            {% for name, path in media_dirs.iteritems() %}
             [{{ name }}]
            @@ -3740,7 +3492,7 @@ systemctl --user isolate yavdr-desktop.target
             
          5. -
          6. include custom samba exports
            +
          7. include custom samba exports
            include = /etc/samba/smb.conf.custom
             
            @@ -3748,15 +3500,15 @@ systemctl --user isolate yavdr-desktop.target
    -
    -

    8.12 STARTED autoinstall-drivers

    +
    +

    8.12 STARTED autoinstall-drivers

    It would be nice to be able to detect if it is suitable to install those drivers:

    -
    -

    8.12.1 TODO sundtek for Sundtek devices (local or network connection)

    +
    +

    8.12.1 TODO sundtek for Sundtek devices (local or network connection)

    Vendor-IDs: @@ -3767,14 +3519,14 @@ Vendor-IDs:

    -
    -

    8.12.2 TODO dddvb-dkms if only newer DD cards are detected

    +
    +

    8.12.2 TODO dddvb-dkms if only newer DD cards are detected

    -
    -

    8.12.3 TODO media-build-experimental (up to kernel 4.8) for „old“ cards like TT S2-6400 FF

    +
    +

    8.12.3 TODO media-build-experimental (up to kernel 4.8) for „old“ cards like TT S2-6400 FF

    -
    -

    8.12.4 TODO newly merged DD drivers

    +
    +

    8.12.4 TODO newly merged DD drivers

    from http://www.vdr-portal.de/board18-vdr-hardware/board102-dvb-karten/120817-treiber-der-cine-ctv6-ddbridge-ci-in-den-kernel-integrieren/ @@ -3783,1783 +3535,1835 @@ from -

    8.13 autoinstall-ubuntu-drivers

    +
    +

    8.13 autoinstall-ubuntu-drivers

    The tool ubuntu-drivers is used to install the matching driver version for nvidia graphics cards, virtualbox guest additions and Intel and AMD microcode updates.

    -
    -

    8.13.1 tasks

    +
    +

    8.13.1 tasks

    -
    ---
    -# file roles/autoinstall-ubuntu-drivers/tasks/main.yml
    -- name: apt | install ubuntu-drivers-common
    -  apt:
    -    name: ubuntu-drivers-common
    -    state: present
    +
    ---
    +# file roles/autoinstall-ubuntu-drivers/tasks/main.yml
    +- name: apt | install ubuntu-drivers-common
    +  apt:
    +    name: ubuntu-drivers-common
    +    state: present
     
    -- name: ensure /etc/yavdr exists
    -  file:
    -    path: /etc/yavdr
    -    state: directory
    -    mode: 0755
    +- name: ensure /etc/yavdr exists
    +  file:
    +    path: /etc/yavdr
    +    state: directory
    +    mode: 0755
     
    -- name: let ubuntu-drivers automatically install additional drivers
    -  command: ubuntu-drivers --package-list /etc/yavdr/autoinstalled autoinstall
    +- name: let ubuntu-drivers automatically install additional drivers
    +  command: ubuntu-drivers --package-list /etc/yavdr/autoinstalled autoinstall
     
    -
    -

    8.14 autoinstall-satip

    +
    +

    8.14 autoinstall-satip

    If a Sat>IP Server responds to a discovery request, the package vdr-plugin-satip is installed.

    -
    -

    8.14.1 tasks

    +
    +

    8.14.1 tasks

    -
    ---
    -# file roles/autoinstall-satip/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-satip/tasks/main.yml
     
    -- name: "detect SAT>IP Server(s) on the network"
    -  action: satip_facts
    +- name: "detect SAT>IP Server(s) on the network"
    +  action: satip_facts
     
    -- debug:
    -    var: satip_detected
    -    verbosity: 1
    +- debug:
    +    var: satip_detected
    +    verbosity: 1
     
    -- name: apt | install vdr-plugin-satip if a Sat>IP server has been detected
    -  apt:
    -    name: vdr-plugin-satip
    -  when: satip_detected
    -  notify: [ 'Restart VDR' ]
    +- name: apt | install vdr-plugin-satip if a Sat>IP server has been detected
    +  apt:
    +    name: vdr-plugin-satip
    +  when: satip_detected
    +  notify: [ 'Restart VDR' ]
     
    -
    -

    8.15 autoinstall-targavfd

    +
    +

    8.15 autoinstall-targavfd

    -
    -

    8.15.1 tasks

    +
    +

    8.15.1 tasks

    -
    ---
    -# file roles/autoinstall-targavfd/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-targavfd/tasks/main.yml
     
    -- name: apt | install vdr-plugin-targavfd if connected
    -  apt:
    -    name: vdr-plugin-targavfd
    -  when: 
    -    - '"19c2:6a11" in usb'
    -  notify: [ 'Restart VDR' ]
    +- name: apt | install vdr-plugin-targavfd if connected
    +  apt:
    +    name: vdr-plugin-targavfd
    +  when: 
    +    - "19c2:6a11" in usb
    +  notify: [ 'Restart VDR' ]
     
    -
    -

    8.16 autoinstall-imonlcd

    +
    +

    8.16 autoinstall-imonlcd

    -
    -

    8.16.1 tasks

    +
    +

    8.16.1 tasks

    -
    ---
    -# file roles/autoinstall-imonlcd/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-imonlcd/tasks/main.yml
     
    -- name: apt | install vdr-plugin-imonlcd if connected
    -  apt:
    -    name: vdr-plugin-imonlcd
    -  when: 
    -    - '"15c2:0038" in usb'
    -    - '"15c2:ffdc" in usb'
    -  notify: [ 'Restart VDR' ]
    +- name: apt | install vdr-plugin-imonlcd if connected
    +  apt:
    +    name: vdr-plugin-imonlcd
    +  when: 
    +    - "15c2:0038" in usb
    +    - "15c2:ffdc" in usb
    +  notify: [ 'Restart VDR' ]
     
    -
    -

    8.17 autoinstall-libcecdaemon

    +
    +

    8.17 autoinstall-libcecdaemon

    -
    -

    8.17.1 tasks

    +
    +

    8.17.1 tasks

    -
    ---
    -# file roles/autoinstall-libcec-daemon/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-libcec-daemon/tasks/main.yml
     
    -- name: apt | install libcec-daemon if connected
    -  apt:
    -    name: libcec-daemon
    -  when: 
    -    - '"2548:1002" in usb'
    +- name: apt | install libcec-daemon if connected
    +  apt:
    +    name: libcec-daemon
    +  when: 
    +    - "2548:1002" in usb
     
    -
    -

    8.18 autoinstall-pvr350

    +
    +

    8.18 autoinstall-pvr350

    -
    -

    8.18.1 tasks

    +
    +

    8.18.1 tasks

    -
    ---
    -# file roles/autoinstall-pvr350/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-pvr350/tasks/main.yml
     
    -- name: apt | install vdr-plugin-pvr350 if connected
    -  apt:
    -    name: vdr-plugin-pvr350
    -  when: 
    -    - '"0070:4000" in pci'
    -  notify: [ 'Restart VDR' ]
    +- name: apt | install vdr-plugin-pvr350 if connected
    +  apt:
    +    name: vdr-plugin-pvr350
    +  when: 
    +    - "0070:4000" in pci
    +  notify: [ 'Restart VDR' ]
     
    - -
    -

    8.19 TODO autoinstall-dvbhddevice

    +
    +

    8.19 autoinstall-hauppauge-pvr

    +
    +
    ---
    +# file roles/autoinstall-hauppauge-pvr/tasks/main.yml
    +
    +- name: apt | install vdr-plugin-pvrinput if a haupauge pvr card is found
    +  apt:
    +    name: vdr-plugin-pvrinput
    +  when: 
    +    - "0070:4000" in pci
    +    - "4444:0016" in pci
    +  notify: [ 'Restart VDR' ]
    +
    +
    +
    +
    +
    +

    8.20 TODO autoinstall-dvbhddevice

    +

    Problem: woher kommt der Treiber (AFAIK noch nicht im Kernel)? Die Firmware sollte in yavdr-firmware stecken

    -
    -

    8.19.1 tasks

    -
    -
    -
    ---
    -# file roles/autoinstall-dvbhddevice/tasks/main.yml
    -
    -- name: apt | install vdr-plugin-dvbhddevice if connected
    -  apt:
    -    name: vdr-plugin-dvbhddevice
    -  when: 
    -    - '"13c2:300a" in pci'
    -    - '"13c2:300b" in pci'
    -  notify: [ 'Restart VDR' ]
    -
    -
    -
    -
    -
    - -
    -

    8.20 autoinstall-dvbsddevice

    -
    -
    -

    8.20.1 tasks

    +
    +

    8.20.1 tasks

    -
    ---
    -# file roles/autoinstall-dvbsddevice/tasks/main.yml
    +
    ---
    +# file roles/autoinstall-dvbhddevice/tasks/main.yml
     
    -- name: apt | install vdr-plugin-dvbsddevice if module is loaded
    -  apt:
    -    name: vdr-plugin-dvbsddevice
    -  when: 
    -    - '"dvb_ttpci" in modules'
    -  notify: [ 'Restart VDR' ]
    +- name: apt | install vdr-plugin-dvbhddevice if connected
    +  apt:
    +    name: vdr-plugin-dvbhddevice
    +  when: 
    +    - '"13c2:300a" in pci'
    +    - '"13c2:300b" in pci'
    +  notify: [ 'Restart VDR' ]
     
    -
    -

    8.21 kodi

    -
    -
    -

    8.21.1 tasks

    -
    -
    1. Install KODI
      -
      -
      ---
       
      -- name: apt | install kodi packages
      -  apt:
      -    name: '{{ item }}'
      -    state: present
      -    install_recommends: no
      -  with_items:
      +
      +

      8.21 autoinstall-dvbsddevice

      +
      +
      +

      8.21.1 tasks

      +
      +
      +
      ---
      +# file roles/autoinstall-dvbsddevice/tasks/main.yml
      +
      +- name: apt | install vdr-plugin-dvbsddevice if module is loaded
      +  apt:
      +    name: vdr-plugin-dvbsddevice
      +  when: 
      +    - '"dvb_ttpci" in modules'
      +  notify: [ 'Restart VDR' ]
      +
      +
      +
      +
      +
      +
      +

      8.22 kodi

      +
      +
      +

      8.22.1 tasks

      +
      +
      1. Install KODI
        +
        +
        - include: install-kodi.yml tags=install,update,kodi:install
        +- include: configure-kodi.yml tags=install,update,kodi:configure
        +
        +
        +
        +
        ---
        +
        +- name: apt | install kodi packages
        +  apt:
        +    name: '{{ item }}'
        +    state: present
        +    install_recommends: no
        +  with_items:
             - kodi
             - kodi-pvr-vdr-vnsi
             - kodi-eventclients-xbmc-send  
        +
        +
        +
        +
        - name: create kodi.service for the user session
        +  template:
        +      src: 'templates/kodi.service.j2'
        +      dest: '{{ vdr.home }}/.config/systemd/user/kodi.service'
        +      mode: 0644
        +      owner: '{{ vdr.user }}'
        +      group: '{{ vdr.group }}'
         
        -- name: create kodi.service for the user session
        -  template:
        -      src: 'templates/kodi.service.j2'
        -      dest: '{{ vdr.home }}/.config/systemd/user/kodi.service'
        -      mode: 0755
        -      owner: '{{ vdr.user }}'
        -      group: '{{ vdr.group }}'
        -
        -- name: create kodi user directory
        -  file:
        -      dest: '{{ vdr.home }}/{{ item }}'
        -      state: directory
        -      owner: '{{ vdr.user }}'
        -      group: '{{ vdr.group }}'
        -      mode: "0775"
        -  with_items:
        +- name: create kodi user directory
        +  file:
        +      dest: '{{ vdr.home }}/{{ item }}'
        +      state: directory
        +      owner: '{{ vdr.user }}'
        +      group: '{{ vdr.group }}'
        +      mode: "0775"
        +  with_items:
               - .kodi
               - .kodi/userdata
               - .kodi/userdata/keymaps
         
        -# TODO: Add configuration files
        -
        -
        -
      -
      -
      -

      8.21.2 templates

      -
      -
      1. kodi.service
        -
        -
        [Unit]
        -Description=Start kodi in user session
        +- name: copy Lircmap.xml if it does not exist yet
        +  copy:
        +      dest: '{{ vdr.home }}/.kodi/userdata/Lircmap.xml'
        +      src: 'files/userdata/Lircmap.xml'
        +      owner: '{{ vdr.user }}'
        +      group: '{{ vdr.group }}'    
        +      mode: "0664"
        +      force: no
         
        -[Service]
        -Type=simple
        -PassEnvironment=DISPLAY XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
        -ExecStartPre=-/usr/bin/set-kodi-display
        -ExecStart=/usr/bin/kodi
        -ExecStop=/bin/bash -c "/usr/bin/kodi-send --action=QUIT; while /usr/bin/pgrep kodi; do sleep 1;  done; sleep 1"
        -TimeoutStopSec=10
        -SuccessExitStatus=0 127
        -Restart=on-failure
        +- name: copy remote.xml if it does not exist yes
        +  copy:
        +      dest: '{{ vdr.home }}/.kodi/userdata/keymaps/remote.xml'
        +      src: 'files/userdata/keymaps/remote.xml'
        +      owner: '{{ vdr.user }}'
        +      group: '{{ vdr.group }}'    
        +      mode: "0664"
        +      force: no
        +# TODO: Add configuration files
         
      -
      -

      8.21.3 files

      -
      -
      1. Lircmap.xml
        +
        +

        8.22.2 templates

        +
        +
        1. kodi.service
          -
          <lircmap>
          -    <remote device="linux-input-layer">
          -    <altname>cx23885_remote</altname>
          -    <altname>devinput</altname>
          -        <up>KEY_UP</up>
          -        <down>KEY_DOWN</down>
          -                <menu>KEY_MENU</menu>
          -        <select>KEY_OK</select>
          -        <back>KEY_ESC</back>
          -        <left>KEY_LEFT</left>
          -        <right>KEY_RIGHT</right>
          -        <red>KEY_RED</red>
          -        <green>KEY_GREEN</green>
          -        <yellow>KEY_YELLOW</yellow>
          -        <blue>KEY_BLUE</blue>
          -        <zero>KEY_0</zero>
          -        <one>KEY_1</one>
          -        <two>KEY_2</two>
          -        <three>KEY_3</three>
          -        <four>KEY_4</four>
          -        <five>KEY_5</five>
          -        <six>KEY_6</six>
          -        <seven>KEY_7</seven>
          -        <eight>KEY_8</eight>
          -        <nine>KEY_9</nine>
          -        <info>KEY_INFO</info>
          -        <play>KEY_PLAY</play>
          -        <play>KEY_PLAYPAUSE</play>
          -        <pause>KEY_PAUSE</pause>
          -        <stop>KEY_STOP</stop>
          -        <record>KEY_RECORD</record>
          -        <forward>KEY_FASTFORWARD</forward>
          -        <reverse>KEY_REWIND</reverse>
          -        <skipplus>KEY_NEXT</skipplus>
          -        <skipminus>KEY_BACK</skipminus>
          -        <power>KEY_POWER2</power>
          -        <channelplus>KEY_CHANNELUP</channelplus>
          -        <channelminus>KEY_CHANNELDOWN</channelminus>
          -        <title>KEY_PROG3</title>
          -        <volumeplus>KEY_VOLUMEUP</volumeplus>
          -        <volumeminus>KEY_VOLUMEDOWN</volumeminus>
          -                <teletext>KEY_TEXT</teletext>
          -        <mute>KEY_MUTE</mute>
          -        <start>KEY_SELECT</start>
          -        <subtitle>KEY_SUBTITLE</subtitle>
          -                <audio>KEY_MODE</audio>
          -        <mute>KEY_MUTE</mute>
          -        <myvideo>KEY_VIDEO</myvideo>
          -        <mymusic>KEY_AUDIO</mymusic>
          -        <mypictures>KEY_IMAGES</mypictures>
          -        <recordedtv>KEY_PVR</recordedtv>
          -                <guide>KEY_EPG</guide>
          -                <display>KEY_SCREEN</display>
          -                <enter>KEY_PROG4</enter>
          -                <playlist>KEY_ZOOM</playlist>
          -                <livetv>KEY_CHANNEL</livetv>
          -                <mytv>KEY_TV</mytv>
          -                <liveradio>KEY_FN</liveradio>
          -    </remote>
          -</lircmap>
          +
          [Unit]
          +Description=Start kodi in user session
          +
          +[Service]
          +Type=simple
          +PassEnvironment=DISPLAY XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
          +ExecStartPre=-/usr/bin/set-kodi-display
          +ExecStart=/usr/bin/kodi -l /run/lirc/lircd
          +ExecStop=/bin/bash -c "/usr/bin/kodi-send --action=QUIT; while /usr/bin/pgrep kodi; do sleep 1;  done; sleep 1"
          +TimeoutStopSec=10
          +SuccessExitStatus=0 127
          +Restart=on-failure
          +
          +
          +
        +
        +
        +

        8.22.3 files

        +
        +
        1. Lircmap.xml
          +
          +
          <lircmap>
          +    <remote device="linux-input-layer">
          +    <altname>cx23885_remote</altname>
          +    <altname>devinput</altname>
          +        <up>KEY_UP</up>
          +        <down>KEY_DOWN</down>
          +                <menu>KEY_MENU</menu>
          +        <select>KEY_OK</select>
          +        <back>KEY_ESC</back>
          +        <left>KEY_LEFT</left>
          +        <right>KEY_RIGHT</right>
          +        <red>KEY_RED</red>
          +        <green>KEY_GREEN</green>
          +        <yellow>KEY_YELLOW</yellow>
          +        <blue>KEY_BLUE</blue>
          +        <zero>KEY_0</zero>
          +        <one>KEY_1</one>
          +        <two>KEY_2</two>
          +        <three>KEY_3</three>
          +        <four>KEY_4</four>
          +        <five>KEY_5</five>
          +        <six>KEY_6</six>
          +        <seven>KEY_7</seven>
          +        <eight>KEY_8</eight>
          +        <nine>KEY_9</nine>
          +        <info>KEY_INFO</info>
          +        <play>KEY_PLAY</play>
          +        <play>KEY_PLAYPAUSE</play>
          +        <pause>KEY_PAUSE</pause>
          +        <stop>KEY_STOP</stop>
          +        <record>KEY_RECORD</record>
          +        <forward>KEY_FASTFORWARD</forward>
          +        <reverse>KEY_REWIND</reverse>
          +        <skipplus>KEY_NEXT</skipplus>
          +        <skipminus>KEY_BACK</skipminus>
          +        <power>KEY_POWER2</power>
          +        <channelplus>KEY_CHANNELUP</channelplus>
          +        <channelminus>KEY_CHANNELDOWN</channelminus>
          +        <title>KEY_PROG3</title>
          +        <volumeplus>KEY_VOLUMEUP</volumeplus>
          +        <volumeminus>KEY_VOLUMEDOWN</volumeminus>
          +                <teletext>KEY_TEXT</teletext>
          +        <mute>KEY_MUTE</mute>
          +        <start>KEY_SELECT</start>
          +        <subtitle>KEY_SUBTITLE</subtitle>
          +                <audio>KEY_MODE</audio>
          +        <mute>KEY_MUTE</mute>
          +        <myvideo>KEY_VIDEO</myvideo>
          +        <mymusic>KEY_AUDIO</mymusic>
          +        <mypictures>KEY_IMAGES</mypictures>
          +        <recordedtv>KEY_PVR</recordedtv>
          +                <guide>KEY_EPG</guide>
          +                <display>KEY_SCREEN</display>
          +                <enter>KEY_PROG4</enter>
          +                <playlist>KEY_ZOOM</playlist>
          +                <livetv>KEY_CHANNEL</livetv>
          +                <mytv>KEY_TV</mytv>
          +                <liveradio>KEY_FN</liveradio>
          +    </remote>
          +</lircmap>
           
        2. -
        3. keymaps
          1. remote.xml
            +
          2. keymaps
            1. remote.xml
              -
              <!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
              -<!-- The <global> section is a fall through - they will only be used if the button is not          -->
              -<!-- used in the current window's section.  Note that there is only handling                       -->
              -<!-- for a single action per button at this stage.                                                 -->
              -<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox       -->
              -<!-- gamepads.                                                                                     -->
              +
              <!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
              +<!-- The <global> section is a fall through - they will only be used if the button is not          -->
              +<!-- used in the current window's section.  Note that there is only handling                       -->
              +<!-- for a single action per button at this stage.                                                 -->
              +<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox       -->
              +<!-- gamepads.                                                                                     -->
               
              -<!-- The format is:                      -->
              -<!--    <device>                         -->
              -<!--      <button>action</button>        -->
              -<!--    </device>                        -->
              +<!-- The format is:                      -->
              +<!--    <device>                         -->
              +<!--      <button>action</button>        -->
              +<!--    </device>                        -->
               
              -<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
              -<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
              -<!-- You set it up by adding a <universalremote> block to the window or <global> section:       -->
              -<!--    <universalremote>             -->
              -<!--       <obc45>Stop</obc45>         -->
              -<!--    </universalremote>            -->
              -<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
              +<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
              +<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
              +<!-- You set it up by adding a <universalremote> block to the window or <global> section:       -->
              +<!--    <universalremote>             -->
              +<!--       <obc45>Stop</obc45>         -->
              +<!--    </universalremote>            -->
              +<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
               
              -<!-- Note that the action can be a built-in function.                 -->
              -<!--  eg <B>XBMC.ActivateWindow(MyMusic)</B>                         -->
              -<!-- would automatically go to My Music on the press of the B button. -->
              +<!-- Note that the action can be a built-in function.                 -->
              +<!--  eg <B>XBMC.ActivateWindow(MyMusic)</B>                         -->
              +<!-- would automatically go to My Music on the press of the B button. -->
               
              -<!-- Joysticks / Gamepads:                                                                    -->
              -<!--   See the sample PS3 controller configuration below for the format.                      -->
              -<!--                                                                                          -->
              -<!--  Joystick Name:                                                                          -->
              -<!--   Do 'cat /proc/bus/input/devices' or see your xbmc log file  to find the names of       -->
              -<!--   detected joysticks. The name used in the configuration should match the detected name. -->
              -<!--                                                                                          -->
              -<!--  Button Ids:                                                                             -->
              -<!--   'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear   -->
              -<!--   in xbmc.log when they are pressed. Use your log to map custom buttons to actions.      -->
              -<!--                                                                                          -->
              -<!--  Axis Ids / Analog Controls                                                              -->
              -<!--   Coming soon.                                                                           -->
              -<keymap>
              -  <global>
              -    <universalremote>
              -       <obc150>XBMC.ejecttray()</obc150>
              -       <obc151>Playlist</obc151>
              -    </universalremote>
              -    <remote>
              -      <play>PlayPause</play>
              -      <pause>Pause</pause>
              -      <stop>Stop</stop>
              -      <forward>FastForward</forward>
              -      <reverse>Rewind</reverse>
              -      <left>Left</left>
              -      <right>Right</right>
              -      <up>Up</up>
              -      <down>Down</down>
              -      <select>Select</select>
              -      <pageplus>PageUp</pageplus>
              -      <pageminus>PageDown</pageminus>
              -      <back>ParentDir</back>
              -      <menu>PreviousMenu</menu>
              -      <title>ContextMenu</title>
              -      <info>Info</info>
              -      <skipplus>SkipNext</skipplus>
              -      <skipminus>SkipPrevious</skipminus>
              -      <display>FullScreen</display>
              -      <start>PreviousMenu</start>
              -      <record>Screenshot</record>
              -      <volumeplus>VolumeUp</volumeplus>
              -      <volumeminus>VolumeDown</volumeminus>
              -      <mute>Mute</mute>
              -      <power>XBMC.Quit()</power>
              -      <myvideo>XBMC.ActivateWindow(MyVideos)</myvideo>
              -      <mymusic>XBMC.ActivateWindow(MyMusic)</mymusic>
              -      <mypictures>XBMC.ActivateWindow(MyPictures)</mypictures>
              -      <!--- <mytv>XBMC.ActivateWindow(Home)</mytv> -->
              -      <recordedtv>XBMC.ActivateWindowAndFocus(MyPVR, 34,0, 13,0)</recordedtv>
              -      <!-- PVR: EPG -->
              -      <guide>XBMC.ActivateWindowAndFocus(MyPVR, 31,0, 10,0)</guide>
              -      <!-- PVR: Channellist -->
              -      <livetv>XBMC.ActivateWindowAndFocus(MyPVR, 32,0, 11,0)</livetv>
              -      <!-- PVR: Radio -->
              -      <liveradio>XBMC.ActivateWindowAndFocus(MyPVR, 33,0, 12,0)</liveradio>
              -      <red>XBMC.ActivateWindow(Home)</red>
              -      <yellow>XBMC.ActivateWindow(MyVideos)</yellow>
              -      <green>XBMC.ActivateWindow(MyMusic)</green>
              -      <!-- <blue>XBMC.ActivateWindow(MyPictures)</blue> -->
              -      <zero>Number0</zero>
              -      <one>Number1</one>
              -      <two>JumpSMS2</two>
              -      <three>JumpSMS3</three>
              -      <four>JumpSMS4</four>
              -      <five>JumpSMS5</five>
              -      <six>JumpSMS6</six>
              -      <seven>JumpSMS7</seven>
              -      <eight>JumpSMS8</eight>
              -      <nine>JumpSMS9</nine>
              -      <audio>AudioNextLanguage</audio>
              -      <subtitle>ShowSubtitles</subtitle>
              -      <enter>FullScreen</enter>
              -      <blue>ContextMenu</blue>
              -      <playlist>XBMC.ActivateWindow(MyMusicPlaylist)</playlist>
              -    </remote>
              -  </global>
              -  <Home>
              -    <remote>
              -      <menu>XBMC.Skin.ToggleSetting(HomeViewToggle)</menu>
              -      <info>XBMC.ActivateWindow(SystemInfo)</info>
              -      <clear>XBMC.ActivateWindow(Weather)</clear>
              -      <blue>XBMC.ActivateWindow(Settings)</blue>
              -      <red>FullScreen</red>
              -      <back>FullScreen</back>
              -    </remote>
              -  </Home>
              -  <MyFiles>
              -    <remote>
              -      <clear>Delete</clear>
              -    </remote>
              -  </MyFiles>
              -  <MyMusicPlaylist>
              -    <remote>
              -      <back>Playlist</back>      <!-- Close playlist -->
              -      <clear>Delete</clear>
              -    </remote>
              -  </MyMusicPlaylist>
              -  <MyMusicPlaylistEditor>
              -    <remote>
              -      <zero>Queue</zero>
              -    </remote>
              -  </MyMusicPlaylistEditor>
              -  <MyMusicFiles>
              -    <remote>
              -      <zero>Queue</zero>
              -      <star>Queue</star>
              -      <start>ContextMenu</start>
              -    </remote>
              -  </MyMusicFiles>
              -  <MyMusicLibrary>
              -    <remote>
              -      <zero>Queue</zero>
              -      <star>Queue</star>
              -    </remote>
              -  </MyMusicLibrary>
              -  <FullscreenVideo>
              -    <remote>
              -      <back>FullScreen</back>
              -      <zero>Number0</zero>
              -      <one>Number1</one>
              -      <two>Number2</two>
              -      <three>Number3</three>
              -      <four>Number4</four>
              -      <five>Number5</five>
              -      <six>Number6</six>
              -      <seven>Number7</seven>
              -      <eight>Number8</eight>
              -      <nine>Number9</nine>
              -      <left>Rewind</left>
              -      <right>FastForward</right>
              -      <up>Play</up>
              -      <down>Pause</down>
              -      <yellow>StepForward</yellow>
              -      <green>StepBack</green>
              -      <blue>CodecInfo</blue>
              -      <menu>OSD</menu>
              -      <start>OSD</start>
              -      <info>XBMC.ActivateWindow(PVROSDChannels)</info>
              -      <title>XBMC.ActivateWindow(PVROSDChannels)</title>
              -      <display>AspectRatio</display>
              -      <select>Info</select>
              -      <teletext>XBMC.ActivateWindow(Teletext)</teletext>
              -      <channelplus>SkipNext</channelplus>
              -      <channelminus>SkipPrevious</channelminus>
              -      <record>XBMC.PlayerControl(Record)</record>
              -    </remote>
              -  </FullscreenVideo>
              -  <FullscreenInfo>
              -    <remote>
              -      <back>FullScreen</back>
              -      <left>Rewind</left>
              -      <right>FastForward</right>
              -      <up>Play</up>
              -      <down>Pause</down>
              -      <yellow>StepForward</yellow>
              -      <green>StepBack</green>
              -      <display>AspectRatio</display>
              -      <info>CodecInfo</info>
              -      <select>Close</select>
              -      <menu>OSD</menu>
              -    </remote>
              -  </FullscreenInfo>
              -  <PlayerControls>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -    </remote>
              -  </PlayerControls>
              -  <Visualisation>
              -    <universalremote>
              -       <obc151>XBMC.ActivateWindow(MyMusicPlaylist)</obc151>
              -    </universalremote>
              -    <remote>
              -      <red>FullScreen</red>
              -      <yellow>AnalogSeekForward</yellow>
              -      <green>AnalogSeekBack</green>
              -      <blue>CodecInfo</blue>
              -      <left>Rewind</left>
              -      <right>FastForward</right>
              -      <pageplus>SkipNext</pageplus>
              -      <pageminus>SkipPrevious</pageminus>
              -      <up>Play</up>
              -      <down>Pause</down>
              -      <info>XBMC.ActivateWindow(PVROSDChannels)</info>
              -      <back>XBMC.ActivateWindow(MyMusicPlaylist)</back>
              -      <select>Info</select>
              -      <menu>XBMC.ActivateWindow(MusicOSD)</menu>
              -      <start>XBMC.ActivateWindow(MusicOSD)</start>
              -    </remote>
              -  </Visualisation>
              -  <MusicOSD>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -      <info>CodecInfo</info>
              -    </remote>
              -  </MusicOSD>
              -  <VisualisationSettings>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -    </remote>
              -  </VisualisationSettings>
              -  <VisualisationPresetList>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -    </remote>
              -  </VisualisationPresetList>
              -  <SlideShow>
              -    <remote>
              -      <zero>ZoomNormal</zero>
              -      <one>ZoomLevel1</one>
              -      <two>ZoomLevel2</two>
              -      <three>ZoomLevel3</three>
              -      <four>ZoomLevel4</four>
              -      <five>ZoomLevel5</five>
              -      <six>ZoomLevel6</six>
              -      <seven>ZoomLevel7</seven>
              -      <eight>ZoomLevel8</eight>
              -      <nine>ZoomLevel9</nine>
              -      <info>CodecInfo</info>
              -      <pageplus>ZoomIn</pageplus>
              -      <pageminus>ZoomOut</pageminus>
              -      <select>Rotate</select>
              -      <up>Pause</up>
              -      <down>Play</down>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </SlideShow>
              -  <ScreenCalibration>
              -    <remote>
              -      <select>NextCalibration</select>
              -      <enter>NextCalibration</enter>
              -      <zero>ResetCalibration</zero>
              -      <display>NextResolution</display>
              -      <xbox>NextResolution</xbox>
              -    </remote>
              -  </ScreenCalibration>
              -  <GUICalibration>
              -    <remote>
              -      <select>NextCalibration</select>
              -      <enter>NextCalibration</enter>
              -      <zero>ResetCalibration</zero>
              -    </remote>
              -  </GUICalibration>
              -  <SelectDialog>
              -    <remote>
              -      <back>Close</back>
              -    </remote>
              -  </SelectDialog>
              -  <VideoOSD>
              -    <remote>
              -      <back>PreviousMenu</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -    </remote>
              -  </VideoOSD>
              -  <VideoMenu>
              -    <remote>
              -      <menu>OSD</menu>
              -      <back>PreviousMenu</back>
              -      <info>Info</info>
              -      <title>CodecInfo</title>
              -      <zero>Number0</zero>
              -      <one>Number1</one>
              -      <two>Number2</two>
              -      <three>Number3</three>
              -      <four>Number4</four>
              -      <five>Number5</five>
              -      <six>Number6</six>
              -      <seven>Number7</seven>
              -      <eight>Number8</eight>
              -      <nine>Number9</nine>
              -    </remote>
              -  </VideoMenu>
              -  <OSDVideoSettings>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -    </remote>
              -  </OSDVideoSettings>
              -  <OSDAudioSettings>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -    </remote>
              -  </OSDAudioSettings>
              -  <VideoBookmarks>
              -    <remote>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -      <zero>Delete</zero>
              -    </remote>
              -  </VideoBookmarks>
              -  <MyVideoLibrary>
              -    <remote>
              -      <zero>Queue</zero>
              -      <clear>Delete</clear>
              -      <green>ToggleWatched</green>
              -      <yellow>Queue</yellow>
              -    </remote>
              -  </MyVideoLibrary>
              -  <MyVideoFiles>
              -    <remote>
              -      <zero>Queue</zero>
              -      <star>Queue</star>
              -      <blue>ContextMenu</blue>
              -      <green>ToggleWatched</green>
              -      <yellow>Queue</yellow>
              -    </remote>
              -  </MyVideoFiles>
              -  <MyPictures>
              -    <remote>
              -      <zero>Queue</zero>
              -      <star>Queue</star>
              -      <start>ContextMenu</start>
              -    </remote>
              -  </MyPictures>
              -  <MyVideoPlaylist>
              -    <remote>
              -      <back>Playlist</back>      <!-- Close playlist -->
              -      <clear>Delete</clear>
              -      <zero>Delete</zero>
              -    </remote>
              -  </MyVideoPlaylist>
              -  <VirtualKeyboard>
              -    <remote>
              -      <back>BackSpace</back>
              -      <star>Shift</star>
              -      <hash>Symbols</hash>
              -      <zero>Number0</zero>
              -      <one>Number1</one>
              -      <two>Number2</two>
              -      <three>Number3</three>
              -      <four>Number4</four>
              -      <five>Number5</five>
              -      <six>Number6</six>
              -      <seven>Number7</seven>
              -      <eight>Number8</eight>
              -      <nine>Number9</nine>
              -      <pageminus>CursorLeft</pageminus>
              -      <pageplus>CursorRight</pageplus>
              -    </remote>
              -  </VirtualKeyboard>
              -  <ContextMenu>
              -    <remote>
              -      <blue>Close</blue>
              -      <back>Close</back>
              -    </remote>
              -  </ContextMenu>
              -  <FileStackingDialog>
              -    <remote>
              -      <back>Close</back>
              -    </remote>
              -  </FileStackingDialog>
              -  <Scripts>
              -    <remote>
              -      <info>XBMC.ActivateWindow(ScriptsDebugInfo)</info>
              -    </remote>
              -  </Scripts>
              -  <ScriptsDebugInfo>
              -    <remote>
              -      <info>Info</info>      <!-- clears debug python info -->
              -    </remote>
              -  </ScriptsDebugInfo>
              -  <NumericInput>
              -    <remote>
              -      <zero>Number0</zero>
              -      <one>Number1</one>
              -      <two>Number2</two>
              -      <three>Number3</three>
              -      <four>Number4</four>
              -      <five>Number5</five>
              -      <six>Number6</six>
              -      <seven>Number7</seven>
              -      <eight>Number8</eight>
              -      <nine>Number9</nine>
              -      <back>BackSpace</back>
              -    </remote>
              -  </NumericInput>
              -  <Weather>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </Weather>
              -  <Settings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </Settings>
              -  <MyPicturesSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </MyPicturesSettings>
              -  <MyProgramsSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </MyProgramsSettings>
              -  <MyWeatherSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </MyWeatherSettings>
              -  <MyMusicSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </MyMusicSettings>
              -  <SystemSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </SystemSettings>
              -  <MyVideosSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </MyVideosSettings>
              -  <NetworkSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </NetworkSettings>
              -  <AppearanceSettings>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </AppearanceSettings>
              -  <Profiles>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </Profiles>
              -  <systeminfo>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </systeminfo>
              -  <shutdownmenu>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </shutdownmenu>
              -  <submenu>
              -    <remote>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </submenu>
              -  <MusicInformation>
              -    <remote>
              -      <back>Close</back>
              -    </remote>
              -  </MusicInformation>
              -  <MovieInformation>
              -    <remote>
              -      <back>Close</back>
              -    </remote>
              -  </MovieInformation>
              -  <LockSettings>
              -    <remote>
              -      <menu>Close</menu>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </LockSettings>
              -  <ProfileSettings>
              -    <remote>
              -      <menu>Close</menu>
              -      <back>PreviousMenu</back>
              -    </remote>
              -  </ProfileSettings>
              -  <PictureInfo>
              -    <remote>
              -      <skipplus>NextPicture</skipplus>
              -      <skipminus>PreviousPicture</skipminus>
              -      <info>Close</info>
              -      <back>Close</back>
              -    </remote>
              -  </PictureInfo>
              -  <Teletext>
              -    <remote>
              -      <zero>number0</zero>
              -      <one>number1</one>
              -      <two>number2</two>
              -      <three>number3</three>
              -      <four>number4</four>
              -      <five>number5</five>
              -      <six>number6</six>
              -      <seven>number7</seven>
              -      <eight>number8</eight>
              -      <nine>number9</nine>
              -      <red>Red</red>
              -      <green>Green</green>
              -      <yellow>Yellow</yellow>
              -      <blue>Blue</blue>
              -      <info>Info</info>
              -      <back>Close</back>
              -      <menu>Close</menu>
              -      <start>Close</start>
              -      <teletext>Close</teletext>
              -    </remote>
              -  </Teletext>
              -  <Favourites>
              -    <remote>
              -      <back>Close</back>
              -    </remote>
              -  </Favourites>
              -</keymap>
              +<!-- Joysticks / Gamepads:                                                                    -->
              +<!--   See the sample PS3 controller configuration below for the format.                      -->
              +<!--                                                                                          -->
              +<!--  Joystick Name:                                                                          -->
              +<!--   Do 'cat /proc/bus/input/devices' or see your xbmc log file  to find the names of       -->
              +<!--   detected joysticks. The name used in the configuration should match the detected name. -->
              +<!--                                                                                          -->
              +<!--  Button Ids:                                                                             -->
              +<!--   'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear   -->
              +<!--   in xbmc.log when they are pressed. Use your log to map custom buttons to actions.      -->
              +<!--                                                                                          -->
              +<!--  Axis Ids / Analog Controls                                                              -->
              +<!--   Coming soon.                                                                           -->
              +<keymap>
              +  <global>
              +    <universalremote>
              +       <obc150>XBMC.ejecttray()</obc150>
              +       <obc151>Playlist</obc151>
              +    </universalremote>
              +    <remote>
              +      <play>PlayPause</play>
              +      <pause>Pause</pause>
              +      <stop>Stop</stop>
              +      <forward>FastForward</forward>
              +      <reverse>Rewind</reverse>
              +      <left>Left</left>
              +      <right>Right</right>
              +      <up>Up</up>
              +      <down>Down</down>
              +      <select>Select</select>
              +      <pageplus>PageUp</pageplus>
              +      <pageminus>PageDown</pageminus>
              +      <back>ParentDir</back>
              +      <menu>PreviousMenu</menu>
              +      <title>ContextMenu</title>
              +      <info>Info</info>
              +      <skipplus>SkipNext</skipplus>
              +      <skipminus>SkipPrevious</skipminus>
              +      <display>FullScreen</display>
              +      <start>PreviousMenu</start>
              +      <record>Screenshot</record>
              +      <volumeplus>VolumeUp</volumeplus>
              +      <volumeminus>VolumeDown</volumeminus>
              +      <mute>Mute</mute>
              +      <power>XBMC.Quit()</power>
              +      <myvideo>XBMC.ActivateWindow(MyVideos)</myvideo>
              +      <mymusic>XBMC.ActivateWindow(MyMusic)</mymusic>
              +      <mypictures>XBMC.ActivateWindow(MyPictures)</mypictures>
              +      <!--- <mytv>XBMC.ActivateWindow(Home)</mytv> -->
              +      <recordedtv>XBMC.ActivateWindowAndFocus(MyPVR, 34,0, 13,0)</recordedtv>
              +      <!-- PVR: EPG -->
              +      <guide>XBMC.ActivateWindowAndFocus(MyPVR, 31,0, 10,0)</guide>
              +      <!-- PVR: Channellist -->
              +      <livetv>XBMC.ActivateWindowAndFocus(MyPVR, 32,0, 11,0)</livetv>
              +      <!-- PVR: Radio -->
              +      <liveradio>XBMC.ActivateWindowAndFocus(MyPVR, 33,0, 12,0)</liveradio>
              +      <red>XBMC.ActivateWindow(Home)</red>
              +      <yellow>XBMC.ActivateWindow(MyVideos)</yellow>
              +      <green>XBMC.ActivateWindow(MyMusic)</green>
              +      <!-- <blue>XBMC.ActivateWindow(MyPictures)</blue> -->
              +      <zero>Number0</zero>
              +      <one>Number1</one>
              +      <two>JumpSMS2</two>
              +      <three>JumpSMS3</three>
              +      <four>JumpSMS4</four>
              +      <five>JumpSMS5</five>
              +      <six>JumpSMS6</six>
              +      <seven>JumpSMS7</seven>
              +      <eight>JumpSMS8</eight>
              +      <nine>JumpSMS9</nine>
              +      <audio>AudioNextLanguage</audio>
              +      <subtitle>ShowSubtitles</subtitle>
              +      <enter>FullScreen</enter>
              +      <blue>ContextMenu</blue>
              +      <playlist>XBMC.ActivateWindow(MyMusicPlaylist)</playlist>
              +    </remote>
              +  </global>
              +  <Home>
              +    <remote>
              +      <menu>XBMC.Skin.ToggleSetting(HomeViewToggle)</menu>
              +      <info>XBMC.ActivateWindow(SystemInfo)</info>
              +      <clear>XBMC.ActivateWindow(Weather)</clear>
              +      <blue>XBMC.ActivateWindow(Settings)</blue>
              +      <red>FullScreen</red>
              +      <back>FullScreen</back>
              +    </remote>
              +  </Home>
              +  <MyFiles>
              +    <remote>
              +      <clear>Delete</clear>
              +    </remote>
              +  </MyFiles>
              +  <MyMusicPlaylist>
              +    <remote>
              +      <back>Playlist</back>      <!-- Close playlist -->
              +      <clear>Delete</clear>
              +    </remote>
              +  </MyMusicPlaylist>
              +  <MyMusicPlaylistEditor>
              +    <remote>
              +      <zero>Queue</zero>
              +    </remote>
              +  </MyMusicPlaylistEditor>
              +  <MyMusicFiles>
              +    <remote>
              +      <zero>Queue</zero>
              +      <star>Queue</star>
              +      <start>ContextMenu</start>
              +    </remote>
              +  </MyMusicFiles>
              +  <MyMusicLibrary>
              +    <remote>
              +      <zero>Queue</zero>
              +      <star>Queue</star>
              +    </remote>
              +  </MyMusicLibrary>
              +  <FullscreenVideo>
              +    <remote>
              +      <back>FullScreen</back>
              +      <zero>Number0</zero>
              +      <one>Number1</one>
              +      <two>Number2</two>
              +      <three>Number3</three>
              +      <four>Number4</four>
              +      <five>Number5</five>
              +      <six>Number6</six>
              +      <seven>Number7</seven>
              +      <eight>Number8</eight>
              +      <nine>Number9</nine>
              +      <left>Rewind</left>
              +      <right>FastForward</right>
              +      <up>Play</up>
              +      <down>Pause</down>
              +      <yellow>StepForward</yellow>
              +      <green>StepBack</green>
              +      <blue>CodecInfo</blue>
              +      <menu>OSD</menu>
              +      <start>OSD</start>
              +      <info>XBMC.ActivateWindow(PVROSDChannels)</info>
              +      <title>XBMC.ActivateWindow(PVROSDChannels)</title>
              +      <display>AspectRatio</display>
              +      <select>Info</select>
              +      <teletext>XBMC.ActivateWindow(Teletext)</teletext>
              +      <channelplus>SkipNext</channelplus>
              +      <channelminus>SkipPrevious</channelminus>
              +      <record>XBMC.PlayerControl(Record)</record>
              +    </remote>
              +  </FullscreenVideo>
              +  <FullscreenInfo>
              +    <remote>
              +      <back>FullScreen</back>
              +      <left>Rewind</left>
              +      <right>FastForward</right>
              +      <up>Play</up>
              +      <down>Pause</down>
              +      <yellow>StepForward</yellow>
              +      <green>StepBack</green>
              +      <display>AspectRatio</display>
              +      <info>CodecInfo</info>
              +      <select>Close</select>
              +      <menu>OSD</menu>
              +    </remote>
              +  </FullscreenInfo>
              +  <PlayerControls>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +    </remote>
              +  </PlayerControls>
              +  <Visualisation>
              +    <universalremote>
              +       <obc151>XBMC.ActivateWindow(MyMusicPlaylist)</obc151>
              +    </universalremote>
              +    <remote>
              +      <red>FullScreen</red>
              +      <yellow>AnalogSeekForward</yellow>
              +      <green>AnalogSeekBack</green>
              +      <blue>CodecInfo</blue>
              +      <left>Rewind</left>
              +      <right>FastForward</right>
              +      <pageplus>SkipNext</pageplus>
              +      <pageminus>SkipPrevious</pageminus>
              +      <up>Play</up>
              +      <down>Pause</down>
              +      <info>XBMC.ActivateWindow(PVROSDChannels)</info>
              +      <back>XBMC.ActivateWindow(MyMusicPlaylist)</back>
              +      <select>Info</select>
              +      <menu>XBMC.ActivateWindow(MusicOSD)</menu>
              +      <start>XBMC.ActivateWindow(MusicOSD)</start>
              +    </remote>
              +  </Visualisation>
              +  <MusicOSD>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +      <info>CodecInfo</info>
              +    </remote>
              +  </MusicOSD>
              +  <VisualisationSettings>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +    </remote>
              +  </VisualisationSettings>
              +  <VisualisationPresetList>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +    </remote>
              +  </VisualisationPresetList>
              +  <SlideShow>
              +    <remote>
              +      <zero>ZoomNormal</zero>
              +      <one>ZoomLevel1</one>
              +      <two>ZoomLevel2</two>
              +      <three>ZoomLevel3</three>
              +      <four>ZoomLevel4</four>
              +      <five>ZoomLevel5</five>
              +      <six>ZoomLevel6</six>
              +      <seven>ZoomLevel7</seven>
              +      <eight>ZoomLevel8</eight>
              +      <nine>ZoomLevel9</nine>
              +      <info>CodecInfo</info>
              +      <pageplus>ZoomIn</pageplus>
              +      <pageminus>ZoomOut</pageminus>
              +      <select>Rotate</select>
              +      <up>Pause</up>
              +      <down>Play</down>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </SlideShow>
              +  <ScreenCalibration>
              +    <remote>
              +      <select>NextCalibration</select>
              +      <enter>NextCalibration</enter>
              +      <zero>ResetCalibration</zero>
              +      <display>NextResolution</display>
              +      <xbox>NextResolution</xbox>
              +    </remote>
              +  </ScreenCalibration>
              +  <GUICalibration>
              +    <remote>
              +      <select>NextCalibration</select>
              +      <enter>NextCalibration</enter>
              +      <zero>ResetCalibration</zero>
              +    </remote>
              +  </GUICalibration>
              +  <SelectDialog>
              +    <remote>
              +      <back>Close</back>
              +    </remote>
              +  </SelectDialog>
              +  <VideoOSD>
              +    <remote>
              +      <back>PreviousMenu</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +    </remote>
              +  </VideoOSD>
              +  <VideoMenu>
              +    <remote>
              +      <menu>OSD</menu>
              +      <back>PreviousMenu</back>
              +      <info>Info</info>
              +      <title>CodecInfo</title>
              +      <zero>Number0</zero>
              +      <one>Number1</one>
              +      <two>Number2</two>
              +      <three>Number3</three>
              +      <four>Number4</four>
              +      <five>Number5</five>
              +      <six>Number6</six>
              +      <seven>Number7</seven>
              +      <eight>Number8</eight>
              +      <nine>Number9</nine>
              +    </remote>
              +  </VideoMenu>
              +  <OSDVideoSettings>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +    </remote>
              +  </OSDVideoSettings>
              +  <OSDAudioSettings>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +    </remote>
              +  </OSDAudioSettings>
              +  <VideoBookmarks>
              +    <remote>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +      <zero>Delete</zero>
              +    </remote>
              +  </VideoBookmarks>
              +  <MyVideoLibrary>
              +    <remote>
              +      <zero>Queue</zero>
              +      <clear>Delete</clear>
              +      <green>ToggleWatched</green>
              +      <yellow>Queue</yellow>
              +    </remote>
              +  </MyVideoLibrary>
              +  <MyVideoFiles>
              +    <remote>
              +      <zero>Queue</zero>
              +      <star>Queue</star>
              +      <blue>ContextMenu</blue>
              +      <green>ToggleWatched</green>
              +      <yellow>Queue</yellow>
              +    </remote>
              +  </MyVideoFiles>
              +  <MyPictures>
              +    <remote>
              +      <zero>Queue</zero>
              +      <star>Queue</star>
              +      <start>ContextMenu</start>
              +    </remote>
              +  </MyPictures>
              +  <MyVideoPlaylist>
              +    <remote>
              +      <back>Playlist</back>      <!-- Close playlist -->
              +      <clear>Delete</clear>
              +      <zero>Delete</zero>
              +    </remote>
              +  </MyVideoPlaylist>
              +  <VirtualKeyboard>
              +    <remote>
              +      <back>BackSpace</back>
              +      <star>Shift</star>
              +      <hash>Symbols</hash>
              +      <zero>Number0</zero>
              +      <one>Number1</one>
              +      <two>Number2</two>
              +      <three>Number3</three>
              +      <four>Number4</four>
              +      <five>Number5</five>
              +      <six>Number6</six>
              +      <seven>Number7</seven>
              +      <eight>Number8</eight>
              +      <nine>Number9</nine>
              +      <pageminus>CursorLeft</pageminus>
              +      <pageplus>CursorRight</pageplus>
              +    </remote>
              +  </VirtualKeyboard>
              +  <ContextMenu>
              +    <remote>
              +      <blue>Close</blue>
              +      <back>Close</back>
              +    </remote>
              +  </ContextMenu>
              +  <FileStackingDialog>
              +    <remote>
              +      <back>Close</back>
              +    </remote>
              +  </FileStackingDialog>
              +  <Scripts>
              +    <remote>
              +      <info>XBMC.ActivateWindow(ScriptsDebugInfo)</info>
              +    </remote>
              +  </Scripts>
              +  <ScriptsDebugInfo>
              +    <remote>
              +      <info>Info</info>      <!-- clears debug python info -->
              +    </remote>
              +  </ScriptsDebugInfo>
              +  <NumericInput>
              +    <remote>
              +      <zero>Number0</zero>
              +      <one>Number1</one>
              +      <two>Number2</two>
              +      <three>Number3</three>
              +      <four>Number4</four>
              +      <five>Number5</five>
              +      <six>Number6</six>
              +      <seven>Number7</seven>
              +      <eight>Number8</eight>
              +      <nine>Number9</nine>
              +      <back>BackSpace</back>
              +    </remote>
              +  </NumericInput>
              +  <Weather>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </Weather>
              +  <Settings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </Settings>
              +  <MyPicturesSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </MyPicturesSettings>
              +  <MyProgramsSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </MyProgramsSettings>
              +  <MyWeatherSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </MyWeatherSettings>
              +  <MyMusicSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </MyMusicSettings>
              +  <SystemSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </SystemSettings>
              +  <MyVideosSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </MyVideosSettings>
              +  <NetworkSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </NetworkSettings>
              +  <AppearanceSettings>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </AppearanceSettings>
              +  <Profiles>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </Profiles>
              +  <systeminfo>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </systeminfo>
              +  <shutdownmenu>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </shutdownmenu>
              +  <submenu>
              +    <remote>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </submenu>
              +  <MusicInformation>
              +    <remote>
              +      <back>Close</back>
              +    </remote>
              +  </MusicInformation>
              +  <MovieInformation>
              +    <remote>
              +      <back>Close</back>
              +    </remote>
              +  </MovieInformation>
              +  <LockSettings>
              +    <remote>
              +      <menu>Close</menu>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </LockSettings>
              +  <ProfileSettings>
              +    <remote>
              +      <menu>Close</menu>
              +      <back>PreviousMenu</back>
              +    </remote>
              +  </ProfileSettings>
              +  <PictureInfo>
              +    <remote>
              +      <skipplus>NextPicture</skipplus>
              +      <skipminus>PreviousPicture</skipminus>
              +      <info>Close</info>
              +      <back>Close</back>
              +    </remote>
              +  </PictureInfo>
              +  <Teletext>
              +    <remote>
              +      <zero>number0</zero>
              +      <one>number1</one>
              +      <two>number2</two>
              +      <three>number3</three>
              +      <four>number4</four>
              +      <five>number5</five>
              +      <six>number6</six>
              +      <seven>number7</seven>
              +      <eight>number8</eight>
              +      <nine>number9</nine>
              +      <red>Red</red>
              +      <green>Green</green>
              +      <yellow>Yellow</yellow>
              +      <blue>Blue</blue>
              +      <info>Info</info>
              +      <back>Close</back>
              +      <menu>Close</menu>
              +      <start>Close</start>
              +      <teletext>Close</teletext>
              +    </remote>
              +  </Teletext>
              +  <Favourites>
              +    <remote>
              +      <back>Close</back>
              +    </remote>
              +  </Favourites>
              +</keymap>
               
        -
        -

        8.22 dvd

        -
        -
        -

        8.22.1 tasks

        -
        -
        1. install libdvd-pkg, allow programs to eject optical media
          +
          +

          8.23 dvd

          +
          +
          +

          8.23.1 tasks

          +
          +
          1. install libdvd-pkg, allow programs to eject optical media
            -
            ---
            -# file: roles/dvd/tasks/main.yml
            +
            ---
            +# file: roles/dvd/tasks/main.yml
             
            -- name: preconfigure libdvd-pkg
            -  shell: |
            -    echo 'libdvd-pkg libdvd-pkg/post-invoke_hook-install boolean true' | debconf-set-selections
            -    echo 'libdvd-pkg libdvd-pkg/build boolean true' | debconf-set-selections
            +- name: preconfigure libdvd-pkg
            +  shell: |
            +    echo 'libdvd-pkg libdvd-pkg/post-invoke_hook-install boolean true' | debconf-set-selections
            +    echo 'libdvd-pkg libdvd-pkg/build boolean true' | debconf-set-selections
             
            -- name: apt | install libdvd-pkg
            -  apt:
            -    name: '{{ item }}'
            -    state: present
            -    install_recommends: no
            -  with_items:
            +- name: apt | install libdvd-pkg
            +  apt:
            +    name: '{{ item }}'
            +    state: present
            +    install_recommends: no
            +  with_items:
                 - libdvd-pkg
             
            -- name: change udev rule to allow KODI to eject optical disks
            -  shell: sed 's/--lock-media //' /lib/udev/rules.d/60-cdrom_id.rules > /etc/udev/rules.d/60-cdrom_id.rules
            -  args:
            -    creates: /etc/udev/rules.d/60-cdrom_id.rules
            +- name: change udev rule to allow KODI to eject optical disks
            +  shell: sed 's/--lock-media //' /lib/udev/rules.d/60-cdrom_id.rules > /etc/udev/rules.d/60-cdrom_id.rules
            +  args:
            +    creates: /etc/udev/rules.d/60-cdrom_id.rules
             
          -
          -

          8.23 template-test

          -
          +
          +

          8.24 template-test

          +
          -
          ---
          +
          ---
           
          -- name: show vars
          -  debug: 
          -    var: '{{ system }}'
          +- name: show vars
          +  debug: 
          +    var: '{{ system }}'
           
          -- name: test templates
          -  template:
          -    src: templates/test.j2
          -    dest: /tmp/test.txt
          +- name: test templates
          +  template:
          +    src: templates/test.j2
          +    dest: /tmp/test.txt
           
          {{ ansible_managed_file | comment }}
           
          -Section "ServerLayout"
          -    Identifier     "Layout0"
          -    Screen      0  "Screen0"
          +Section "ServerLayout"
          +    Identifier     "Layout0"
          +    Screen      0  "Screen0"
               {% if system.x11.dualhead.enabled %}
          -    Screen      1  "Screen1" RightOf "Screen0"
          +    Screen      1  "Screen1" RightOf "Screen0"
               {% endif %}
          -    InputDevice    "Keyboard0" "CoreKeyboard"
          -    InputDevice    "Mouse0" "CorePointer"
          +    InputDevice    "Keyboard0" "CoreKeyboard"
          +    InputDevice    "Mouse0" "CorePointer"
           EndSection
           
          -Section "InputDevice"
          -    # generated from default
          -    Identifier     "Mouse0"
          -    Driver         "mouse"
          -    Option         "Protocol" "auto"
          -    Option         "Device" "/dev/psaux"
          -    Option         "Emulate3Buttons" "no"
          -    Option         "ZAxisMapping" "4 5"
          +Section "InputDevice"
          +    # generated from default
          +    Identifier     "Mouse0"
          +    Driver         "mouse"
          +    Option         "Protocol" "auto"
          +    Option         "Device" "/dev/psaux"
          +    Option         "Emulate3Buttons" "no"
          +    Option         "ZAxisMapping" "4 5"
           EndSection
           
          -# ignore devices with eventlircd tag 
          -# ENV{ID_INPUT.tags}+="eventlircd"
          -# must be set by an udev rule
          -Section "InputClass"
          -    Identifier "ignore eventlircd devices"
          -    MatchTag "eventlircd"
          -    Option "Ignore" "True"
          +# ignore devices with eventlircd tag 
          +# ENV{ID_INPUT.tags}+="eventlircd"
          +# must be set by an udev rule
          +Section "InputClass"
          +    Identifier "ignore eventlircd devices"
          +    MatchTag "eventlircd"
          +    Option "Ignore" "True"
           EndSection
           
           
           
          -Section "InputDevice"
          -    # generated from default
          -    Identifier     "Keyboard0"
          -    Driver         "kbd"
          +Section "InputDevice"
          +    # generated from default
          +    Identifier     "Keyboard0"
          +    Driver         "kbd"
           EndSection
           
           
          -Section "Monitor"
          -    Identifier     "Monitor0"
          -    VendorName     "Unknown"
          -    ModelName      "Unknown"
          -{% if system.x11.display.0.default == "VGA2Scart_4_3" or system.x11.display.0.default == "VGA2Scart_16_9" %}
          +Section "Monitor"
          +    Identifier     "Monitor0"
          +    VendorName     "Unknown"
          +    ModelName      "Unknown"
          +{% if system.x11.display.0.default == "VGA2Scart_4_3" or system.x11.display.0.default == "VGA2Scart_16_9" %}
               HorizSync       14-17
               VertRefresh     49-61
          -    {% if system.x11.display.0.default == "VGA2Scart_4_3" %}
          -    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
          -    {% elif system.x11.display.0.default == "VGA2Scart_16_9" %}
          -    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
          +    {% if system.x11.display.0.default == "VGA2Scart_4_3" %}
          +    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
          +    {% elif system.x11.display.0.default == "VGA2Scart_16_9" %}
          +    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
               {% endif %}
           {% endif %}
          -    Option         "DPMS"
          -    Option         "ExactModeTimingsDVI" "True"
          +    Option         "DPMS"
          +    Option         "ExactModeTimingsDVI" "True"
           EndSection
           
           
          -{% if system.x11.dualhead.enabled == "1" %}
          -Section "Monitor"
          -    Identifier     "Monitor1"
          -    VendorName     "Unknown"
          -    ModelName      "Unknown"
          -{% if system.x11.display.1.default in ("VGA2Scart_4_3",  "VGA2Scart_16_9") %}
          +{% if system.x11.dualhead.enabled == "1" %}
          +Section "Monitor"
          +    Identifier     "Monitor1"
          +    VendorName     "Unknown"
          +    ModelName      "Unknown"
          +{% if system.x11.display.1.default in ("VGA2Scart_4_3",  "VGA2Scart_16_9") %}
               HorizSync       14-17
               VertRefresh     49-61
          -    {% if system.x11.display.1.default == "VGA2Scart_4_3" %}
          -    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
          -    {% elif system.x11.display.1.default == "VGA2Scart_16_9" %}
          -    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
          +    {% if system.x11.display.1.default == "VGA2Scart_4_3" %}
          +    Modeline "VGA2Scart_4_3" 13.875 720 744 808 888 576 580 585 625 -HSync -Vsync interlace
          +    {% elif system.x11.display.1.default == "VGA2Scart_16_9" %}
          +    Modeline "VGA2Scart_16_9" 19 1024 1032 1120 1216 576 581 586 625 -Hsync -Vsync interlace
               {% endif %}
          -    Option         "DPMS"
          -    Option         "ExactModeTimingsDVI" "True"
          +    Option         "DPMS"
          +    Option         "ExactModeTimingsDVI" "True"
           {% endif %}
           EndSection
           {% endif %}
           
          -Section "Device"
          -    Identifier     "Device0"
          +Section "Device"
          +    Identifier     "Device0"
           {% if system.hardware.nvidia.detected %}
          -    Driver         "nvidia"
          -    VendorName     "NVIDIA Corporation"
          +    Driver         "nvidia"
          +    VendorName     "NVIDIA Corporation"
           {% endif %}
               Screen          0
          -    Option         "DPI" "100x100"
          +    Option         "DPI" "100x100"
           {% if system.hardware.nvidia.busid %}
          -    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
          +    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
           {% endif %}
          -    Option         "NoLogo" "True"
          -    Option         "UseEvents" "True"
          -    Option         "TripleBuffer" "False"
          -    Option         "AddARGBGLXVisuals" "True"
          -    Option         "TwinView" "0"
          -    Option         "DynamicTwinView" "0"
          -    Option         "OnDemandVBlankinterrupts" "on"
          -    Option         "FlatPanelProperties" "Scaling = Native"
          +    Option         "NoLogo" "True"
          +    Option         "UseEvents" "True"
          +    Option         "TripleBuffer" "False"
          +    Option         "AddARGBGLXVisuals" "True"
          +    Option         "TwinView" "0"
          +    Option         "DynamicTwinView" "0"
          +    Option         "OnDemandVBlankinterrupts" "on"
          +    Option         "FlatPanelProperties" "Scaling = Native"
           EndSection
           
          -{% if system.x11.dualhead.enabled == "1" %}
          -Section "Device"
          -    Identifier     "Device1"
          +{% if system.x11.dualhead.enabled == "1" %}
          +Section "Device"
          +    Identifier     "Device1"
               {% if system.hardware.nvidia.detected %}
          -    Driver         "nvidia"
          -    VendorName     "NVIDIA Corporation"
          +    Driver         "nvidia"
          +    VendorName     "NVIDIA Corporation"
               {% endif %}
               Screen          1
               {% if system.hardware.nvidia.busid %}
          -    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
          +    BusID          "PCI: {{ system.hardware.nvidia.busid }}"
               {% endif %}
          -    Option         "NoLogo" "True"
          -    Option         "UseEvents" "True"
          -    Option         "TripleBuffer" "False"
          -    Option         "AddARGBGLXVisuals" "True"
          -    Option         "TwinView" "0"
          -    Option         "DynamicTwinView" "0"
          +    Option         "NoLogo" "True"
          +    Option         "UseEvents" "True"
          +    Option         "TripleBuffer" "False"
          +    Option         "AddARGBGLXVisuals" "True"
          +    Option         "TwinView" "0"
          +    Option         "DynamicTwinView" "0"
           EndSection
           {% endif %}
           
           
          -Section "Screen"
          -    Identifier     "Screen0"
          -    Device         "Device0"
          -    Monitor        "Monitor0"
          +Section "Screen"
          +    Identifier     "Screen0"
          +    Device         "Device0"
          +    Monitor        "Monitor0"
               DefaultDepth    24
          -    SubSection     "Display"
          +    SubSection     "Display"
                   Depth       24
           {% if system.x11.display.0.default is defined and system.x11.display.0.default %}
          -        Modes      "{{ system.x11.display.0.default }}"{% for mode in system.x11.display.0.mode %}{% if mode != system.x11.display.0.default %} "{{ mode }}"{% endif %}{% endfor %}
          +        Modes      "{{ system.x11.display.0.default }}"{% for mode in system.x11.display.0.mode %}{% if mode != system.x11.display.0.default %} "{{ mode }}"{% endif %}{% endfor %}
           
           {% elif system.hardware.nvidia.detected == 1 %}
          -        Modes      "nvidia-auto-select"
          +        Modes      "nvidia-auto-select"
           {% endif %}
               EndSubSection
           {% if system.x11.display.0.default or system.x11.default %}
               {% if system.x11.display.0.device is definded and system.x11.display.0.device %}
          -    Option         "ConnectedMonitor" {{ system.x11.display.0.device }}
          +    Option         "ConnectedMonitor" {{ system.x11.display.0.device }}
               {% else %}
          -    Option         "ConnectedMonitor" {{ system.x11.default }}
          +    Option         "ConnectedMonitor" {{ system.x11.default }}
               {% endif %}
          -    #     Option         "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
          -    #Option         "ConnectedMonitor"
          -    "<?cs if:(?system.x11.display.0.device) ?>
          -          <?cs call:fix_display_name(system.x11.display.0.device) ?>
          -     <?cs else ?>
          -          <?cs var:system.x11.default ?>
          -     <?cs /if ?>
          -     <?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
          -#     Option         "UseDisplayDevice" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?>"
          -# <?cs /if ?>
          -# <?cs if:(?system.hardware.nvidia.0.edid && system.hardware.nvidia.0.edid == "1") ?>
          -#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.0.device) ?>:/etc/X11/edid.0.yavdr"
          -# <?cs /if ?>
          -# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.0.device) ?>
          -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:system.x11.display.0.default ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"
          -# <?cs each:mode = system.x11.display.0.mode ?><?cs if:(mode != system.x11.display.0.default) ?>
          -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?> 
          +    #     Option         "ConnectedMonitor" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?><?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
          +    #Option         "ConnectedMonitor"
          +    "<?cs if:(?system.x11.display.0.device) ?>
          +          <?cs call:fix_display_name(system.x11.display.0.device) ?>
          +     <?cs else ?>
          +          <?cs var:system.x11.default ?>
          +     <?cs /if ?>
          +     <?cs if:(?system.x11.dualhead.enabled && system.x11.dualhead.enabled == 1) ?>, <?cs call:fix_display_name(system.x11.display.1.device) ?><?cs /if ?>"
          +#     Option         "UseDisplayDevice" "<?cs if:(?system.x11.display.0.device) ?><?cs call:fix_display_name(system.x11.display.0.device) ?><?cs else ?><?cs var:system.x11.default ?><?cs /if ?>"
          +# <?cs /if ?>
          +# <?cs if:(?system.hardware.nvidia.0.edid && system.hardware.nvidia.0.edid == "1") ?>
          +#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.0.device) ?>:/etc/X11/edid.0.yavdr"
          +# <?cs /if ?>
          +# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.0.device) ?>
          +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:system.x11.display.0.default ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"
          +# <?cs each:mode = system.x11.display.0.mode ?><?cs if:(mode != system.x11.display.0.default) ?>
          +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.0.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.0.viewport.in.x ?>x<?cs var:system.x11.display.0.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.0.viewport.out.x ?>x<?cs var:system.x11.display.0.viewport.out.y ?>+<?cs var:system.x11.display.0.viewport.out.plusx ?>+<?cs var:system.x11.display.0.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?> 
           {% endif %}
           EndSection
           
          -{% if system.x11.dualhead.enabled == "1" %}
          -Section "Screen"
          +{% if system.x11.dualhead.enabled == "1" %}
          +Section "Screen"
           
          -     Identifier     "Screen1"
          -     Device         "Device1"
          -     Monitor        "Monitor1"
          +     Identifier     "Screen1"
          +     Device         "Device1"
          +     Monitor        "Monitor1"
                DefaultDepth    24
          -     SubSection     "Display"
          +     SubSection     "Display"
                    Depth       24
           {% if system.x11.display.0.default is defined and system.x11.display.0.default %}
          -         Modes      "{{ system.x11.display.1.default }}"{% for mode in system.x11.display.1.mode %}{% if mode != system.x11.display.1.default %} "{{ mode }}"{% endif %}{% endfor %}
          +         Modes      "{{ system.x11.display.1.default }}"{% for mode in system.x11.display.1.mode %}{% if mode != system.x11.display.1.default %} "{{ mode }}"{% endif %}{% endfor %}
           
          -{% elif system.hardware.nvidia.detected == "1" %}
          -         Modes      "nvidia-auto-select"
          +{% elif system.hardware.nvidia.detected == "1" %}
          +         Modes      "nvidia-auto-select"
           {% endif %}
                 EndSubSection
           
          -# <?cs if:(?system.x11.display.1.default && system.x11.display.1.default != "" && system.x11.display.1.default != "disabled") ?>
          -#     Option         "UseDisplayDevice" "<?cs call:fix_display_name(system.x11.display.1.device) ?>"
          -# <?cs /if ?>
          -# <?cs if:(?system.hardware.nvidia.1.edid && system.hardware.nvidia.1.edid == "1") ?>
          -#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.1.device) ?>:/etc/X11/edid.1.yavdr"
          -# <?cs /if ?>
          -# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.1.device) ?>
          -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:system.x11.display.1.default ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"
          -# <?cs each:mode = system.x11.display.1.mode ?><?cs if:(mode != system.x11.display.1.default) ?>
          -#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?>
          -# <?cs /if ?>
          +# <?cs if:(?system.x11.display.1.default && system.x11.display.1.default != "" && system.x11.display.1.default != "disabled") ?>
          +#     Option         "UseDisplayDevice" "<?cs call:fix_display_name(system.x11.display.1.device) ?>"
          +# <?cs /if ?>
          +# <?cs if:(?system.hardware.nvidia.1.edid && system.hardware.nvidia.1.edid == "1") ?>
          +#     Option         "CustomEDID" "<?cs call:fix_display_name(system.x11.display.1.device) ?>:/etc/X11/edid.1.yavdr"
          +# <?cs /if ?>
          +# <?cs if:(system.hardware.nvidia.detected == 1 && ?system.x11.display.1.device) ?>
          +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:system.x11.display.1.default ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"
          +# <?cs each:mode = system.x11.display.1.mode ?><?cs if:(mode != system.x11.display.1.default) ?>
          +#     Option          "MetaModes" "<?cs call:fix_display_name(system.x11.display.1.device) ?>: <?cs var:mode ?> { ViewPortIn=<?cs var:system.x11.display.1.viewport.in.x ?>x<?cs var:system.x11.display.1.viewport.in.y ?>, ViewPortOut=<?cs var:system.x11.display.1.viewport.out.x ?>x<?cs var:system.x11.display.1.viewport.out.y ?>+<?cs var:system.x11.display.1.viewport.out.plusx ?>+<?cs var:system.x11.display.1.viewport.out.plusy ?> }"<?cs /if ?><?cs /each ?>
          +# <?cs /if ?>
           EndSection
           {% endif %}
           
           {% if not system.x11.use_compositing %}
          -Section "Extensions"
          -# if not open-gl OSD is needed (e.g. for vdr-sxfe):
          -    Option         "Composite" "Disable"
          +Section "Extensions"
          +# if not open-gl OSD is needed (e.g. for vdr-sxfe):
          +    Option         "Composite" "Disable"
           EndSection
           {% endif %}
           
          -
          foo:
          +
          foo:
             - bar
             - baz
             - spam
           
          -system:
          -  hardware:
          -    nvidia:
          -      detected: "1"
          -      busid: "000:2304:234"
          -  x11:
          -    dualhead:
          -      enabled: "0"
          -    display:
          -      0:
          -        mode:
          -          - "1920x1080_50"
          -        default: "nvidia-auto"
          +system:
          +  hardware:
          +    nvidia:
          +      detected: "1"
          +      busid: "000:2304:234"
          +  x11:
          +    dualhead:
          +      enabled: "0"
          +    display:
          +      0:
          +        mode:
          +          - "1920x1080_50"
          +        default: "nvidia-auto"
           
          -      1:
          -        mode:
          -          - "1280x720_60"
          +      1:
          +        mode:
          +          - "1280x720_60"
           
          -
          -

          8.24 grub-config

          -
          -
          -

          8.24.1 default variables

          -
          +
          +

          8.25 grub-config

          +
          +
          +

          8.25.1 default variables

          +
          -
          system:
          -  shutdown: poweroff
          -grub:
          -  timeout: 0
          -  boot_options: quiet nosplash
          +
          system:
          +  shutdown: poweroff
          +grub:
          +  timeout: 0
          +  boot_options: quiet nosplash
           
          -
          -

          8.24.2 tasks

          -
          +
          +

          8.25.2 tasks

          +
          -
          ---
          +
          ---
           
          -- name: custom grub configuration for timeout and reboot halt
          -  template:
          -    src: templates/50_custom.j2
          -    dest: /etc/grub.d/50_custom
          -    mode: '0775'
          -  notify: [ 'Update GRUB' ]
          +- name: custom grub configuration for timeout and reboot halt
          +  template:
          +    src: templates/50_custom.j2
          +    dest: /etc/grub.d/50_custom
          +    mode: '0775'
          +  notify: [ 'Update GRUB' ]
           
          -# TODO: add special case if plymouth is used
          -- name: let the system boot quietly
          -  lineinfile:
          -      dest: /etc/default/grub
          -      state: present
          -      regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=")'
          -      line: '\1{{ grub.boot_options}}"'
          -      backrefs: yes
          -  notify: [ 'Update GRUB' ]
          +# TODO: add special case if plymouth is used
          +- name: let the system boot quietly
          +  lineinfile:
          +      dest: /etc/default/grub
          +      state: present
          +      regexp: '^(GRUB_CMDLINE_LINUX_DEFAULT=")'
          +      line: '\1{{ grub.boot_options}}"'
          +      backrefs: yes
          +  notify: [ 'Update GRUB' ]
           
          -
          -

          8.24.3 templates

          -
          +
          +

          8.25.3 templates

          +
          -
          #!/bin/sh
          -exec tail -n +3 $0
          +
          #!/bin/sh
          +exec tail -n +3 $0
           
          -# This file is configured by the ansible configuration for yaVDR
          +# This file is configured by the ansible configuration for yaVDR
           
          -{% if system.shutdown is defined and system.shutdown == 'reboot' %}
          -menuentry "PowerOff" {
          +{% if system.shutdown is defined and system.shutdown == 'reboot' %}
          +menuentry "PowerOff" {
               halt
           }
           {% endif %}
           
          -if [ "${recordfail}" = 1 ]; then
          -    set timeout={{ 3 if grub.timeout < 3 else grub.timeout }}
          -else
          -    set timeout={{ grub.timeout if grub.timeout is defined else 0 }}
          -fi
          +if [ "${recordfail}" = 1 ]; then
          +    set timeout={{ 3 if grub.timeout < 3 else grub.timeout }}
          +else
          +    set timeout={{ grub.timeout if grub.timeout is defined else 0 }}
          +fi
           
          -
          -

          8.24.4 handlers

          -
          +
          +

          8.25.4 handlers

          +
          -
          ---
          +
          ---
           
          -- name: Update GRUB
          -  command: update-grub
          -  failed_when: ('error' in grub_register_update.stderr)
          -  register: grub_register_update
          +- name: Update GRUB
          +  command: update-grub
          +  failed_when: ('error' in grub_register_update.stderr)
          +  register: grub_register_update
           
          -  # TODO: Do we need to use grub-set-default?
          -  # https://github.com/yavdr/yavdr-utils/blob/master/events/actions/update-grub
          +  # TODO: Do we need to use grub-set-default?
          +  # https://github.com/yavdr/yavdr-utils/blob/master/events/actions/update-grub
           
          -
          -

          9 Modules

          +
          +

          9 Modules

          This section contains custom modules for the yaVDR Playbooks. They are used to collect facts about the system and configure applications and daemons.

          -
          -

          9.1 hardware_facts.py

          +
          +

          9.1 hardware_facts.py

          -
          # This Module collects the vendor- and device ids for USB- and PCI(e)-devices and currently loaded kernel modules.
          -DOCUMENTATION = '''
          -  ---
          -  module: hardware_facts
          -  short_description: collects facts for kernel modules, usb and pci devices
          -  description:
          -       - This Module collects the vendor- and device ids for USB- and PCI(e)-devices and
          -         currently loaded kernel modules.
          -  options:
          -      usb:
          -          required: False
          -          default: True
          -          description:
          -            - return a list of vendor- and device ids for usb devices in '04x:04x' notation
          +
          # This Module collects the vendor- and device ids for USB- and PCI(e)-devices and currently loaded kernel modules.
          +DOCUMENTATION = '''
          +  ---
          +  module: hardware_facts
          +  short_description: collects facts for kernel modules, usb and pci devices
          +  description:
          +       - This Module collects the vendor- and device ids for USB- and PCI(e)-devices and
          +         currently loaded kernel modules.
          +  options:
          +      usb:
          +          required: False
          +          default: True
          +          description:
          +            - return a list of vendor- and device ids for usb devices in '04x:04x' notation
           
          -    pci:
          -        required: False
          -        default: True
          -        description:
          -          - return a list of vendor- and device ids for pci devices in '04x:04x' notation
          +    pci:
          +        required: False
          +        default: True
          +        description:
          +          - return a list of vendor- and device ids for pci devices in '04x:04x' notation
           
          -    modules:
          -        required: False
          -        default: True
          -        description:
          -          - return a list of currently loaded kernel modules
          +    modules:
          +        required: False
          +        default: True
          +        description:
          +          - return a list of currently loaded kernel modules
           
          -    gpus:
          -        required: False
          -        default: True
          -        description:
          -          - return a list of devices of the pci gpu class (0x030000)
          -notes:
          -   - requres python-pyusb and python-kmodpy
          -requirements: [ ]
          -author: "Alexander Grothe <seahawk1986@gmx.de>"
          -'''
          +    gpus:
          +        required: False
          +        default: True
          +        description:
          +          - return a list of devices of the pci gpu class (0x030000)
          +notes:
          +   - requres python-pyusb and python-kmodpy
          +requirements: [ ]
          +author: "Alexander Grothe <seahawk1986@gmx.de>"
          +'''
           
          -EXAMPLES = '''
          -- name: get information about usb and pci hardware and loaded kernel modules
          -  hardware_facts:
          -    usb: True
          -    pci: True
          -    modules: True
          -- debug:
          -    var: usb
          -- debug
          -    var: pci
          -- debug
          -    var: modules
          -- debug
          -    var: gpus
          -'''
          +EXAMPLES = '''
          +- name: get information about usb and pci hardware and loaded kernel modules
          +  hardware_facts:
          +    usb: True
          +    pci: True
          +    modules: True
          +- debug:
          +    var: usb
          +- debug
          +    var: pci
          +- debug
          +    var: modules
          +- debug
          +    var: gpus
          +'''
           
          -import glob
          -import json
          -import os
          -import sys
          -import usb.core
          -from collections import namedtuple
          +import glob
          +import json
          +import os
          +import sys
          +import usb.core
          +from collections import namedtuple
           
          -import kmodpy
          -from ansible.module_utils.basic import *
          +import kmodpy
          +from ansible.module_utils.basic import *
           
           
          -PCIDevice = namedtuple("PCIDevice", 'idVendor idProduct idClass pciPath')
          +PCIDevice = namedtuple("PCIDevice", 'idVendor idProduct idClass pciPath')
           
          -def get_pci_devices():
          -    for device in glob.glob('/sys/devices/pci*/*:*:*/'):
          -        with open(os.path.join(device, 'device')) as d:
          -            product_id = int(d.read().strip(), 16)
          -        with open(os.path.join(device, 'vendor')) as d:
          -            vendor_id = int(d.read().strip(), 16)
          -        with open(os.path.join(device, 'class')) as d:
          -            class_id = int(d.read().strip(), 16)
          -        yield PCIDevice(idVendor=vendor_id, idProduct=product_id, idClass=class_id, pciPath=device)
          +vendor_dict = {
          +    0x10de: 'nvidia',
          +    0x8086: 'intel',
          +    0x1002: 'amd',
          +    0x80ee: 'virtualbox',
          +    }
           
          -def format_device_list(iterator):
          -    return ["{:04x}:{:04x}".format(d.idVendor, d.idProduct) for d in iterator]
          +def get_pci_devices():
          +    for device in glob.glob('/sys/devices/pci*/*:*:*/*:*:*/'):
          +        try:
          +            with open(os.path.join(device, 'device')) as d:
          +                product_id = int(d.read().strip(), 16)
          +            with open(os.path.join(device, 'vendor')) as d:
          +                vendor_id = int(d.read().strip(), 16)
          +            with open(os.path.join(device, 'class')) as d:
          +                class_id = int(d.read().strip(), 16)
          +            yield PCIDevice(idVendor=vendor_id, idProduct=product_id, idClass=class_id, pciPath=device)
          +        except IOError:
          +            pass
           
          -def format_gpu_device_list(iterator):
          -    def get_entries(iterator):
          -        for d in iterator:
          -            if d.idClass == 0x030000:
          -                yield ("{:04x}:{:04x}".format(d.idVendor, d.idProduct))
          -    return [entry for entry in get_entries(iterator)]
          +def format_device_list(iterator):
          +    return ["{:04x}:{:04x}".format(d.idVendor, d.idProduct) for d in iterator]
           
          -arg_specs = {
          -    'usb': dict(default=True, type='bool', required=False),
          -    'pci': dict(default=True, type='bool', required=False),
          -    'modules': dict(default=True, type='bool', required=False),
          -    'gpus': dict(default=True, type='bool', required=False),
          +def format_gpu_device_list(iterator):
          +    def get_entries(iterator):
          +        for d in iterator:
          +            if d.idClass == 0x030000:
          +                yield {"VendorName": vendor_dict.get(d.idVendor, "unknown"),
          +                       "VendorID": d.idVendor, "ProductID": d.idProduct}
          +    return [entry for entry in get_entries(iterator)]
          +
          +arg_specs = {
          +    'usb': dict(default=True, type='bool', required=False),
          +    'pci': dict(default=True, type='bool', required=False),
          +    'modules': dict(default=True, type='bool', required=False),
          +    'gpus': dict(default=True, type='bool', required=False),
               }
           
           
          -def main():
          -    module = AnsibleModule(argument_spec=arg_specs, supports_check_mode=True,)
          -    collect_usb = module.params['usb']
          -    collect_pci = module.params['pci']
          -    collect_modules = module.params['modules']
          -    collect_gpus = module.params['gpus']
          -    if collect_usb:
          -        usb_devices = format_device_list(usb.core.find(find_all=True))
          -    else:
          -        usb_device = []
          -    if collect_pci:
          -        pci_devices = format_device_list(get_pci_devices())
          -    else:
          -        pci_devices = []
          -    if collect_modules:
          -        k = kmodpy.Kmod()
          -        modules = [m[0] for m in k.loaded()]
          -    else:
          -        modules = []
          -    if collect_gpus:
          -        gpus = format_gpu_device_list(get_pci_devices())
          -    else:
          -        gpus = []
          -    data = {'usb': usb_devices, 'pci': pci_devices, 'modules': modules, 'gpus': gpus}
          -    module.exit_json(changed=False, ansible_facts=data, msg=data)
          +def main():
          +    module = AnsibleModule(argument_spec=arg_specs, supports_check_mode=True,)
          +    collect_usb = module.params['usb']
          +    collect_pci = module.params['pci']
          +    collect_modules = module.params['modules']
          +    collect_gpus = module.params['gpus']
          +    if collect_usb:
          +        usb_devices = format_device_list(usb.core.find(find_all=True))
          +    else:
          +        usb_device = []
          +    if collect_pci:
          +        pci_devices = format_device_list(get_pci_devices())
          +    else:
          +        pci_devices = []
          +    if collect_modules:
          +        k = kmodpy.Kmod()
          +        modules = [m[0] for m in k.loaded()]
          +    else:
          +        modules = []
          +    if collect_gpus:
          +        gpus = format_gpu_device_list(get_pci_devices())
          +    else:
          +        gpus = []
          +    data = {'usb': usb_devices, 'pci': pci_devices, 'modules': modules, 'gpus': gpus}
          +    module.exit_json(changed=False, ansible_facts=data, msg=data)
           
           
          -if __name__ == '__main__':  
          +if __name__ == '__main__':  
               main()
           
          -
          -

          9.2 satip_facts.py

          +
          +

          9.2 satip_facts.py

          -
          DOCUMENTATION = '''
          ----
          -module: hardware_facts
          -short_description: "check if at least one SAT>IP server responds on the network"
          -description:
          -     - This script sends a multicast message and awaits responses by Sat>IP servers.
          -       Returns the boolean variable 'satip_detected'
          -'''
          -EXAMPLES = '''
          -- name: "detect SAT>IP Server on the network"
          -  action: satip_facts
          +
          DOCUMENTATION = '''
          +---
          +module: hardware_facts
          +short_description: "check if at least one SAT>IP server responds on the network"
          +description:
          +     - This script sends a multicast message and awaits responses by Sat>IP servers.
          +       Returns the boolean variable 'satip_detected'
          +'''
          +EXAMPLES = '''
          +- name: "detect SAT>IP Server on the network"
          +  action: satip_facts
           
          -- debug:
          -    var: satip_detected
          -'''
          +- debug:
          +    var: satip_detected
          +'''
           
          -import json
          -import socket
          -import sys
          -import time
          +import json
          +import socket
          +import sys
          +import time
           
          -from ansible.module_utils.basic import *
          +from ansible.module_utils.basic import *
           
          -SSDP_ADDR = "239.255.255.250"
          -SSDP_PORT = 1900
          -# SSDP_MX = max delay for server response
          -# a value of 2s is recommended by the SAT>IP specification 1.2.2
          -SSDP_MX = 2
          -SSDP_ST = "urn:ses-com:device:SatIPServer:1"
          +SSDP_ADDR = "239.255.255.250"
          +SSDP_PORT = 1900
          +# SSDP_MX = max delay for server response
          +# a value of 2s is recommended by the SAT>IP specification 1.2.2
          +SSDP_MX = 2
          +SSDP_ST = "urn:ses-com:device:SatIPServer:1"
           
          -ssdpRequest = "\r\n".join((
          -    "M-SEARCH * HTTP/1.1",
          -    "HOST: %s:%d" % (SSDP_ADDR, SSDP_PORT),
          -    "MAN: \"ssdp:discover\"",
          -    "MX: %d" % (SSDP_MX),
          -    "ST: %s" % (SSDP_ST),
          -    "\r\n"))
          +ssdpRequest = "\r\n".join((
          +    "M-SEARCH * HTTP/1.1",
          +    "HOST: %s:%d" % (SSDP_ADDR, SSDP_PORT),
          +    "MAN: \"ssdp:discover\"",
          +    "MX: %d" % (SSDP_MX),
          +    "ST: %s" % (SSDP_ST),
          +    "\r\n"))
           
          -def main():
          -    module = AnsibleModule(argument_spec={}, supports_check_mode=True,)
          -    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          -    # according to Sat>IP Specification 1.2.2, p. 20
          -    # a client should send three requests within 100 ms with a ttl of 2
          +def main():
          +    module = AnsibleModule(argument_spec={}, supports_check_mode=True,)
          +    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          +    # according to Sat>IP Specification 1.2.2, p. 20
          +    # a client should send three requests within 100 ms with a ttl of 2
               sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
               sock.settimeout(SSDP_MX + 0.5)
          -    for _ in range(3):
          +    for _ in range(3):
                   sock.sendto(ssdpRequest, (SSDP_ADDR, SSDP_PORT))
                   time.sleep(0.03)
          -    try:
          -        response = sock.recv(1000)
          -        if response and "SERVER:" in response:
          -            got_response = True
          -        else:
          -            raise ValueError('No satip server detected')
          -    except (socket.timeout, ValueError):
          -        got_response = False
          +    try:
          +        response = sock.recv(1000)
          +        if response and "SERVER:" in response:
          +            got_response = True
          +        else:
          +            raise ValueError('No satip server detected')
          +    except (socket.timeout, ValueError):
          +        got_response = False
           
          -    module.exit_json(changed=False, ansible_facts={'satip_detected': got_response})
          +    module.exit_json(changed=False, ansible_facts={'satip_detected': got_response})
           
          -if __name__ == '__main__':  
          +if __name__ == '__main__':  
               main()
           
          -
          -

          9.3 xrandr_facts.py

          +
          +

          9.3 xrandr_facts.py

          • [ ] support multiple screens (-d :0.0 .. :0.n)
          -
          from __future__ import print_function
          -import ast
          -import binascii
          -import csv
          -import re
          -import subprocess
          -from collections import namedtuple
          +
          from __future__ import print_function
          +import ast
          +import binascii
          +import csv
          +import re
          +import subprocess
          +from collections import namedtuple
           
          -from ansible.module_utils.basic import *
          +from ansible.module_utils.basic import *
           
          -DOCUMENTATION = '''
          ----
          -module: xrandr_facts
          -short_description: "gather facts about connected monitors and available modelines"
          -description:
          -     - This module needs a running x-server on a given display in order to successfully call xrandr.
          -       Returns the dictionary "xrandr", wich contains all screens with output states, connected displays,
          -       EDID info and their modes and a recommendation for the best fitting tv mode.
          -options:
          -    display:
          -        required: False
          -        default: ":0"
          -        description:
          -          - the DISPLAY variable to use when calling xrandr
          -    preferred_outpus:
          -        required: False
          -        default: ["HDMI", "DP", "DVI", "VGA", "TV": 0]
          -        description:
          -          - ranking of the preferred display connectors
          -    preferred_refreshrates:
          -        required: False
          -        default: ["50", "60", "75", "30", "25"]
          -        description:
          -          - ranking of the preferred display refreshrate
          -    preferred_resolutions:
          -        required: False
          -        default: ["7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"]
          -        description:
          -           - ranking of the preferred display resolutions
          -    write_edids:
          -        required: False
          -        default: True
          -        description:
          -           - write edid data to /etc/X11/edid.{connector}.bin
          -'''
          -EXAMPLES = '''
          -- name: "collect facts for connected displays"
          -  action: xserver_facts
          -    display: ":0"
          +DOCUMENTATION = '''
          +---
          +module: xrandr_facts
          +short_description: "gather facts about connected monitors and available modelines"
          +description:
          +     - This module needs a running x-server on a given display in order to successfully call xrandr.
          +       Returns the dictionary "xrandr", wich contains all screens with output states, connected displays,
          +       EDID info and their modes and a recommendation for the best fitting tv mode.
          +options:
          +    display:
          +        required: False
          +        default: ":0"
          +        description:
          +          - the DISPLAY variable to use when calling xrandr
          +    preferred_outpus:
          +        required: False
          +        default: ["HDMI", "DP", "DVI", "VGA", "TV": 0]
          +        description:
          +          - ranking of the preferred display connectors
          +    preferred_refreshrates:
          +        required: False
          +        default: ["50", "60", "75", "30", "25"]
          +        description:
          +          - ranking of the preferred display refreshrate
          +    preferred_resolutions:
          +        required: False
          +        default: ["7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"]
          +        description:
          +           - ranking of the preferred display resolutions
          +    write_edids:
          +        required: False
          +        default: True
          +        description:
          +           - write edid data to /etc/X11/edid.{connector}.bin
          +'''
          +EXAMPLES = '''
          +- name: "collect facts for connected displays"
          +  action: xserver_facts
          +    display: ":0"
           
          -- debug:
          -    var: xrandr
          +- debug:
          +    var: xrandr
           
          -- debug:
          -    var: xorg
          -'''
          +- debug:
          +    var: xorg
          +'''
           
          -ARG_SPECS = {
          -    'display': dict(default=":0", type='str', required=False),
          -    'preferred_outputs': dict(
          -        default=["HDMI", "DP", "DVI", "VGA", "TV"], type='list', required=False),
          -    'preferred_refreshrates': dict(
          -        default=[50, 60, 75, 30, 25], type='list', required=False),
          -    'preferred_resolutions': dict(
          +ARG_SPECS = {
          +    'display': dict(default=":0", type='str', required=False),
          +    'preferred_outputs': dict(
          +        default=["HDMI", "DP", "DVI", "VGA", "TV"], type='list', required=False),
          +    'preferred_refreshrates': dict(
          +        default=[50, 60, 75, 30, 25], type='list', required=False),
          +    'preferred_resolutions': dict(
                   default=[
          -            "7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"],
          -        type='list', required=False),
          -    'write_edids': dict(default=True, type='bool', required=False),
          +            "7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"],
          +        type='list', required=False),
          +    'write_edids': dict(default=True, type='bool', required=False),
               }
           
          -SCREEN_REGEX = re.compile("^(?P<screen>Screen\s\d+:)(?:.*)")
          -CONNECTOR_REGEX = re.compile(
          -    "^(?P<connector>.*-\d+)\s(?P<connection_state>connected|disconnected)\s(?P<primary>primary)?")
          -MODE_REGEX = re.compile("^\s+(?P<resolution>\d{3,}x\d{3,}).*")
          +SCREEN_REGEX = re.compile("^(?P<screen>Screen\s\d+:)(?:.*)")
          +CONNECTOR_REGEX = re.compile(
          +    "^(?P<connector>.*-\d+)\s(?P<connection_state>connected|disconnected)\s(?P<primary>primary)?")
          +MODE_REGEX = re.compile("^\s+(?P<resolution>\d{3,}x\d{3,}).*")
           
          -Mode = namedtuple('Mode', ['connection', 'resolution', 'refreshrate'])
          +Mode = namedtuple('Mode', ['connection', 'resolution', 'refreshrate'])
           
          -def check_for_screen(line):
          -    """check line for screen information"""
          -    match = re.match(SCREEN_REGEX, line)
          -    if match:
          -        return match.groupdict()['screen']
          +def check_for_screen(line):
          +    """check line for screen information"""
          +    match = re.match(SCREEN_REGEX, line)
          +    if match:
          +        return match.groupdict()['screen']
           
          -def check_for_connection(line):
          -    """check line for connection name and state"""
          -    match = re.match(CONNECTOR_REGEX, line)
          -    connector = None
          -    is_connected = False
          -    if match:
          -        match = match.groupdict()
          -        connector = match['connector']
          -        is_connected = True if match['connection_state'] == 'connected' else False
          -    return connector, is_connected
          +def check_for_connection(line):
          +    """check line for connection name and state"""
          +    match = re.match(CONNECTOR_REGEX, line)
          +    connector = None
          +    is_connected = False
          +    if match:
          +        match = match.groupdict()
          +        connector = match['connector']
          +        is_connected = True if match['connection_state'] == 'connected' else False
          +    return connector, is_connected
           
          -def get_indentation(line):
          -    """return the number of leading whitespace characters"""
          -    return len(line) - len(line.lstrip())
          +def get_indentation(line):
          +    """return the number of leading whitespace characters"""
          +    return len(line) - len(line.lstrip())
           
          -def sort_mode(mode):
          -    """rate modes by several criteria"""
          -    connection_score = 0
          -    rrate_score = 0
          -    resolution_score = 0
          -    preferred_rrates = module.params['preferred_refreshrates']
          -    # [50, 60]
          -    preferred_resolutions = module.params['preferred_resolutions']
          -    # ["7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"]
          -    preferred_outputs = module.params['preferred_outputs']
          -    # ["HDMI", "DP", "DVI", "VGA"]
          -    if mode.refreshrate in preferred_rrates:
          -        rrate_score = len(preferred_rrates) - preferred_rrates.index(mode.refreshrate)
          -    if mode.resolution in preferred_resolutions:
          -        resolution_score = len(preferred_resolutions) - preferred_resolutions.index(mode.resolution)
          -    x_resolution, y_resolution = (int(n) for n in  mode.resolution.split('x'))
          -    connection = mode.connection.split('-')[0]
          -    if connection in preferred_outputs:
          -        connection_score = len(preferred_outputs) - preferred_outputs.index(connection)
          -    return (rrate_score, resolution_score, x_resolution, y_resolution, connection_score)
          +def sort_mode(mode):
          +    """rate modes by several criteria"""
          +    connection_score = 0
          +    rrate_score = 0
          +    resolution_score = 0
          +    preferred_rrates = module.params['preferred_refreshrates']
          +    # [50, 60]
          +    preferred_resolutions = module.params['preferred_resolutions']
          +    # ["7680x4320", "3840x2160", "1920x1080", "1280x720", "720x576"]
          +    preferred_outputs = module.params['preferred_outputs']
          +    # ["HDMI", "DP", "DVI", "VGA"]
          +    if mode.refreshrate in preferred_rrates:
          +        rrate_score = len(preferred_rrates) - preferred_rrates.index(mode.refreshrate)
          +    if mode.resolution in preferred_resolutions:
          +        resolution_score = len(preferred_resolutions) - preferred_resolutions.index(mode.resolution)
          +    x_resolution, y_resolution = (int(n) for n in  mode.resolution.split('x'))
          +    connection = mode.connection.split('-')[0]
          +    if connection in preferred_outputs:
          +        connection_score = len(preferred_outputs) - preferred_outputs.index(connection)
          +    return (rrate_score, resolution_score, x_resolution, y_resolution, connection_score)
           
          -def parse_xrandr_verbose(iterator):
          -    """parse the output of xrandr --verbose using an iterator delivering single lines"""
          -    xorg = {}
          -    is_connected = False
          -    for line in iterator:
          -        if line.startswith('Screen'):
          -            screen = check_for_screen(line)
          -            xorg[screen] = {}
          -        elif 'connected' in line:
          -            connector, is_connected = check_for_connection(line)
          +def parse_xrandr_verbose(iterator):
          +    """parse the output of xrandr --verbose using an iterator delivering single lines"""
          +    xorg = {}
          +    is_connected = False
          +    for line in iterator:
          +        if line.startswith('Screen'):
          +            screen = check_for_screen(line)
          +            xorg[screen] = {}
          +        elif 'connected' in line:
          +            connector, is_connected = check_for_connection(line)
                       xorg[screen][connector] = {
          -                'is_connected': is_connected,
          -                'EDID': '',
          -                'modes': {},
          -                'preferred': '',
          -                'current': '',
          -                'auto': '',
          +                'is_connected': is_connected,
          +                'EDID': '',
          +                'modes': {},
          +                'preferred': '',
          +                'current': '',
          +                'auto': '',
                           }
          -        elif is_connected and 'EDID:' in line:
          -            edid_str = ""
          -            outer_indentation = get_indentation(line)
          -            while True:
          -                line = next(iterator)
          -                if get_indentation(line) > outer_indentation:
          -                    edid_str += line.strip()
          -                else:
          -                    break
          -            xorg[screen][connector]['EDID'] = edid_str
          -        elif is_connected and "MHz" in line and not "Interlace" in line:
          -            match = re.match(MODE_REGEX, line)
          -            if match:
          -                match = match.groupdict()
          -                preferred = bool("+preferred" in line)
          -                current = bool("*current" in line)
          +        elif is_connected and 'EDID:' in line:
          +            edid_str = ""
          +            outer_indentation = get_indentation(line)
          +            while True:
          +                line = next(iterator)
          +                if get_indentation(line) > outer_indentation:
          +                    edid_str += line.strip()
          +                else:
          +                    break
          +            xorg[screen][connector]['EDID'] = edid_str
          +        elif is_connected and "MHz" in line and not "Interlace" in line:
          +            match = re.match(MODE_REGEX, line)
          +            if match:
          +                match = match.groupdict()
          +                preferred = bool("+preferred" in line)
          +                current = bool("*current" in line)
           
          -                while True:
          -                    line = next(iterator)
          -                    if line.strip().startswith('v:'):                        
          -                        refresh_rate = ast.literal_eval(line.split()[-1][:-2])
          -                        rrate = int(round(refresh_rate))
          -                        if xorg[screen][connector]['modes'].get(match['resolution']) is None:
          -                            xorg[screen][connector]['modes'][match['resolution']] = []
          -                        if rrate not in xorg[screen][connector]['modes'][match['resolution']]:
          -                            xorg[screen][connector]['modes'][match['resolution']].append(rrate)
          -                        if preferred:
          -                            xorg[screen][connector]['preferred'] = "{}_{}".format(
          -                                match['resolution'], rrate)
          -                        if current:
          -                            xorg[screen][connector]['current'] = "{}_{}".format(
          -                                match['resolution'], rrate)
          -                        break
          -    return xorg
          +                while True:
          +                    line = next(iterator)
          +                    if line.strip().startswith('v:'):                        
          +                        refresh_rate = ast.literal_eval(line.split()[-1][:-2])
          +                        rrate = int(round(refresh_rate))
          +                        if xorg[screen][connector]['modes'].get(match['resolution']) is None:
          +                            xorg[screen][connector]['modes'][match['resolution']] = []
          +                        if rrate not in xorg[screen][connector]['modes'][match['resolution']]:
          +                            xorg[screen][connector]['modes'][match['resolution']].append(rrate)
          +                        if preferred:
          +                            xorg[screen][connector]['preferred'] = "{}_{}".format(
          +                                match['resolution'], rrate)
          +                        if current:
          +                            xorg[screen][connector]['current'] = "{}_{}".format(
          +                                match['resolution'], rrate)
          +                        break
          +    return xorg
           
          -def parse_edid_data(edid):
          -    vendor = "Unknown"
          -    model = "Unknown"
          -    data = subprocess.check_output("parse-edid < {}".format(edid), shell=True, universal_newlines=True)
          -    for line in data.splitlines():
          -        if "VendorName" in line:
          -            vendor = line.strip().split('"')[1]
          -        if "ModelName" in line:
          -            model =  line.strip().split('"')[1]
          -    return vendor, model
          +def parse_edid_data(edid):
          +    vendor = "Unknown"
          +    model = "Unknown"
          +    data = subprocess.check_output("parse-edid < {}".format(edid), shell=True, universal_newlines=True)
          +    for line in data.splitlines():
          +        if "VendorName" in line:
          +            vendor = line.strip().split('"')[1]
          +        if "ModelName" in line:
          +            model =  line.strip().split('"')[1]
          +    return vendor, model
           
          -def collect_nvidia_data():
          -    BusID_RE = re.compile((
          -        '(?P<domain>[0-9a-fA-F]+)'
          -        ':'
          -        '(?P<bus>[0-9a-fA-F]+)'
          -        ':'
          -        '(?P<device>[0-9a-fA-F]+)'
          -        '\.'
          -        '(?P<function>[0-9a-fA-F]+)'
          +def collect_nvidia_data():
          +    BusID_RE = re.compile((
          +        '(?P<domain>[0-9a-fA-F]+)'
          +        ':'
          +        '(?P<bus>[0-9a-fA-F]+)'
          +        ':'
          +        '(?P<device>[0-9a-fA-F]+)'
          +        '\.'
          +        '(?P<function>[0-9a-fA-F]+)'
                ))    
          -    try:
          -        data = subprocess.check_output(["nvidia-smi", "--query-gpu=name,pci.bus_id", "--format=csv", "-i0"],
          -                                universal_newlines=True)
          -    except subprocess.CalledProcessError:
          -        pass
          -    else:
          -        for row in csv.DictReader(data.splitlines(), delimiter=',', skipinitialspace=True):
          -            name = row['name']
          -            bus_id = row['pci.bus_id']
          -            # pci.bus_id structure as reported by nvidia-smi: "domain:bus:device.function", in hex.
          -            match = BusID_RE.search(bus_id)
          -            if match:
          -                domain, bus, device, function = (int(n, 16) for n in match.groups())
          -                bus_id = "PCI:{:d}@{:d}:{:d}:{:d}".format(bus, domain, device, function)
          -                return name, bus_id
          -    raise ValueError
          +    try:
          +        data = subprocess.check_output(["nvidia-smi", "--query-gpu=name,pci.bus_id", "--format=csv", "-i0"],
          +                                universal_newlines=True)
          +    except subprocess.CalledProcessError:
          +        pass
          +    else:
          +        for row in csv.DictReader(data.splitlines(), delimiter=',', skipinitialspace=True):
          +            name = row['name']
          +            bus_id = row['pci.bus_id']
          +            # pci.bus_id structure as reported by nvidia-smi: "domain:bus:device.function", in hex.
          +            match = BusID_RE.search(bus_id)
          +            if match:
          +                domain, bus, device, function = (int(n, 16) for n in match.groups())
          +                bus_id = "PCI:{:d}@{:d}:{:d}:{:d}".format(bus, domain, device, function)
          +                return name, bus_id
          +    raise ValueError
           
           
          -def output_data(data, write_edids=True):
          -    if data:
          -        modes = []
          -        for _, screen_data in data.items():
          -            for connector, connection_data in screen_data.items():
          -                if connection_data.get('EDID') and write_edids:
          -                    with open('/etc/X11/edid.{}.bin'.format(connector), 'wb') as edid:
          -                        edid.write(binascii.a2b_hex(connection_data['EDID']))
          -                for resolution, refreshrates in connection_data['modes'].items():
          -                    for refreshrate in refreshrates:
          +def output_data(data, write_edids=True):
          +    if data:
          +        modes = []
          +        for _, screen_data in data.items():
          +            for connector, connection_data in screen_data.items():
          +                if connection_data.get('EDID') and write_edids:
          +                    with open('/etc/X11/edid.{}.bin'.format(connector), 'wb') as edid:
          +                        edid.write(binascii.a2b_hex(connection_data['EDID']))
          +                for resolution, refreshrates in connection_data['modes'].items():
          +                    for refreshrate in refreshrates:
                                   modes.append(Mode(connector, resolution, refreshrate))
          -        if modes:
          -            result = {}
          -            try:
          -                gpu_name, bus_id = collect_nvidia_data()
          -            except ValueError:
          -                gpu_name = None
          -                bus_id = None
          +        if modes:
          +            result = {}
          +            try:
          +                gpu_name, bus_id = collect_nvidia_data()
          +            except ValueError:
          +                gpu_name = None
          +                bus_id = None
           
          -            def create_entry(my_dict, name, connector, resolution, refreshrate, vendor, model):
          -                my_dict[name] = {
          -                    'connector': connector,
          -                    'resolution': resolution,
          -                    'refreshrate': refreshrate,
          -                    'edid': '/etc/X11/edid.{}.bin'.format(connector),
          -                    'mode': "{}_{}".format(resolution, refreshrate),
          -                    'vendor': vendor,
          -                    'model': model,
          +            def create_entry(my_dict, name, connector, resolution, refreshrate, vendor, model):
          +                my_dict[name] = {
          +                    'connector': connector,
          +                    'resolution': resolution,
          +                    'refreshrate': refreshrate,
          +                    'edid': '/etc/X11/edid.{}.bin'.format(connector),
          +                    'mode': "{}_{}".format(resolution, refreshrate),
          +                    'vendor': vendor,
          +                    'model': model,
                           }
          -                if gpu_name and bus_id:
          -                    result[name]['gpu_name'] = gpu_name
          -                    result[name]['bus_id'] = bus_id
          +                if gpu_name and bus_id:
          +                    result[name]['gpu_name'] = gpu_name
          +                    result[name]['bus_id'] = bus_id
           
          -            connector_0, resolution_0, refreshrate_0 = max(modes, key=sort_mode)[:3]
          -            vendor_0, model_0 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_0))
          -            create_entry(result, 'primary', connector_0, resolution_0, refreshrate_0, vendor_0, model_0)
          +            connector_0, resolution_0, refreshrate_0 = max(modes, key=sort_mode)[:3]
          +            vendor_0, model_0 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_0))
          +            create_entry(result, 'primary', connector_0, resolution_0, refreshrate_0, vendor_0, model_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 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_1))
          -                create_entry(result, 'secondary', connector_1, resolution_1, refreshrate_1, vendor_1, model_1)
          +            # 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 = parse_edid_data('/etc/X11/edid.{}.bin'.format(connector_1))
          +                create_entry(result, 'secondary', connector_1, resolution_1, refreshrate_1, vendor_1, model_1)
           
          -    #print(json.dumps(data, sort_keys=True, indent=4))
          -    module.exit_json(changed=True if write_edids else False, ansible_facts={'xrandr': data, 'xorg': result})
          +    #print(json.dumps(data, sort_keys=True, indent=4))
          +    module.exit_json(changed=True if write_edids else False, ansible_facts={'xrandr': data, 'xorg': result})
           
          -if __name__ == '__main__':
          -    module = AnsibleModule(argument_spec=ARG_SPECS, supports_check_mode=False,)
          -    try:
          -        d = subprocess.check_output(['xrandr', '-d', module.params['display'], '--verbose'], universal_newlines=True).splitlines()
          -    except subprocess.CalledProcessError:
          -        xorg_data = {}
          -    else:
          -        xorg_data = parse_xrandr_verbose(iter(d))
          -    output_data(xorg_data, module.params['write_edids'])
          +if __name__ == '__main__':
          +    module = AnsibleModule(argument_spec=ARG_SPECS, supports_check_mode=False,)
          +    try:
          +        d = subprocess.check_output(['xrandr', '-d', module.params['display'], '--verbose'], universal_newlines=True).splitlines()
          +    except subprocess.CalledProcessError:
          +        xorg_data = {}
          +    else:
          +        xorg_data = parse_xrandr_verbose(iter(d))
          +    output_data(xorg_data, module.params['write_edids'])
           
          -
          -

          10 Handlers

          +
          +

          10 Handlers

          -
          - name: Restart Samba
          -  systemd:
          -    name: smbd.service
          -    state: restarted
          -    enabled: yes
          -    #masked: no
          -  register: samba_reload
          +
          - name: Restart Samba
          +  systemd:
          +    name: smbd.service
          +    state: restarted
          +    enabled: yes
          +    #masked: no
          +  register: samba_reload
           
          -- name: Restart NFS Kernel Server
          -  systemd:
          -    name: nfs-server.service
          -    state: restarted
          -    enabled: yes
          -    #masked: no
          -  register: nfs_reload
          +- name: Restart NFS Kernel Server
          +  systemd:
          +    name: nfs-server.service
          +    state: restarted
          +    enabled: yes
          +    #masked: no
          +  register: nfs_reload
           
          -- name: Restart VDR
          -  systemd:
          -    name: vdr.service
          -    state: restarted
          -    enabled: yes
          -  register: vdr_restart
          +- name: Restart VDR
          +  systemd:
          +    name: vdr.service
          +    state: restarted
          +    enabled: yes
          +  register: vdr_restart
           
          -- name: Stop VDR
          -  systemd:
          -    name: vdr.service
          -    state: stopped
          -    enabled: yes
          -  register: vdr_stop
          +- name: Stop VDR
          +  systemd:
          +    name: vdr.service
          +    state: stopped
          +    enabled: yes
          +  register: vdr_stop
           
          -- name: Start VDR
          -  systemd:
          -    name: vdr.service
          -    state: started
          -    enabled: yes
          -  register: vdr_start
          +- name: Start VDR
          +  systemd:
          +    name: vdr.service
          +    state: started
          +    enabled: yes
          +  register: vdr_start
           
          -- name: Stop xlogin
          -  systemd:
          -    name: xlogin@vdr.service
          -    state: stopped
          -    enabled: yes
          -  register: xlogin_stop
          +- name: Stop xlogin
          +  systemd:
          +    name: xlogin@vdr.service
          +    state: stopped
          +    enabled: yes
          +  register: xlogin_stop
           
          -- name: Stop x
          -  systemd:
          -    name: x@vt7.service
          -    state: stopped
          -  register: x_stop
          +- name: Stop x
          +  systemd:
          +    name: x@vt7.service
          +    state: stopped
          +  register: x_stop
           
          @@ -5567,7 +5371,7 @@ This section contains custom modules for the yaVDR Playbooks. They are used to c

          Autor: Alexander Grothe <seahawk1986@gmx.de>

          -

          Created: 2017-07-09 So 10:58

          +

          Created: 2017-08-31 Do 15:57

          Validate