311 righe
7 KiB
PHP
File eseguibile
311 righe
7 KiB
PHP
File eseguibile
#!/usr/bin/php
|
|
<?php
|
|
|
|
function error($message)
|
|
{
|
|
file_put_contents('php://stderr', $message."\n");
|
|
}
|
|
|
|
function notice($message)
|
|
{
|
|
file_put_contents('php://stdin', $message."\n");
|
|
}
|
|
|
|
function filter(array $data, array $default)
|
|
{
|
|
foreach ($data as $k => $v) {
|
|
if (!array_key_exists($k, $default)) {
|
|
unset($data[$k]);
|
|
} elseif (is_array($default[$k]) && !is_array($v)) {
|
|
$data[$k] = (array) $v;
|
|
}
|
|
}
|
|
|
|
foreach ($default as $k => $v) {
|
|
if (!array_key_exists($k, $data)) {
|
|
$data[$k] = $v;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
function filterScreen(array $data)
|
|
{
|
|
$default = [
|
|
'name' => null,
|
|
'resolutionX' => null,
|
|
'resolutionY' => null,
|
|
'dpi' => null,
|
|
'xrandr_extra' => null,
|
|
];
|
|
|
|
return filter($data, $default);
|
|
}
|
|
|
|
function filterMode(array $data)
|
|
{
|
|
$default = [
|
|
'config' => [],
|
|
'primary' => null,
|
|
'before_command' => null,
|
|
'after_command' => null,
|
|
];
|
|
|
|
$data = filter($data, $default);
|
|
|
|
foreach ($data['config'] as $k => $v) {
|
|
$v = explode(',', $v);
|
|
$v = array_map('trim', $v);
|
|
|
|
$data['config'][$k] = $v;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
function getCurrentModeFile()
|
|
{
|
|
return sys_get_temp_dir().'/monitordisplay.tmp';
|
|
}
|
|
|
|
function getCurrentMode()
|
|
{
|
|
$currentModeFile = getCurrentModeFile();
|
|
|
|
if (file_exists($currentModeFile)) {
|
|
$currentMode = (array) @parse_ini_file($currentModeFile);
|
|
} else {
|
|
$currentMode = [];
|
|
}
|
|
|
|
return filter($currentMode, [
|
|
'mode' => null,
|
|
'config' => null,
|
|
]);
|
|
}
|
|
|
|
function build(array $modes, array $screens, $mode, $toggle, array $currentMode, $addOff)
|
|
{
|
|
if (null === $mode) {
|
|
if (!array_key_exists($currentMode['mode'], $modes)) {
|
|
return;
|
|
}
|
|
|
|
$tmpMode = $currentMode['mode'];
|
|
$mode = $modes[$currentMode['mode']];
|
|
} else {
|
|
if (!array_key_exists($mode, $modes)) {
|
|
return;
|
|
}
|
|
|
|
$tmpMode = $mode;
|
|
$mode = $modes[$mode];
|
|
}
|
|
|
|
if (false !== $toggle) {
|
|
$configs = $mode['config'];
|
|
$configsKeys = array_keys($configs);
|
|
|
|
if (null === $currentMode['mode']) {
|
|
$currentMode['config'] = $configsKeys[0];
|
|
}
|
|
|
|
if (!array_key_exists($currentMode['config'], $mode['config'])) {
|
|
$currentMode['config'] = $configsKeys[0];
|
|
}
|
|
|
|
if (true === $toggle) {
|
|
foreach ($configsKeys as $k => $key) {
|
|
if ($key == $currentMode['config']) {
|
|
$currentKey = $k;
|
|
}
|
|
}
|
|
|
|
$config = $configsKeys[($currentKey + 1) % count($configsKeys)];
|
|
} elseif (array_key_exists($toggle, $configs)) {
|
|
$config = $toggle;
|
|
} else {
|
|
error(sprintf('Invalid config "%s"', $toggle));
|
|
die(1);
|
|
}
|
|
} else {
|
|
$config = array_keys($mode['config'])[0];
|
|
}
|
|
|
|
if (!array_key_exists($config, $mode['config'])) {
|
|
return;
|
|
}
|
|
|
|
$tmpConfig = $config;
|
|
$config = $mode['config'][$config];
|
|
|
|
$command = ['xrandr'];
|
|
|
|
$x = 0;
|
|
|
|
$screensUsed = [];
|
|
|
|
foreach ($config as $screen) {
|
|
if (!array_key_exists($screen, $screens)) {
|
|
return;
|
|
}
|
|
|
|
$tScreen = $screens[$screen];
|
|
$name = $tScreen['name'];
|
|
$resolutionX = $tScreen['resolutionX'];
|
|
$resolutionY = $tScreen['resolutionY'];
|
|
$dpi = $tScreen['dpi'];
|
|
$xrandrExtra = $tScreen['xrandr_extra'];
|
|
|
|
if (empty($name) || empty($resolutionX) || empty($resolutionY)) {
|
|
error(sprintf('Invalid screen configuration "%s"', $screen));
|
|
die(1);
|
|
}
|
|
|
|
$command[] = '--output';
|
|
$command[] = escapeshellarg($name);
|
|
$screensUsed[] = $name;
|
|
|
|
if ($mode['primary'] === $name) {
|
|
$command[] = '--primary';
|
|
}
|
|
|
|
if (null !== $dpi) {
|
|
$command[] = sprintf('--dpi %d', $dpi);
|
|
}
|
|
|
|
$command[] = '--mode';
|
|
$command[] = sprintf('%dx%d', $resolutionX, $resolutionY);
|
|
|
|
$command[] = '--pos';
|
|
$command[] = sprintf('%dx%d', $x, 0);
|
|
$x += (int) $resolutionX;
|
|
|
|
if (null !== $xrandrExtra) {
|
|
$command[] = $xrandrExtra;
|
|
}
|
|
}
|
|
|
|
if ($addOff) {
|
|
foreach ($screens as $screen) {
|
|
if (!in_array($screen['name'], $screensUsed)) {
|
|
$command[] = '--output';
|
|
$command[] = escapeshellarg($screen['name']);
|
|
$command[] = '--off';
|
|
}
|
|
}
|
|
}
|
|
|
|
$command = implode(' ', $command);
|
|
|
|
return [
|
|
'config' => sprintf("mode=%s\nconfig=%s", $tmpMode, $tmpConfig),
|
|
'command' => $command,
|
|
'mode' => $mode,
|
|
];
|
|
}
|
|
|
|
$files = [
|
|
'/etc/monitordisplay/config.ini',
|
|
getenv('HOME').'/.config/monitordisplay/config.ini',
|
|
getenv('HOME').'/.monitordisplay',
|
|
];
|
|
|
|
$config = [];
|
|
$currentMode = getCurrentMode();
|
|
|
|
foreach ($files as $file) {
|
|
if (file_exists($file)) {
|
|
$parsing = @parse_ini_file($file, true);
|
|
|
|
if (false === $parsing) {
|
|
error(sprintf('The file "%s" is not a valid ini file', $file));
|
|
|
|
continue;
|
|
}
|
|
|
|
notice(sprintf('Configuration file merged: %s', $file));
|
|
|
|
$config = array_merge(
|
|
$config,
|
|
$parsing
|
|
);
|
|
}
|
|
}
|
|
|
|
if (empty($config)) {
|
|
error('No configuration found');
|
|
error(sprintf('Paths checked: \n%s', implode(', ', $files)));
|
|
die(1);
|
|
}
|
|
|
|
$screens = [];
|
|
$modes = [];
|
|
|
|
foreach ($config as $section => $values) {
|
|
$type = explode(':', $section);
|
|
|
|
if (2 !== count($type)) {
|
|
error(sprintf('Invalid section "%s". Ignored', $section));
|
|
}
|
|
|
|
if ('screen' === $type[0]) {
|
|
$screens[$type[1]] = filterScreen($values);
|
|
} elseif ('mode' === $type[0]) {
|
|
$modes[$type[1]] = filterMode($values);
|
|
} else {
|
|
error(sprintf('Section "%s" ignored', $section));
|
|
}
|
|
}
|
|
|
|
if (empty($screens)) {
|
|
error('No screen found');
|
|
die(1);
|
|
}
|
|
|
|
if (empty($modes)) {
|
|
error('No mode found');
|
|
die(1);
|
|
}
|
|
|
|
$options = getopt('m:t::sn');
|
|
$mode = isset($options['m']) ? $options['m'] : null;
|
|
$toggle = isset($options['t']) ? (false === $options['t'] ? true : $options['t']) : false;
|
|
$addOff = !isset($options['s']);
|
|
$isTest = isset($options['n']);
|
|
$build = build($modes, $screens, $mode, $toggle, $currentMode, $addOff);
|
|
|
|
if (!empty($build)) {
|
|
file_put_contents(getCurrentModeFile(), $build['config']);
|
|
|
|
$commands = [
|
|
$build['mode']['before_command'],
|
|
$build['command'],
|
|
$build['mode']['after_command'],
|
|
];
|
|
|
|
$output = [];
|
|
|
|
if ($isTest) {
|
|
$output[] = 'Mode TEST';
|
|
}
|
|
|
|
foreach ($commands as $command) {
|
|
if (!empty($command)) {
|
|
$output[] = 'Command: '.$command;
|
|
|
|
if (!$isTest) {
|
|
exec($command, $output);
|
|
}
|
|
}
|
|
}
|
|
|
|
notice(implode("\n", $output));
|
|
|
|
die(0);
|
|
}
|
|
|
|
error(sprintf('Invalid mode "%s"', $mode));
|
|
die(1);
|