방법 1: 분석xrandr --verbose

방법 1: 분석xrandr --verbose

각 연결 지점(있는 경우)에 연결된 물리적 모니터를 식별하면서 DisplayPort-1-7또는 같은 X 서버 디스플레이 연결 지점을 열거하고 싶습니다 .HDMI-A-1-1

동기 부여: 저는 Xubuntu 18.04(Bionic)을 사용하고 있는데 xfce는 도킹/도킹 해제 시 모니터를 자동으로 구성하는 기능이 제대로 작동하지 않습니다. Dell 노트북을 사용하고 있는데 GPU가 도킹, 도킹 해제 및 재도킹 시 모니터 연결 식별자를 변경하므로 고정된 식별자만으로는 모니터를 설정할 수 없어 arandr실패하게 됩니다.

내 목표는 연결된 모니터를 보고 xrandr을 실행하여 내가 원하는 방식으로 모니터를 설정할 수 있는 간단한 Bash/Python 스크립트를 작성하는 것입니다.

잠재적인 도구:

  • xrandrX Server 특정 디스플레이 연결 지점 목록은 제공되었지만 모니터 ID는 제공되지 않았습니다.
  • hwinfo --monitor모니터를 나열하고 EDID 데이터를 디코딩하여 모델 이름과 일련 ID를 확인할 수 있지만 X Windows 이름은 확인할 수 없습니다.

어떤 물리적 모니터가 어떤 X 서버 포트에 연결되어 있는지 확인하는 방법을 찾지 못했습니다.

편집하다다음 설명을 명확히 하려면: 내 목표는 이름, 모델 또는 일련 번호로 모니터를 식별하는 것입니다. 그런 다음 xrandr스크립트에서 모니터의 ID를 사용하여 해상도와 위치를 설정할 수 있습니다 .

답변1

그냥 좋은 부분들:이 작업을 수행하는 데 사용하는 Python 스크립트는 다음과 같습니다., python-xlib설치가 필요합니다.

지금까지 나는 X 서버가 연결 목록을 표시하고 모니터가 각 서버에 연결되도록 할 수 있는 소스 하나를 찾았습니다. 바로 X 자체입니다. 구문 분석에 대한 허용 범위와 X에서 직접 데이터를 가져오는 능력에 따라 X에서 이 정보를 얻는 방법에는 여러 가지가 있습니다.

방법 1: 분석xrandr --verbose

xrandr --verbose명령에는 디스플레이 연결을 모니터에 일치시키는 데 필요한 모든 정보가 포함되어 있습니다. 단일 모니터 연결에 대한 출력은 다음과 같습니다.

Screen 0: minimum 320 x 200, current 6400 x 1600, maximum 8192 x 8192
DP-1 disconnected (normal left inverted right x axis y axis)
    [extra content removed]
DisplayPort-1-7 connected 1920x1080+0+464 (0x4a) normal (normal left inverted right x axis y axis) 510mm x 287mm
    Identifier: 0x224
    Timestamp:  6668772
    Subpixel:   unknown
    Gamma:      1.0:1.0:1.0
    Brightness: 1.0
    Clones:    
    CRTC:       4
    CRTCs:      0 4 5 6 7
    Transform:  1.000000 0.000000 0.000000
                0.000000 1.000000 0.000000
                0.000000 0.000000 1.000000
               filter: 
    EDID: 
        00ffffffffffff0010ac73404c424241
        ------[more hex redacted]-------
        001155223811000a202020202020007e
    GAMMA_LUT_SIZE: 4096 
        range: (0, -1)
    DEGAMMA_LUT_SIZE: 4096 
        range: (0, -1)
    GAMMA_LUT: 0 
        range: (0, 65535)
    CTM: 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 
        0 1 
    DEGAMMA_LUT: 0 
        range: (0, 65535)
    TearFree: auto 
        supported: off, on, auto
    vrr_capable: 0 
        range: (0, 1)
    max bpc: 8 
        range: (8, 16)
    underscan vborder: 0 
        range: (0, 128)
    underscan hborder: 0 
        range: (0, 128)
    underscan: off 
        supported: off, on, auto
    scaling mode: None 
        supported: None, Full, Center, Full aspect
    link-status: Good 
        supported: Good, Bad
    CONNECTOR_ID: 76 
        supported: 76
    non-desktop: 0 
        range: (0, 1)
  1920x1080 (0x4a) 148.500MHz +HSync +VSync *current +preferred
        h: width  1920 start 2008 end 2052 total 2200 skew    0 clock  67.50KHz
        v: height 1080 start 1084 end 1089 total 1125           clock  60.00Hz
  1680x1050 (0x9b) 146.250MHz -HSync +VSync
        h: width  1680 start 1784 end 1960 total 2240 skew    0 clock  65.29KHz
        v: height 1050 start 1053 end 1059 total 1089           clock  59.95Hz
[extra content removed]

이 출력을 구문 분석하는 것은 좋지 않습니다. 화면에 대한 디스플레이 연결을 나타내는 라인을 식별해야 하며 연결 ​​여부 등에 따라 달라집니다. 하지만 이렇게 하면 EDID를 추출하여 원시 바이트로 변환하고 parse-edid.

방법 2: Xlib클라이언트 및 EDID 파서

하나 있다Xlib용 Python 클라이언트연결된 각 모니터에서 디스플레이 연결 및 관련 EDID 바이트를 얻는 데 필요한 도구가 있습니다. 마찬가지로,EDID 데이터 구문 분석을 위한 Python 라이브러리, 이상적이지는 않지만(아래에서 설명) 그러나 저는 원하는 답을 얻기 위해 이 두 프로젝트를 함께 사용하는 샘플 스크립트를 만들었습니다.

#!/usr/bin/env python3

import pyedid.edid, pyedid.helpers.registry
import Xlib.display

def get_x_displays():
    # Used by PyEDID to fetch manufacturers given their EDID code
    registry = pyedid.helpers.registry.Registry.from_web()

    # Xlib resources
    d = Xlib.display.Display()
    root = d.screen().root
    resources = root.xrandr_get_screen_resources()._data

    outputs = {}
    for output in resources['outputs']:
        output_info = d.xrandr_get_output_info(output, resources['config_timestamp'])._data
        output_name = output_info['name']
        props = d.xrandr_list_output_properties(output)
        edid_data = None

        # Look through the atoms (properties) of each output to see if there's one named 'EDID'
        for atom in props._data['atoms']:
            atom_name = d.get_atom_name(atom)
            if atom_name == 'EDID':
                edid_raw = d.xrandr_get_output_property(output, atom, 0, 0, 1000)._data['value']
                edid_data = pyedid.edid.Edid(bytes(edid_raw)[:128], registry)
                break

        outputs[output_name] = edid_data

    return outputs

if __name__ == '__main__':
    displays = get_x_displays()
    for connection, monitor in sorted(displays.items(), key=lambda kv: kv[0]):
        print(connection)
        print('    ' + ("No connection or empty EDID" if monitor is None else
                        "{} ({})".format(monitor.name, monitor.serial)))

내 컴퓨터에서는 다음과 같은 출력이 생성됩니다(일련 번호가 손상되었습니다).

DP-1
    No connection or empty EDID
DP-2
    No connection or empty EDID
DP-3
    No connection or empty EDID
DisplayPort-1-3
    No connection or empty EDID
DisplayPort-1-4
    No connection or empty EDID
DisplayPort-1-5
    No connection or empty EDID
DisplayPort-1-6
    DELL UP3017 (DDSB553SBDFL)
DisplayPort-1-7
    DELL U2312HM (V092DMLS657D)
DisplayPort-1-8
    No connection or empty EDID
HDMI-1
    No connection or empty EDID
HDMI-A-1-1
    No connection or empty EDID
eDP-1
    None (0)
eDP-1-1
    No connection or empty EDID

PyEDID 라이브러리에는 EDID의 제조업체 필드를 채울 수 있도록 제조업체의 "레지스트리"가 필요합니다. from_web()온라인 소스에서 레지스트리를 생성하기 위한 호출은 이 스크립트에서 가장 느린 부분입니다. 내가 만들었다이 스크립트의 대체 버전제조업체 조회를 완전히 건너뛰고 대신 원시 값을 전달하여 이 요구 사항을 제거합니다.

답변2

해보셨나요`

    $ xrandr --listactivemonitors
    Monitors: 2
    0: +*DVI-0 1920/521x1080/293+0+0  DVI-0
    1:  +DVI-1 1920/521x1080/293+0+0  DVI-1

다음과 같은 표 형식으로 나뉩니다.

[화면/모니터] 번호: [커넥터 + 모드] [커넥터]

관련 정보