init
This commit is contained in:
commit
72925d313b
57
README.md
Normal file
57
README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
Monitor display
|
||||
===============
|
||||
|
||||
Configurations files loaded (if exist):
|
||||
|
||||
* `/etc/monitordisplay/config.ini`
|
||||
* `$HOME/.config/monitordisplay/config.ini`
|
||||
* `$HOME/.monitordisplay`
|
||||
|
||||
Screens's sections examples:
|
||||
|
||||
```
|
||||
[screen:HUMAIN_SCREEN_NAME1]
|
||||
name=SYSTEM_SCREEN_NAME1
|
||||
resolutionX=1920
|
||||
resolutionY=1080
|
||||
|
||||
[screen:HUMAIN_SCREEN_NAME2]
|
||||
name=SYSTEM_SCREEN_NAME2
|
||||
resolutionX=1024
|
||||
resolutionY=768
|
||||
|
||||
[screen:HUMAIN_SCREEN_NAME3]
|
||||
name=SYSTEM_SCREEN_NAME2
|
||||
resolutionX=1920
|
||||
resolutionY=1080
|
||||
```
|
||||
|
||||
Modes's sections examples:
|
||||
|
||||
```
|
||||
[mode:MODE_NAME]
|
||||
config[]=HUMAIN_SCREEN_NAME1,HUMAIN_SCREEN_NAME2
|
||||
config[]=HUMAIN_SCREEN_NAME2,HUMAIN_SCREEN_NAME1
|
||||
primary=HUMAIN_SCREEN_NAME1
|
||||
|
||||
[mode:MODE_NAME2]
|
||||
config[]=HUMAIN_SCREEN_NAME1,HUMAIN_SCREEN_NAME3
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
monitordisplay -m MODE_NAME
|
||||
# equals: xrand --output SYSTEM_SCREEN_NAME1 --primary --mode 1920x1080 --pos 0x0 --output SYSTEM_SCREEN_NAME2 --mode 1024x768 --pos 1920x0
|
||||
|
||||
monitordisplay -t
|
||||
# equals: xrand --output SYSTEM_SCREEN_NAME2 --mode 1024x768 --pos 0x0 --output SYSTEM_SCREEN_NAME1 --mode 1920x1080 --primary --pos 1024x0
|
||||
|
||||
monitordisplay -m MODE_NAME2
|
||||
# equals: xrand --output SYSTEM_SCREEN_NAME1 --primary --mode 1920x1080 --pos 0x0 --output SYSTEM_SCREEN_NAME3 --mode 1920x1080 --pos 1920x0 --output SYSTEM_SCREEN_NAME3 --off
|
||||
|
||||
# For removing the parameter "--off"
|
||||
|
||||
monitordisplay -m MODE_NAME2 -s
|
||||
# equals: xrand --output SYSTEM_SCREEN_NAME1 --primary --mode 1920x1080 --pos 0x0 --output SYSTEM_SCREEN_NAME3 --mode 1920x1080 --pos 1920x0
|
||||
```
|
20
config.ini-dist
Normal file
20
config.ini-dist
Normal file
|
@ -0,0 +1,20 @@
|
|||
[screen:laptop]
|
||||
name=eDP1
|
||||
resolutionX=1920
|
||||
resolutionY=1080
|
||||
|
||||
[screen:hdmi]
|
||||
name=HDMI1
|
||||
resolutionX=1920
|
||||
resolutionY=1080
|
||||
|
||||
[mode:laptop]
|
||||
config[]=laptop
|
||||
|
||||
[mode:hdmi]
|
||||
config[]=hdmi
|
||||
|
||||
[mode:work]
|
||||
config[]=laptop,hdmi
|
||||
config[]=hdmi,laptop
|
||||
primary=laptop
|
257
monitordisplay
Executable file
257
monitordisplay
Executable file
|
@ -0,0 +1,257 @@
|
|||
#!/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,
|
||||
];
|
||||
|
||||
return filter($data, $default);
|
||||
}
|
||||
|
||||
function filterMode(array $data)
|
||||
{
|
||||
$default = [
|
||||
'config' => [],
|
||||
'primary' => 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 ($mode === null) {
|
||||
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 ($toggle === true) {
|
||||
if ($currentMode['mode'] === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($currentMode['config'] === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currentMode['config'] = (int) $currentMode['config'];
|
||||
|
||||
if (!array_key_exists($currentMode['config'], $mode['config'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$configs = $mode['config'];
|
||||
$config = ($currentMode['config'] + 1) % count($configs);
|
||||
} else {
|
||||
$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'];
|
||||
|
||||
if (empty($name) || empty($resolutionX) || empty($resolutionY)) {
|
||||
error(sprintf('Invalid screen configuration "%s"', $screen));
|
||||
die(1);
|
||||
}
|
||||
|
||||
$command[] = '--output';
|
||||
$command[] = $name;
|
||||
$screensUsed[] = $name;
|
||||
|
||||
if ($mode['primary'] === $name) {
|
||||
$command[] = '--primary';
|
||||
}
|
||||
|
||||
$command[] = '--mode';
|
||||
$command[] = sprintf('%dx%d', $resolutionX, $resolutionY);
|
||||
|
||||
$command[] = '--pos';
|
||||
$command[] = sprintf('%dx%d', $x, 0);
|
||||
$x += $resolutionX;
|
||||
}
|
||||
|
||||
if ($addOff) {
|
||||
foreach ($screens as $screen) {
|
||||
if (!in_array($screen['name'], $screensUsed)) {
|
||||
$command[] = '--output';
|
||||
$command[] = $screen['name'];
|
||||
$command[] = '--off';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$command = implode(' ', $command);
|
||||
|
||||
return [
|
||||
'tmp' => sprintf("mode=%s\nconfig=%d", $tmpMode, $tmpConfig),
|
||||
'command' => $command,
|
||||
];
|
||||
}
|
||||
|
||||
$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 ($parsing === false) {
|
||||
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: %s', implode(', ', $files)));
|
||||
die(1);
|
||||
}
|
||||
|
||||
$screens = [];
|
||||
$modes = [];
|
||||
|
||||
foreach ($config as $section => $values) {
|
||||
$type = explode(':', $section);
|
||||
|
||||
if (count($type) !== 2) {
|
||||
error(sprintf('Invalid section "%s". Ignored.', $section));
|
||||
}
|
||||
|
||||
if ($type[0] === 'screen') {
|
||||
$screens[$type[1]] = filterScreen($values);
|
||||
} elseif ($type[0] === 'mode') {
|
||||
$modes[$type[1]] = filterMode($values);
|
||||
} else {
|
||||
error(sprintf('Invalid 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:ts');
|
||||
$mode = isset($options['m']) ? $options['m'] : null;
|
||||
$toggle = isset($options['t']);
|
||||
$addOff = !isset($options['s']);
|
||||
$build = build($modes, $screens, $mode, $toggle, $currentMode, $addOff);
|
||||
|
||||
if (!empty($build)) {
|
||||
file_put_contents(getCurrentModeFile(), $build['tmp']);
|
||||
shell_exec($build['command']);
|
||||
}
|
Loading…
Reference in a new issue