In addition to Adrien Beau answer.
Changing monitor input source
Standard change input source command is 0x60. So you want to use such command:
ddccontrol -r 0x60 -w $some_value dev:/dev/i2c-X
Determining values to pass to monitor
But how do you know which values are responsible for which input source?
I do not know if vendors provide such information, but I have found a way how you can know it without asking vendor.
Just read current value of 0x60 command (using sudo ddccontrol -r 0x60 dev:/dev/i2c-X
). It will return something like this:
Case when your monitor is in ddccontrol database
EDID readings:
Plug and Play ID: DELA0D7 [DELL P2217H (VGA)]
Input type: Analog
Reading 0x60...
Control 0x60: +/257/4626 C [Input Source Select]
Case when your monitor is not in ddccontrol database
EDID readings:
Plug and Play ID: DELA0D9 [VESA standard monitor]
Input type: Digital
=============================== WARNING ===============================
There is no support for your monitor in the database, but ddccontrol is
using a basic generic profile. Many controls will not be supported, and
some controls may not work as expected.
Please update ddccontrol-db, or, if you are already using the latest
version, please send the output of the following command to
d[email protected]:
LANG= LC_ALL= ddccontrol -p -c -d
Thank you.
=============================== WARNING ===============================
Reading 0x60...
Control 0x60: +/4369/4626 C [Input Source Select]
Let's assume your monitor is not in ddccontrol database. Note this 4369 value. This is a value that you will use to switch monitor back to current state via cable you are currently speak to monitor. Note, that this value will be different when you use another transport cable (I mean port which you use to speak to monitor, for example via vga and via hdmi values will be different even for same input source).
Now, disable auto selecting input source using monitor's osd menu, because we do not want it for now.
Now switch input source using your monitor's osd menu, and then read current value. For this example, I switched monitor to use vga source (source is coming from another computer), while still speaking to monitor via hdmi using first computer, and returned value is 4353.
Do the same for all inputs which you are planning to use for switching.
Ok, so now you know values of monitor in different source states. Now you can switch input source for monitor using:
sudo ddccontrol -r 0x60 -w 4353 dev:/dev/i2c-X # switch to vga input using hdmi cable on Dell P2217H
sudo ddccontrol -r 0x60 -w 4369 dev:/dev/i2c-X # switch to hdmi input using hdmi cable on Dell P2217H
Values are presented in decimal, however you can use hexadecimal values like this:
sudo ddccontrol -r 0x60 -w 0x1101 dev:/dev/i2c-X # 0x1101 is 4353
sudo ddccontrol -r 0x60 -w 0x1111 dev:/dev/i2c-X # 0x1111 is 4369
Adding your monitor to ddccontrol database
Now you want your monitor to be in ddccontrol-db. You need to explore values for all functions of your monitor and which values are applied to which state. Then you should create xml file describing all these values. Note, there will be several xml files, due to different ports use different monitor Plug and Play id.
For example, for my DELL P2217H monitor I will create two files:
DELA0D7.xml (this id is used when connecting via vga) and DELA0D9.xml (this id is used when connecting via hdmi).
Dell P2217H has one vga, one hdmi and one displayport. Because I have not got displayport devices, I cannot make explorations to create DELA0D8.xml (this id is used when connecting via displayport).
Some description of xml parameters could be found at Monitor Database Structure page (file:///usr/share/doc/ddccontrol/html/apes02.html).
Capabilities (caps) and Plug and Play ID could be recieved using
sudo ddccontrol -c dev:/dev/i2c-X
.
When you are ready, contribute to https://github.com/ddccontrol/ddccontrol-db repository.
Detect monitor by serial number
Let's assume you have connected several monitors of the same model to a single computer. Then you need to differentiate monitors somehow. For this purpose, I have created a script, which determines i2c bus number by monitor serial number.
I do it using
sudo get-edid -b $X 2>/dev/null | grep $TARGET_SERIAL
See my repository for more details: https://github.com/Ashark/Ashark-bin/blob/master/i2c-bus-by-monitor-serial
Final script for keyboard binding
Now, see this script: https://github.com/Ashark/Ashark-bin/blob/master/switch-monitor-source
You can use it as following:
switch-monitor-source -s 0G2TG7360DXB -u # get and cache i2c-id number for monitor with specified s/n
switch-monitor-source -s 0G2TG7360DXB -v # switch that monitor to vga input
switch-monitor-source -s 0G2TG7360DXB -h # switch that monitor to hdmi input
Now you can bind two last commands to keyboard shortcut and use them for fast switching. Amazing!