Browse Source

init

master
Simon Vieille 2 years ago
commit
72925d313b
3 changed files with 334 additions and 0 deletions
  1. 57
    0
      README.md
  2. 20
    0
      config.ini-dist
  3. 257
    0
      monitordisplay

+ 57
- 0
README.md View 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
- 0
config.ini-dist View 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
- 0
monitordisplay View 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…
Cancel
Save