[PLUGIN] Touch Display

I made a fresh install with volumio3 on a Raspberry Pi 3. Then i waited some time and tried to install the plugin. During the install there was an error (sorry i don’t know what exactly). Now the plugin is installed, but does not work and uninstall does also not work. :roll_eyes:
Maybe there is another way to “rescue” the device (purge the plugin), because to reflash i need to disassemble the device again → Not really funny! :stuck_out_tongue_winking_eye:

1 Like

What is the plugin version?

I see 3.3.1.
A little bit frustrating that i haven’t noted the error message sorry. :roll_eyes:
Maybe can i rerun the install command in CMD to see what goes wrong?

  1. Connect to Volumio via SSH.

  2. Exexcute

rm -rf /data/configuration/user_interface/touch_display
rm -rf /data/plugins/user_interface/touch_display

If you don’t you any other plugins installed simply

rm /data/configuration/plugins.json

Otherwise backup /data/configuration/plugins.json"

cp /data/configuration/plugins.json /data/configuration/plugins.json.bak

and edit “/data/configuration/plugins.json”.

nano /data/configuration/plugins.json

Look out for this code section:

 ,
"touch_display": {
  "enabled": {
    "type": "boolean",
    "value": true
  },
  "status": {
    "type": "string",
    "value": "STARTED"
  }
}

and remove it. Your values for “enabled” and “status” might differ, but that’s not relevant.

Be careful not to destroy the json syntax. The comma in the first line of the code section above immediately follows a “}” and has to be removed, too.

Save the modified file hitting Ctrl+x, y and Enter.

  1. Run

volumio vrestart

  1. Enable “Plugins Test Mode” on Volumio’s dev page. From the plugin store install version 3.3.2 of the plugin.

Okidoki, worked so far, but same error during installation. Now i “catched” the error, but it does not show any usefull information:


Edit1: Ah, wait, i have an idea… :grimacing:
Edit2: Okidoki, i found the “Problem”. It is simple when you know for what you are looking… :roll_eyes: It does NOT work if you change the default password. And yes, i always change the default PW. :wink: After changing PW back to default, the installation of 3.3.2 works fine so far (it is installing the dependencies).

Yes, this is an old one (e.g. https://community.volumio.com/t/change-volumio-account-password/4955). :wink:

Hi, Thanks for this great plugin !
I have a cheap 3.5inch screen which probably not support dpms, I discover that the LCD backlight is always on but can be disabled with GPIO :
gpio mode 3 out and then
gpio write 3 1 to switch on the backlight
gpio write 3 0 to switch off

I just need to ON/OFF the screen so first I found the plugin “gpio control”. Thanks to gvolt it works on Volumio 3 and I’m able to switch off/on my backlight on play/pause, …

But I think that the screensaver is very conveniant so I would like to add these gpio commands next to the existing dpms commands in the Touch Display plugin…

Can I edit the /data/plugins/user_interface/touch_display/index.js file directly and restart the plugin to test ?

I’ve added this kind of commands :
exec('/usr/bin/gpio write 3 0');
just before dpms commands but it doesn’t seems to works.

My index.js file, click here to expanse

'use strict';

const libQ = require('kew');
const fs = require('fs-extra');
const { exec } = require('child_process');
const path = require('path');
const os = require('os');
const net = require('net');
const io = require('socket.io-client');
const unixDomSocket = new net.Socket();
const socket = io.connect('http://localhost:3000');
const blInterface = '/sys/devices/platform/rpi_backlight/backlight/rpi_backlight';
const als = '/etc/als'; // The plugin awaits the current value of an optional ambient light sensor (ALS) as a single number in /etc/als.
const configTxtGpuMemBanner = '#### Touch Display gpu_mem setting below: do not alter ####' + os.EOL;
const configTxtRotationBanner = '#### Touch Display rotation setting below: do not alter ####' + os.EOL;
const id = 'touch_display: ';
let rpiScreen = false;
let rpiBacklight = false;
let maxBrightness = 255;
const alsProgression = [];
let autoBrTimeoutCleared = false;
let currentlyAdjusting = false;
let uiNeedsUpdate = false;
let device, displayNumber, autoBrTimer, toggleBrTimer;

module.exports = TouchDisplay;

function TouchDisplay (context) {
  const self = this;

  self.context = context;
  self.commandRouter = self.context.coreCommand;
  self.logger = self.context.logger;
  self.configManager = self.context.configManager;
}

TouchDisplay.prototype.onVolumioStart = function () {
  const self = this;
  const configFile = self.commandRouter.pluginManager.getConfigurationFile(self.context, 'config.json');

  self.config = new (require('v-conf'))();
  self.config.loadFile(configFile);
  return libQ.resolve();
};

TouchDisplay.prototype.onVolumioShutdown = function () {
  const self = this;

  if (rpiBacklight) {
    // in order to have full brightness during the next boot up
    self.setBrightness(maxBrightness);
  }
  return libQ.resolve();
};

TouchDisplay.prototype.onVolumioReboot = function () {
  const self = this;

  if (rpiBacklight) {
    // in order to have full brightness during the next boot up
    self.setBrightness(maxBrightness);
  }
  return libQ.resolve();
};

TouchDisplay.prototype.onStart = function () {
  const self = this;
  const defer = libQ.defer();
  let lastStateIsPlaying = false;
  let attempts = 0;

  self.commandRouter.loadI18nStrings();
  self.systemctl('daemon-reload')
    .then(self.systemctl.bind(self, 'start volumio-kiosk.service'))
    .then(function () {
      self.logger.info(id + 'Volumio Kiosk started');
      self.commandRouter.executeOnPlugin('system_controller', 'system', 'getSystemVersion', '')
        .then(function (infos) {
          device = infos.hardware;
          if (device === 'pi') {
            fs.readFile('/proc/modules', 'utf8', function (err, data) {
              if (err) {
                self.logger.error(id + 'Error reading /proc/modules: ' + err);
                self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_READ') + '/proc/modules: ' + err);
              } else {
                // detect Raspberry Pi Foundation original touch screen
                if (data.match(/^rpi_ft5406\b/gm) === null && data.match(/^raspberrypi_ts\b/gm) === null) {
                  self.logger.info(id + 'No Raspberry Pi Foundation touch screen detected.');
                } else {
                  rpiScreen = true;
                  self.logger.info(id + 'Raspberry Pi Foundation touch screen detected.');
                  // check for backlight module of Raspberry Pi Foundation original touch screen
                  if (data.match(/^rpi_backlight\b/gm) === null) {
                    self.logger.info(id + 'No backlight module of a Raspberry Pi Foundation touch screen detected.');
                  } else {
                    rpiBacklight = true;
                    self.logger.info(id + 'Backlight module of a Raspberry Pi Foundation touch screen detected.');
                    // screen brightness
                    fs.readFile(blInterface + '/max_brightness', 'utf8', function (err, data) {
                      if (err) {
                        self.logger.error(id + 'Error reading ' + blInterface + '/max_brightness: ' + err);
                        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_READ') + blInterface + '/max_brightness: ' + err);
                      } else {
                        maxBrightness = parseInt(data, 10);
                        exec('/usr/bin/sudo /bin/chmod a+w ' + blInterface + '/brightness', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
                          if (error !== null) {
                            self.logger.error(id + 'Error setting file permissions for backlight brightness control: ' + error);
                          } else {
                            self.logger.info(id + 'File permissions for backlight brightness control set.');
                            if (!self.config.get('autoMode')) {
                              if (self.config.get('br2StartTime') !== self.config.get('br1StartTime')) {
                                self.toggleBrightness();
                              } else {
                                self.setBrightness(self.config.get('manualBr'));
                              }
                            } else {
                              self.autoBrightness();
                            }
                          }
                        });
                      }
                    });
                  }
                }
              }
              // screen orientation
              self.setOrientation(self.config.get('angle'));
              // GPU memory size
              if (self.config.get('controlGpuMem')) {
                self.modBootConfig(configTxtGpuMemBanner + 'gpu_mem=.*', configTxtGpuMemBanner + 'gpu_mem=' + self.config.get('gpuMem'))
                  .then(self.modBootConfig.bind(self, '^gpu_mem', '#GPU_MEM'))
                  .fail(function () {
                    self.logger.info(id + 'Writing the touch display plugin\'s gpu_mem setting failed. Previous gpu_mem settings in /boot/config.txt have not been commented.');
                  });
              }
            });
          }
        });
      // screensaver
      if (self.commandRouter.volumioGetState().status === 'play') {
        lastStateIsPlaying = true;
      }
      unixDomSocket.connect('/tmp/.X11-unix/X' + self.getDisplaynumber());
      unixDomSocket.on('connect', function () {
        if ((self.config.get('afterPlay') && self.commandRouter.volumioGetState().status === 'play') || self.config.get('timeout') === 0) {
			exec('/usr/bin/gpio write 26 1');
          exec('/usr/bin/xset -display :' + displayNumber + ' s reset dpms force on', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
            if (error !== null) {
              self.logger.error(id + 'Error waking up the screen: ' + error);
            }
          });
          self.setScreenTimeout(0, false);
        } else {
          self.setScreenTimeout(self.config.get('timeout'), false);
        }
        attempts = 0;
      });
      unixDomSocket.on('error', function (data) {
      });
      unixDomSocket.on('close', function () {
        if (attempts < 100) {
          setTimeout(function () {
            unixDomSocket.connect('/tmp/.X11-unix/X' + self.getDisplaynumber());
          }, 100);
          attempts++;
        } else {
          self.logger.error(id + 'Connecting to the Xserver failed.');
          self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_CON_XSERVER'));
        }
      });
      // catch state related events and react to changes of the playing status
      socket.emit('getState', '');
      socket.on('pushState', function (state) {
        if (state.status === 'play' && !lastStateIsPlaying) {
          if (self.config.get('afterPlay')) {
			  exec('/usr/bin/gpio write 26 1');
            exec('/usr/bin/xset -display :' + displayNumber + ' s reset dpms force on', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
              if (error !== null) {
                self.logger.error(id + 'Error waking up the screen: ' + error);
              }
            });
            self.setScreenTimeout(0, true);
          }
          lastStateIsPlaying = true;
        } else if (state.status !== 'play' && lastStateIsPlaying) {
          self.setScreenTimeout(self.config.get('timeout'), true);
          lastStateIsPlaying = false;
        }
      });
      defer.resolve();
    })
    .fail(function () {
      defer.reject(new Error());
    });
  return defer.promise;
};

TouchDisplay.prototype.onStop = function () {
  const self = this;
  const defer = libQ.defer();

  unixDomSocket.removeAllListeners();
  unixDomSocket.destroy();
  socket.off('pushState');
  if (device === 'pi') {
    self.setOrientation('0');
    if (self.config.get('controlGpuMem')) {
      self.modBootConfig('^#GPU_MEM', 'gpu_mem')
        .then(self.modBootConfig.bind(self, configTxtGpuMemBanner + 'gpu_mem=.*', ''))
        .fail(function () {
          self.logger.info(id + 'Restoring gpu_mem settings in /boot/config.txt failed. The touch display plugin\'s gpu_mem settings have been preserved.');
        });
    }
    clearTimeout(autoBrTimer);
    clearTimeout(toggleBrTimer);
    if (rpiBacklight) {
      self.setBrightness(maxBrightness);
    }
  }
  self.systemctl('stop volumio-kiosk.service')
    .fin(function () {
      defer.resolve();
    });
  return defer.promise;
};

// Configuration Methods -----------------------------------------------------------------------------

TouchDisplay.prototype.getUIConfig = function () {
  const self = this;
  const defer = libQ.defer();
  const langCode = self.commandRouter.sharedVars.get('language_code');

  self.commandRouter.i18nJson(path.join(__dirname, 'i18n', 'strings_' + langCode + '.json'),
    path.join(__dirname, 'i18n', 'strings_en.json'),
    path.join(__dirname, 'UIConfig.json'))
    .then(function (uiconf) {
      uiconf.sections[0].hidden = false;
      uiconf.sections[0].content[0].value = self.config.get('timeout');
      uiconf.sections[0].content[0].attributes = [
        {
          placeholder: 120,
          maxlength: Number.MAX_SAFE_INTEGER.toString().length,
          min: 0,
          max: Number.MAX_SAFE_INTEGER
        }
      ];
      uiconf.sections[0].content[1].value = self.config.get('afterPlay');
      if (rpiBacklight) {
        uiconf.sections[1].hidden = false;
        try {
          if (fs.existsSync(als)) {
            uiconf.sections[1].content[0].hidden = false;
            uiconf.sections[1].content[0].value = self.config.get('autoMode');
            uiconf.sections[1].content[1].value = self.config.get('minBr');
            uiconf.sections[1].content[1].attributes = [
              {
                placeholder: 15,
                maxlength: maxBrightness.toString().length,
                min: 0,
                max: maxBrightness
              }
            ];
            uiconf.sections[1].content[2].value = self.config.get('maxBr');
            uiconf.sections[1].content[2].attributes = [
              {
                placeholder: maxBrightness,
                maxlength: maxBrightness.toString().length,
                min: 0,
                max: maxBrightness
              }
            ];
            uiconf.sections[1].content[4].value = self.config.get('brightnessCurve');
            uiconf.sections[1].content[5].value = self.config.get('midBr');
            uiconf.sections[1].content[5].attributes = [
              {
                placeholder: maxBrightness,
                maxlength: maxBrightness.toString().length,
                min: 0,
                max: maxBrightness
              }
            ];
          }
        } catch (e) {
          self.logger.error(id + 'Error checking the existence of "/etc/als": ' + e);
        }
        uiconf.sections[1].content[7].value = self.config.get('manualBr');
        uiconf.sections[1].content[7].attributes = [
          {
            placeholder: maxBrightness,
            maxlength: maxBrightness.toString().length,
            min: 0,
            max: maxBrightness
          }
        ];
        uiconf.sections[1].content[8].value = self.config.get('br1StartTime');
        uiconf.sections[1].content[8].attributes = [
          {
            placeholder: 'hh:mm',
            maxlength: 5
          }
        ];
        uiconf.sections[1].content[9].value = self.config.get('manualBr2');
        uiconf.sections[1].content[9].attributes = [
          {
            placeholder: maxBrightness,
            maxlength: maxBrightness.toString().length,
            min: 0,
            max: maxBrightness
          }
        ];
        uiconf.sections[1].content[10].value = self.config.get('br2StartTime');
        uiconf.sections[1].content[10].attributes = [
          {
            placeholder: 'hh:mm',
            maxlength: 5
          }
        ];
      }
      if (device === 'pi') {
        uiconf.sections[2].hidden = false;
        uiconf.sections[2].content[0].value.value = self.config.get('angle');
        uiconf.sections[2].content[0].value.label = self.commandRouter.getI18nString('TOUCH_DISPLAY.' + self.config.get('angle'));
        uiconf.sections[3].hidden = false;
        uiconf.sections[3].content[0].value = self.config.get('controlGpuMem');
        uiconf.sections[3].content[1].value = self.config.get('gpuMem');
        uiconf.sections[3].content[1].attributes = [
          {
            placeholder: 32,
            maxlength: 3,
            min: 32,
            max: 128
          }
        ];
      }
      uiconf.sections[4].hidden = false;
      uiconf.sections[4].content[0].value = self.config.get('showPointer');
      uiconf.sections[5].hidden = false;
      uiconf.sections[5].content[0].value = self.config.get('scale');
      uiconf.sections[5].content[0].attributes = [
        {
          placeholder: 100,
          maxlength: 3,
          min: 10,
          max: 200
        }
      ];
      defer.resolve(uiconf);
    })
    .fail(function (e) {
      self.logger.error(id + 'Could not fetch UI configuration: ' + e);
      defer.reject(new Error());
    });
  return defer.promise;
};

TouchDisplay.prototype.updateUIConfig = function () {
  const self = this;

  self.commandRouter.getUIConfigOnPlugin('user_interface', 'touch_display', {})
    .then(function (uiconf) {
      self.commandRouter.broadcastMessage('pushUiConfig', uiconf);
    });
  self.commandRouter.broadcastMessage('pushUiConfig');
  uiNeedsUpdate = false;
};

TouchDisplay.prototype.getConfigurationFiles = function () {
  return ['config.json'];
};

TouchDisplay.prototype.getI18nFile = function (langCode) {
  const self = this;
  const langFile = 'strings_' + langCode + '.json';

  try {
    const i18nFiles = fs.readdirSync(path.join(__dirname, 'i18n'));
    // check for i18n file fitting the system language
    if (i18nFiles.some(function (i18nFile) { return i18nFile === langFile; })) {
      return path.join(__dirname, 'i18n', langFile);
    }
    throw new Error('i18n file complementing the system language not found.');
  } catch (e) {
    self.logger.error(id + 'Fetching language file: ' + e);
    // return default i18n file
    return path.join(__dirname, 'i18n', 'strings_en.json');
  }
};

TouchDisplay.prototype.saveScreensaverConf = function (confData) {
  const self = this;
  let noChanges = true;

  if (Number.isNaN(parseInt(confData.timeout, 10)) || !isFinite(confData.timeout)) {
    uiNeedsUpdate = true;
    self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.TIMEOUT') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
  } else {
    confData.timeout = self.checkLimits('timeout', confData.timeout, 0, Number.MAX_SAFE_INTEGER);
    if (self.config.get('timeout') !== confData.timeout || self.config.get('afterPlay') !== confData.afterPlay) {
      self.config.set('timeout', confData.timeout);
      self.config.set('afterPlay', confData.afterPlay);
      if ((confData.afterPlay && self.commandRouter.volumioGetState().status === 'play') || confData.timeout === 0) {
		  exec('/usr/bin/gpio write 26 1');
        exec('/usr/bin/xset -display :' + displayNumber + ' s reset dpms force on', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
          if (error !== null) {
            self.logger.error(id + 'Error waking up the screen: ' + error);
          }
        });
        self.setScreenTimeout(0, true);
      } else {
        self.setScreenTimeout(confData.timeout, true);
      }
      noChanges = false;
    }
  }
  if (uiNeedsUpdate) {
    self.updateUIConfig();
  } else if (noChanges) {
    self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
  } else {
    self.commandRouter.pushToastMessage('success', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('COMMON.SETTINGS_SAVED_SUCCESSFULLY'));
  }
};

TouchDisplay.prototype.saveBrightnessConf = function (confData) {
  const self = this;
  const responseData = {
    title: self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'),
    message: self.commandRouter.getI18nString('TOUCH_DISPLAY.TEST_MSG'),
    size: 'lg',
    buttons: [
      {
        name: self.commandRouter.getI18nString('TOUCH_DISPLAY.TESTBRIGHTNESS'),
        class: 'btn btn-default',
        emit: 'callMethod',
        payload: { endpoint: 'user_interface/touch_display', method: 'testBrightness', data: Object.assign({}, confData) }
      },
      {
        name: self.commandRouter.getI18nString('COMMON.CONTINUE'),
        class: 'btn btn-info',
        emit: 'callMethod',
        payload: { endpoint: 'user_interface/touch_display', method: 'saveBrightnessConf', data: (function () { const data = Object.assign({}, confData); data.modalResult = true; return data; })() }
      },
      {
        name: self.commandRouter.getI18nString('COMMON.CANCEL'),
        class: 'btn btn-info',
        emit: 'callMethod',
        payload: { endpoint: 'user_interface/touch_display', method: 'saveBrightnessConf', data: (function () { const data = Object.assign({}, confData); data.modalResult = false; return data; })() }
      }
    ]
  };
  const timeValidator = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])$/;
  let noChanges = true;

  self.commandRouter.broadcastMessage('closeAllModals', '');
  if (self.config.get('autoMode') !== confData.autoMode) {
    noChanges = false;
  }
  if (confData.autoMode) {
    if (Number.isNaN(parseInt(confData.minBr, 10)) || !isFinite(confData.minBr)) {
      confData.minBr = self.config.get('minBr');
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.MINBR') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
    }
    confData.minBr = self.checkLimits('minBr', confData.minBr, 0, maxBrightness);
    if (confData.modalResult === undefined && confData.minBr < 15 && confData.minBr < self.config.get('minBr')) {
      responseData.message = responseData.message.replace('${}', confData.minBr);
      responseData.buttons[2].payload.data.minBr = self.config.get('minBr');
      self.commandRouter.broadcastMessage('openModal', responseData);
      return;
    } else {
      if (confData.modalResult === false) {
        uiNeedsUpdate = true;
      } else {
        if (self.config.get('minBr') !== confData.minBr) {
          self.config.set('minBr', confData.minBr);
          noChanges = false;
        }
      }
      if (Number.isNaN(parseInt(confData.maxBr, 10)) || !isFinite(confData.maxBr)) {
        confData.maxBr = self.config.get('maxBr');
        uiNeedsUpdate = true;
        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.MAXBR') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
      }
      confData.maxBr = self.checkLimits('maxBr', confData.maxBr, confData.minBr, maxBrightness);
      if (self.config.get('maxBr') !== confData.maxBr) {
        self.config.set('maxBr', confData.maxBr);
        noChanges = false;
      }
      if (confData.brightnessCurve) {
        if (Number.isNaN(parseInt(confData.midBr, 10)) || !isFinite(confData.midBr)) {
          confData.midBr = self.config.get('midBr');
          uiNeedsUpdate = true;
          self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.MIDBR') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
        }
        confData.midBr = self.checkLimits('midBr', confData.midBr, confData.minBr, confData.maxBr);
        if (self.config.get('midBr') !== confData.midBr) {
          self.config.set('midBr', confData.midBr);
          noChanges = false;
        }
      }
      // minAls and maxAls can only be the same value if the ALS range has not been determined before
      if (self.config.get('maxAls') <= self.config.get('minAls')) {
        if (confData.brightnessCurve) {
          self.getAlsValue({ confData: confData, action: 'minmaxmid' });
        } else {
          self.getAlsValue({ confData: confData, action: 'minmax' });
        }
      } else if (confData.brightnessCurve && (!self.config.has('midAls') || self.config.get('midAls') <= self.config.get('minAls') || self.config.get('midAls') >= self.config.get('maxAls'))) {
        self.getAlsValue({ confData: confData, action: 'mid' });
      } else {
        if (self.config.get('brightnessCurve') !== confData.brightnessCurve) {
          self.config.set('brightnessCurve', confData.brightnessCurve);
          noChanges = false;
        }
        self.config.set('autoMode', confData.autoMode);
        clearTimeout(toggleBrTimer);
        clearTimeout(autoBrTimer);
        autoBrTimeoutCleared = true;
        self.autoBrightness();
      }
    }
  } else {
    self.config.set('autoMode', confData.autoMode);
    clearTimeout(autoBrTimer);
    autoBrTimeoutCleared = true;
    if (Number.isNaN(parseInt(confData.manualBr, 10)) || !isFinite(confData.manualBr)) {
      confData.manualBr = self.config.get('manualBr');
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.MANUALBR') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
    }
    confData.manualBr = self.checkLimits('manualBr', confData.manualBr, 0, maxBrightness);
    if (Number.isNaN(parseInt(confData.manualBr2, 10)) || !isFinite(confData.manualBr2)) {
      confData.manualBr2 = self.config.get('manualBr2');
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.MANUALBR2') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
    }
    confData.manualBr2 = self.checkLimits('manualBr2', confData.manualBr2, 0, maxBrightness);
    if (confData.modalResult === undefined && ((confData.manualBr < 15 && confData.manualBr < self.config.get('manualBr') && confData.manualBr < self.config.get('manualBr2')) || (confData.manualBr2 < 15 && confData.manualBr2 < self.config.get('manualBr2') && confData.manualBr2 < self.config.get('manualBr')))) {
      if (confData.manualBr <= confData.manualBr2) {
        responseData.message = responseData.message.replace('${}', confData.manualBr);
        responseData.buttons[2].payload.data.manualBr = self.config.get('manualBr');
        if (confData.manualBr === confData.manualBr2) {
          responseData.buttons[2].payload.data.manualBr2 = self.config.get('manualBr2');
        }
      } else {
        responseData.message = responseData.message.replace('${}', confData.manualBr2);
        responseData.buttons[2].payload.data.manualBr2 = self.config.get('manualBr2');
      }
      self.commandRouter.broadcastMessage('openModal', responseData);
      return;
    } else {
      if (confData.modalResult === false) {
        uiNeedsUpdate = true;
        if (confData.manualBr !== confData.manualBr2) {
          if (confData.manualBr < 15 && confData.manualBr < self.config.get('manualBr')) {
            responseData.message = responseData.message.replace('${}', confData.manualBr);
            responseData.buttons[2].payload.data.manualBr = self.config.get('manualBr');
            self.commandRouter.broadcastMessage('openModal', responseData);
            return;
          } else if (confData.manualBr2 < 15 && confData.manualBr2 < self.config.get('manualBr2')) {
            responseData.message = responseData.message.replace('${}', confData.manualBr2);
            responseData.buttons[2].payload.data.manualBr2 = self.config.get('manualBr2');
            self.commandRouter.broadcastMessage('openModal', responseData);
            return;
          }
        } else {
          self.config.set('manualBr', confData.manualBr);
          self.config.set('manualBr2', confData.manualBr2);
          noChanges = false;
        }
      } else {
        self.config.set('manualBr', confData.manualBr);
        self.config.set('manualBr2', confData.manualBr2);
        noChanges = false;
      }
      if (confData.br1StartTime.match(timeValidator) === null) {
        uiNeedsUpdate = true;
        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.BR1STARTTIME') + self.commandRouter.getI18nString('TOUCH_DISPLAY.INVALID'));
      } else if (self.config.get('br1StartTime') !== confData.br1StartTime) {
        self.config.set('br1StartTime', confData.br1StartTime);
        noChanges = false;
      }
      if (confData.br2StartTime.match(timeValidator) === null) {
        uiNeedsUpdate = true;
        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.BR2STARTTIME') + self.commandRouter.getI18nString('TOUCH_DISPLAY.INVALID'));
      } else if (self.config.get('br2StartTime') !== confData.br2StartTime) {
        self.config.set('br2StartTime', confData.br2StartTime);
        noChanges = false;
      }
      if (self.config.get('br2StartTime') !== self.config.get('br1StartTime') && self.config.get('manualBr') !== self.config.get('manualBr2')) {
        self.toggleBrightness();
      } else {
        self.setBrightness(confData.manualBr);
        clearTimeout(toggleBrTimer);
      }
    }
  }
  if (uiNeedsUpdate) {
    self.updateUIConfig();
  } else if (noChanges) {
    self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
  } else {
    self.commandRouter.pushToastMessage('success', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('COMMON.SETTINGS_SAVED_SUCCESSFULLY'));
  }
};

TouchDisplay.prototype.saveOrientationConf = function (confData) {
  const self = this;
  const responseData = {
    title: self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'),
    message: self.commandRouter.getI18nString('TOUCH_DISPLAY.REBOOT_MSG'),
    size: 'lg',
    buttons: [
      {
        name: self.commandRouter.getI18nString('COMMON.RESTART'),
        class: 'btn btn-default',
        emit: 'reboot',
        payload: ''
      },
      {
        name: self.commandRouter.getI18nString('COMMON.CONTINUE'),
        class: 'btn btn-info',
        emit: 'closeModals',
        payload: ''
      }
    ]
  };

  if (self.config.get('angle') !== confData.angle.value) {
    self.config.set('angle', confData.angle.value);
    self.setOrientation(confData.angle.value)
      .then(function () {
        self.commandRouter.broadcastMessage('openModal', responseData);
      });
  } else {
    self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
  }
};

TouchDisplay.prototype.saveGpuMemConf = function (confData) {
  const self = this;
  const responseData = {
    title: self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'),
    message: self.commandRouter.getI18nString('TOUCH_DISPLAY.REBOOT_MSG'),
    size: 'lg',
    buttons: [
      {
        name: self.commandRouter.getI18nString('COMMON.RESTART'),
        class: 'btn btn-default',
        emit: 'reboot',
        payload: ''
      },
      {
        name: self.commandRouter.getI18nString('COMMON.CONTINUE'),
        class: 'btn btn-info',
        emit: 'closeModals',
        payload: ''
      }
    ]
  };

  if (confData.controlGpuMem) {
    if (Number.isNaN(parseInt(confData.gpuMem, 10)) || !isFinite(confData.gpuMem)) {
      confData.gpuMem = self.config.get('gpuMem');
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.GPUMEM') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
    } else {
      confData.gpuMem = self.checkLimits('gpuMem', confData.gpuMem, 32, 128);
    }
    if (self.config.get('gpuMem') !== confData.gpuMem || self.config.get('controlGpuMem') !== confData.controlGpuMem) {
      self.modBootConfig(configTxtGpuMemBanner + 'gpu_mem=.*', configTxtGpuMemBanner + 'gpu_mem=' + confData.gpuMem)
        .then(function () {
          self.config.set('gpuMem', confData.gpuMem);
          if (self.config.get('controlGpuMem') !== confData.controlGpuMem) {
            self.modBootConfig('^gpu_mem', '#GPU_MEM');
          }
        })
        .then(function () {
          self.config.set('controlGpuMem', confData.controlGpuMem);
          self.commandRouter.broadcastMessage('openModal', responseData);
        })
        .fail(function () {
          uiNeedsUpdate = true;
          self.logger.error(id + 'Changing gpu_mem settings failed.');
        })
        .done(function () {
          if (uiNeedsUpdate) {
            self.updateUIConfig();
          }
        });
    } else if (uiNeedsUpdate) {
      self.updateUIConfig();
    } else {
      self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
    }
  } else if (self.config.get('controlGpuMem') !== confData.controlGpuMem) {
    self.modBootConfig('^#GPU_MEM', 'gpu_mem')
      .then(function () {
        self.modBootConfig(configTxtGpuMemBanner + 'gpu_mem=.*', '');
      })
      .then(function () {
        self.config.set('controlGpuMem', confData.controlGpuMem);
        self.commandRouter.broadcastMessage('openModal', responseData);
      })
      .fail(function () {
        self.updateUIConfig();
        self.logger.error(id + 'Uncommenting gpu_mem settings in /boot/config.txt failed.');
      });
  } else {
    self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
  }
};

TouchDisplay.prototype.savePointerConf = function (confData) {
  const self = this;
  const defer = libQ.defer();
  const execStartLine = 'ExecStart=\\/usr\\/bin\\/startx \\/etc\\/X11\\/Xsession \\/opt\\/volumiokiosk.sh';
  const pointerOpt = confData.showPointer ? "'" : " -- -nocursor'";

  if (self.config.get('showPointer') !== confData.showPointer) {
    fs.stat('/tmp/.X11-unix/X' + displayNumber, function (err, stats) {
      if (err !== null || !stats.isSocket()) {
        self.updateUIConfig();
        self.logger.error(id + 'Pointer config cannot be applied: ' + err); // this can happen if the user applies a pointer setting which leads to a restart of the Xserver and then fastly (before the Xserver has completed its start) tries to apply a new pointer config
        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_SET_POINTER') + err);
        defer.reject(err);
      } else {
        self.config.set('showPointer', confData.showPointer);
        exec("/bin/echo volumio | /usr/bin/sudo -S /bin/sed -i -e '/" + execStartLine + '/c\\' + execStartLine + pointerOpt + ' /lib/systemd/system/volumio-kiosk.service', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
          if (error !== null) {
            self.logger.error(id + 'Error modifying /lib/systemd/system/volumio-kiosk.service: ' + error);
            self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_MOD') + '/lib/systemd/system/volumio-kiosk.service: ' + error);
            defer.reject(error);
          } else {
            self.systemctl('daemon-reload')
              .then(self.onStop.bind(self))
              .then(self.onStart.bind(self))
              .then(function () {
                self.commandRouter.pushToastMessage('success', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('COMMON.SETTINGS_SAVED_SUCCESSFULLY'));
                defer.resolve();
              })
              .fail(function () {
                defer.reject(new Error());
              });
          }
        });
      }
    });
  } else {
    self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
  }
  return defer.promise;
};

TouchDisplay.prototype.saveScaleConf = function (confData) {
  const self = this;
  const defer = libQ.defer();

  if (Number.isNaN(parseInt(confData.scale, 10)) || !isFinite(confData.scale)) {
    uiNeedsUpdate = true;
    self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.SCALE') + self.commandRouter.getI18nString('TOUCH_DISPLAY.NAN'));
  } else {
    confData.scale = self.checkLimits('scale', confData.scale, 10, 200);
    if (self.config.get('scale') !== confData.scale) {
      fs.stat('/tmp/.X11-unix/X' + displayNumber, function (err, stats) {
        if (err !== null || !stats.isSocket()) {
          self.updateUIConfig();
          self.logger.error(id + 'Scale config cannot be applied: ' + err); // this can happen if the user applies a scale setting which leads to a restart of the Xserver and then fastly (before the Xserver has completed its start) tries to apply a new scale config
          self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_SET_SCALE') + err);
          defer.reject(err);
        } else {
          self.config.set('scale', confData.scale);
          exec('/usr/bin/chromium-browser -version', { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
            if (error !== null) {
              self.logger.error(id + 'Error requesting browser version.');
            } else {
              if (confData.scale < 100 && stdout.match(/\d*\./).toString().slice(0, -1) < 57) {
                self.commandRouter.pushToastMessage('warning', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.SCALE_WARN'));
              }
              exec("/bin/echo volumio | /usr/bin/sudo -S /bin/sed -i -e 's/factor=.* /factor=" + confData.scale / 100 + " /' /opt/volumiokiosk.sh", { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
                if (error !== null) {
                  self.logger.error(id + 'Error modifying /opt/volumiokiosk.sh: ' + error);
                  self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_MOD') + '/opt/volumiokiosk.sh: ' + error);
                  defer.reject(error);
                } else {
                  self.systemctl('daemon-reload')
                    .then(self.onStop.bind(self))
                    .then(self.onStart.bind(self))
                    .then(function () {
                      self.commandRouter.pushToastMessage('success', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('COMMON.SETTINGS_SAVED_SUCCESSFULLY'));
                      defer.resolve();
                    })
                    .fail(function () {
                      defer.reject(new Error());
                    });
                }
              });
            }
          });
        }
      });
    } else {
      self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.NO_CHANGES'));
    }
  }
  if (uiNeedsUpdate) {
    self.updateUIConfig();
  }
  return defer.promise;
};

// Plugin Methods ------------------------------------------------------------------------------------

TouchDisplay.prototype.checkLimits = function (item, value, min, max) {
  const self = this;

  if (value < min) {
    if (item !== '') {
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.' + item.toUpperCase()) + ': ' + self.commandRouter.getI18nString('TOUCH_DISPLAY.INFO_MIN'));
    }
    return min;
  }
  if (value > max) {
    if (item !== '') {
      uiNeedsUpdate = true;
      self.commandRouter.pushToastMessage('info', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.' + item.toUpperCase()) + ': ' + self.commandRouter.getI18nString('TOUCH_DISPLAY.INFO_MAX'));
    }
    return max;
  }
  return parseInt(value, 10);
};

TouchDisplay.prototype.setScreenTimeout = function (timeout, showErr) {
  const self = this;
  const defer = libQ.defer();

  fs.stat('/tmp/.X11-unix/X' + displayNumber, function (err, stats) {
    if (err !== null || !stats.isSocket()) {
      self.logger.error(id + 'Error setting screensaver timeout: ' + err);
      if (showErr) {
        self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_SET_TIMEOUT') + err);
      }
      defer.reject(err);
    } else {
		exec('/usr/bin/gpio write 26 0');
      exec('/usr/bin/xset -display :' + displayNumber + ' s off +dpms dpms 0 0 ' + timeout, { uid: 1000, gid: 1000 }, function (error, stdout, stderr) {
        if (error !== null) {
          self.logger.error(id + 'Error setting screensaver timeout: ' + error);
          if (showErr) {
            self.commandRouter.pushToastMessage('error', self.commandRouter.getI18nString('TOUCH_DISPLAY.PLUGIN_NAME'), self.commandRouter.getI18nString('TOUCH_DISPLAY.ERR_SET_TIMEOUT') + error);
          }
          defer.reject(error);
        } else {
          self.logger.info(id + 'Setting screensaver timeout to ' + timeout + ' seconds.');
          defer.resolve();
        }
      });
    }
  });
  return defer.promise;
};


........
code to long, cutted here
.........

A great alternative could be to authorise users to run custom scripts from events in settings of “Touch Display” plugin :stuck_out_tongue:

This plug-in doesn’t work with Version 3 when you have the screen rotated 180 degrees in the settings.

It’s still expecting the presses to be in the regular non rotated position.

I have a video showing the screen presses with the cursor on (so you can see the behavior) but it won’t upload from my iPhone.

It has already been reported and I am working on a new version. Hold on :wink:

Ironically a reboot seemed to correct the problem and it’s working right lol…

Yes, I am aware of this phenomenon. Thanks for reporting.

Using the official 7" display on Volumio 3.198, adjusting the brightness settings appears to have no effect. Is this a known issue, or could it be particular to my setup?

Adjusting brightness should work as long as you don’t have V1.0 of the official 7" display. On screens of this old revision, brightness values below 128 simply turn the screen off, while values above 127 turn it on.

Apart from that, on the config page of the plugin it is possible to define two different brightness values (“Brightness 1” and “Brightness 2”) and to specify the time of day at which each brightness value should be set (e.g. a higher brightness value in the daytime starting at 6:00 and a lower brightness at the night-time starting at 21:00). The time of day values need to follow the 24-hour clock system and the time format hh:mm. If both time of day settings should be identical, the screen brightness will not be changed but only brightness 1 will be applied.

Regarding the time values be aware that the plugin uses the system time. The system time might deviate from the local time and can only be changed from the command line currently.

What are your settings for “Brightness 1”, “Brightness 2” and their start times on the plugin’s config page?

Ok, I don’t know why it wasn’t working before when I had two separate brightness values entered to start at different times. But I decided to make start time the same for each, and then adjusting Brightness 1 started to work. And then I changed it back to two brightness values starting at different times and that now works too.

hey i would like to get volumio 2.907 to run with touchdsisplay but i can’t do it… when i try it with volumio3.xx everything works

Received SIGRTMIN+20 from PID 1506 (plymouthd).
Started Show Plymouth Reboot Screen.
[2022/02/20 19:32:01.889520,  0] ../source3/winbindd/winbindd.c:266(winbindd_sig_term_handler)
Got sig[15] terminate (is_parent=1)
[2022/02/20 19:32:01.889725,  0] ../source3/winbindd/winbindd.c:266(winbindd_sig_term_handler)
Got sig[15] terminate (is_parent=0)
[2022/02/20 19:32:01.892315,  0] ../source3/winbindd/winbindd.c:266(winbindd_sig_term_handler)
Got sig[15] terminate (is_parent=0)
[2022/02/20 19:32:01.896990,  0] ../source3/winbindd/winbindd.c:266(winbindd_sig_term_handler)
Got sig[15] terminate (is_parent=0)
Stopped LSB: start Winbind daemon.
Stopping the Winbind daemon: winbind.
error: touch_display: Xserver unix domain socket cannot be determined.
error: touch_display: Xserver unix domain socket cannot be determined.
error: touch_display: Xserver unix domain socket cannot be determined.
error: touch_display: Xserver unix domain socket cannot be determined.
xinit: unexpected signal 15
volumio-kiosk.service: main process exited, code=exited, status=1/FAILURE
Stopped Volumio Kiosk.
Unit volumio-kiosk.service entered failed state.

Please post the output of

cat /var/log/Xorg.0.log

What screen (brand and exact model name) are you using?

hey good evening, at the moment the ui doesn’t even work via HDMI. I haven’t gotten to the display yet

pure volumio 2.907 installation and then only touch plugin tries to install, on volumio 3.178 everything is ok

cat /var/log/Xorg.0.log

[ 30.573]
X.Org X Server 1.18.4
Release Date: 2016-07-19
[ 30.573] X Protocol Version 11, Revision 0
[ 30.573] Build Operating System: Linux 4.4.26-v7+ armv7l Raspbian
[ 30.573] Current Operating System: Linux volumio2 4.19.118-v7l+ #1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l
[ 30.573] Kernel command line: coherent_pool=1M 8250.nr_uarts=0 cma=64M bcm2708_fb.fbwidth=1824 bcm2708_fb.fbheight=984 bcm2708_fb.fbswap=1 smsc95xx.macaddr=DC:A6:32:51:22:DC vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000 splash quiet plymouth.ignore-serial-consoles dwc_otg.fiq_enable=1 dwc_otg.fiq_fsm_enable=1 dwc_otg.fiq_fsm_mask=0xF dwc_otg.nak_holdoff=1 console=ttyS0,115200 kgdboc=ttyS0,115200 console=tty1 imgpart=/dev/mmcblk0p2 imgfile=/volumio_current.sqsh elevator=noop rootwait bootdelay=5 logo.nologo vt.global_cursor_default=0 loglevel=0 snd-bcm2835.enable_compat_alsa=1 snd_bcm2835.enable_headphones=1
[ 30.573] Build Date: 11 November 2016 11:59:59AM
[ 30.573] xorg-server 2:1.18.4-2+rpi1 (Debian -- Support)
[ 30.573] Current version of pixman: 0.32.6
[ 30.573] Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
[ 30.573] Markers: (–) probed, () from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[ 30.573] (==) Log file: “/var/log/Xorg.0.log”, Time: Sun Feb 20 21:42:10 2022
[ 30.577] (==) Using config directory: “/etc/X11/xorg.conf.d”
[ 30.577] (==) Using system config directory “/usr/share/X11/xorg.conf.d”
[ 30.580] (==) No Layout section. Using the first Screen section.
[ 30.580] (==) No screen section available. Using defaults.
[ 30.580] (
) |–>Screen “Default Screen Section” (0)
[ 30.580] () | |–>Monitor “”
[ 30.584] (==) No device specified for screen “Default Screen Section”.
Using the first device section listed.
[ 30.584] (
) | |–>Device “Allwinner A10/A13 FBDEV”
[ 30.584] (==) No monitor specified for screen “Default Screen Section”.
Using a default monitor configuration.
[ 30.584] (==) Automatically adding devices
[ 30.584] (==) Automatically enabling devices
[ 30.584] (==) Automatically adding GPU devices
[ 30.587] (==) Max clients allowed: 256, resource mask: 0x1fffff
[ 30.589] (WW) The directory “/usr/share/fonts/X11/cyrillic” does not exist.
[ 30.589] Entry deleted from font path.
[ 30.591] (==) FontPath set to:
/usr/share/fonts/X11/misc,
/usr/share/fonts/X11/100dpi/:unscaled,
/usr/share/fonts/X11/75dpi/:unscaled,
/usr/share/fonts/X11/Type1,
/usr/share/fonts/X11/100dpi,
/usr/share/fonts/X11/75dpi,
built-ins
[ 30.591] (==) ModulePath set to “/usr/lib/xorg/modules”
[ 30.591] (II) The server relies on udev to provide the list of input devices.
If no devices become available, reconfigure udev or disable AutoAddDevices.
[ 30.591] (II) Loader magic: 0x636f20
[ 30.591] (II) Module ABI versions:
[ 30.591] X.Org ANSI C Emulation: 0.4
[ 30.591] X.Org Video Driver: 20.0
[ 30.591] X.Org XInput driver : 22.1
[ 30.591] X.Org Server Extension : 9.0
[ 30.593] (–) using VT number 2

[ 30.593] (II) systemd-logind: logind integration requires -keeptty and -keeptty was not provided, disabling logind integration
[ 30.593] (II) no primary bus or device found
[ 30.594] (II) LoadModule: “glx”
[ 30.597] (II) Loading /usr/lib/xorg/modules/extensions/libglx.so
[ 30.635] (II) Module glx: vendor=“X.Org Foundation”
[ 30.635] compiled for 1.18.4, module version = 1.0.0
[ 30.635] ABI class: X.Org Server Extension, version 9.0
[ 30.635] (==) AIGLX enabled
[ 30.635] (II) LoadModule: “fbturbo”
[ 30.635] (II) Loading /usr/lib/xorg/modules/drivers/fbturbo_drv.so
[ 30.638] (II) Module fbturbo: vendor=“X.Org Foundation”
[ 30.638] compiled for 1.18.4, module version = 0.5.1
[ 30.638] Module class: X.Org Video Driver
[ 30.638] ABI class: X.Org Video Driver, version 20.0
[ 30.638] (II) FBTURBO: driver for framebuffer: fbturbo
[ 30.642] (WW) Falling back to old probe method for fbturbo
[ 30.643] (II) Loading sub module “fbdevhw”
[ 30.643] (II) LoadModule: “fbdevhw”
[ 30.643] (II) Loading /usr/lib/xorg/modules/libfbdevhw.so
[ 30.644] (II) Module fbdevhw: vendor=“X.Org Foundation”
[ 30.644] compiled for 1.18.4, module version = 0.0.2
[ 30.644] ABI class: X.Org Video Driver, version 20.0
[ 30.645] (II) FBTURBO(0): using /dev/fb0
[ 30.645] (II) FBTURBO(0): Creating default Display subsection in Screen section
“Default Screen Section” for depth/fbbpp 24/32
[ 30.645] (==) FBTURBO(0): Depth 24, (==) framebuffer bpp 32
[ 30.645] (==) FBTURBO(0): RGB weight 888
[ 30.645] (==) FBTURBO(0): Default visual is TrueColor
[ 30.645] (==) FBTURBO(0): Using gamma correction (1.0, 1.0, 1.0)
[ 30.645] (II) FBTURBO(0): hardware: BCM2708 FB (video memory: 7011kB)
[ 30.645] () FBTURBO(0): Option “fbdev” “/dev/fb0”
[ 30.645] (
) FBTURBO(0): Option “SwapbuffersWait” “true”
[ 30.645] (II) FBTURBO(0): processor: Unknown
[ 30.645] (II) FBTURBO(0): checking modes against framebuffer device…
[ 30.645] (II) FBTURBO(0): checking modes against monitor…
[ 30.645] (–) FBTURBO(0): Virtual size is 1824x984 (pitch 1824)
[ 30.645] (**) FBTURBO(0): Built-in mode “current”
[ 30.645] (==) FBTURBO(0): DPI set to (96, 96)
[ 30.645] (II) Loading sub module “fb”
[ 30.645] (II) LoadModule: “fb”
[ 30.645] (II) Loading /usr/lib/xorg/modules/libfb.so
[ 30.649] (II) Module fb: vendor=“X.Org Foundation”
[ 30.649] compiled for 1.18.4, module version = 1.0.0
[ 30.649] ABI class: X.Org ANSI C Emulation, version 0.4
[ 30.649] (==) Depth 24 pixmap format is 32 bpp
[ 30.661] (II) FBTURBO(0): using backing store heuristics
[ 30.667] (II) FBTURBO(0): can’t load ‘g2d_23’ kernel module
[ 30.667] (II) FBTURBO(0): failed to enable the use of sunxi display controller
[ 30.667] (II) FBTURBO(0): No sunxi-g2d hardware detected (check /dev/disp and /dev/g2d)
[ 30.667] (II) FBTURBO(0): G2D hardware acceleration can’t be enabled
[ 30.667] (II) FBTURBO(0): enabled fbdev copyarea acceleration
[ 30.667] (==) FBTURBO(0): Backing store enabled
[ 30.672] (==) FBTURBO(0): DPMS enabled
[ 30.672] (II) FBTURBO(0): failed to enable hardware cursor
[ 30.672] (II) FBTURBO(0): no 3D acceleration because the driver has been compiled without libUMP
[ 30.672] (II) FBTURBO(0): if this is wrong and needs to be fixed, please check ./configure log
[ 30.673] (==) RandR enabled
[ 30.689] (II) SELinux: Disabled on system
[ 30.694] (II) AIGLX: Screen 0 is not DRI2 capable
[ 30.694] (EE) AIGLX: reverting to software rendering
[ 31.520] (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
[ 31.522] (II) AIGLX: Loaded and initialized swrast
[ 31.522] (II) GLX: Initialized DRISWRAST GL provider for screen 0
[ 31.687] (II) FBTURBO(0): using backing store heuristics
[ 31.693] (II) FBTURBO(0): can’t load ‘g2d_23’ kernel module
[ 31.693] (II) FBTURBO(0): failed to enable the use of sunxi display controller
[ 31.693] (II) FBTURBO(0): No sunxi-g2d hardware detected (check /dev/disp and /dev/g2d)
[ 31.693] (II) FBTURBO(0): G2D hardware acceleration can’t be enabled
[ 31.693] (II) FBTURBO(0): enabled fbdev copyarea acceleration
[ 31.694] (==) FBTURBO(0): DPMS enabled
[ 31.694] (II) FBTURBO(0): failed to enable hardware cursor
[ 31.694] (II) FBTURBO(0): no 3D acceleration because the driver has been compiled without libUMP
[ 31.694] (II) FBTURBO(0): if this is wrong and needs to be fixed, please check ./configure log
[ 31.694] (==) RandR enabled
[ 31.707] (II) SELinux: Disabled on system
[ 31.709] (II) AIGLX: Screen 0 is not DRI2 capable
[ 31.709] (EE) AIGLX: reverting to software rendering
[ 31.714] (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
[ 31.716] (II) AIGLX: Loaded and initialized swrast
[ 31.716] (II) GLX: Initialized DRISWRAST GL provider for screen 0

Are you using the screen you mentioned here?

it’s not my setup, everything works for me thank you. this is from my friend who prefers to stay with 2.xxx he only uses hdmi to tv. sound does not work but IU surface

Ok, what is the brand and model name of his HDMI display?

In case there has been a download problem during the installation of the Touch Display plugin: Did you already try to uninstall and re-install the plugin?