[mutter] tools: Add tool for pretty printing DisplayConfig.GetCurrentState



commit 8a4bec767b9fb2cb2bef2ac5d62d9c673dc327b4
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Jun 1 12:13:27 2022 +0200

    tools: Add tool for pretty printing DisplayConfig.GetCurrentState
    
    It can pretty print either output from a `gdbus` call, from e.g. a bug
    report, or invoke `gdbus` itself and get the state of the running
    compositor.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2448>

 tools/get-state.py | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)
---
diff --git a/tools/get-state.py b/tools/get-state.py
new file mode 100755
index 0000000000..624738ad18
--- /dev/null
+++ b/tools/get-state.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python3
+
+import enum
+import subprocess
+import sys
+
+from gi.repository import GLib
+
+
+class Source(enum.Enum):
+    DBUS = 1
+    FILE = 2
+
+
+def print_usage():
+    print(f'Usage: {sys.argv[0]} [--help] [FILE]')
+
+def print_help():
+    print(f'Without any argument this command queries the GNOME display server '
+           'using D-Bus and pretty prints the result')
+    print()
+    print(f'  --help        Show this help screen')
+    print(f'  FILE          Read the output from gdbus call instead of calling D-Bus')
+
+
+if len(sys.argv) > 2:
+    print_usage()
+    sys.exit(1)
+elif len(sys.argv) == 1:
+    source = Source.DBUS
+elif sys.argv[1] == '--help':
+    print_usage()
+    print_help()
+    sys.exit(0)
+else:
+    source = Source.FILE
+    path = sys.argv[1]
+
+type_signature = '(ua((ssss)a(siiddada{sv})a{sv})a(iiduba(ssss)a{sv})a{sv})'
+variant_type = GLib.VariantType.new(type_signature)
+
+if source == Source.DBUS:
+    command = 'gdbus call -e '\
+        '-d org.gnome.Mutter.DisplayConfig '\
+        '-o /org/gnome/Mutter/DisplayConfig '\
+        '-m org.gnome.Mutter.DisplayConfig.GetCurrentState'
+    result = subprocess.run(command,
+                            shell=True, check=True, capture_output=True, text=True)
+    data = result.stdout
+else:
+    if path == '-':
+        data = sys.stdin.read()
+    else:
+        with open(path) as file:
+            data = file.read()
+
+variant = GLib.variant_parse(variant_type, data)
+
+def transform_to_string(transform):
+    match transform:
+        case 0: return 'normal'
+        case 1: return '90'
+        case 2: return '180'
+        case 3: return '270'
+        case 4: return 'flipped'
+        case 5: return 'flipped-90'
+        case 6: return 'flipped-180'
+        case 7: return 'flipped-270'
+
+def print_data(level, is_last, lines, data):
+    if is_last:
+        link = '└'
+    else:
+        link = '├'
+    padding = ' '
+
+    if level >= 0:
+        indent = level
+        buffer = f'{link:{padding}>{indent * 4}}──{data}'
+        buffer = list(buffer)
+        for line in lines:
+            if line == level:
+                continue
+            index = line * 4
+            if line > 0:
+                index -= 1
+            buffer[index] = '│'
+        buffer = ''.join(buffer)
+    else:
+        buffer = data
+
+    print(buffer)
+
+    if is_last and level in lines:
+        lines.remove(level)
+    elif not is_last and level not in lines:
+        lines.append(level)
+
+def print_properties(level, lines, properties):
+    property_list = list(properties)
+
+    print_data(level, True, lines, f'Properties: ({len(property_list)})')
+    for property in property_list:
+        is_last = property == property_list[-1]
+        print_data(level + 1, is_last, lines,
+                   f'{property} ⇒ {properties[property]}')
+
+print('Serial: {}'.format(variant[0]))
+print()
+print('Monitors:')
+monitors = variant[1]
+lines=[]
+for monitor in monitors:
+    is_last = monitor == monitors[-1]
+    spec = monitor[0]
+    modes = monitor[1]
+    properties = monitor[2]
+    print_data(0, is_last, lines, 'Monitor {}'.format(spec[0]))
+    print_data(1, False, lines, f'EDID: vendor: {spec[1]}, product: {spec[2]}, serial: {spec[3]}')
+    print_data(1, False, lines, f'Modes ({len(modes)})')
+
+    for mode in modes:
+        is_last = mode == modes[-1]
+        print_data(2, is_last, lines, f'{mode[0]}')
+        print_data(3, False, lines, f'Dimension: {mode[1]}x{mode[2]}')
+        print_data(3, False, lines, f'Refresh rate: {mode[3]}')
+        print_data(3, False, lines, f'Preferred scale: {mode[4]}')
+        print_data(3, False, lines, f'Supported scales: {mode[5]}')
+
+        mode_properties = mode[6]
+        print_properties(3, lines, mode_properties)
+
+    print_properties(1, lines, properties)
+
+print()
+print('Logical monitors:')
+logical_monitors = variant[2]
+index = 1
+for logical_monitor in logical_monitors:
+    is_last = logical_monitor == logical_monitors[-1]
+    properties = logical_monitor[2]
+    print_data(0, is_last, lines, f'Logical monitor #{index}')
+    print_data(1, False, lines,
+               f'Position: ({logical_monitor[0]}, {logical_monitor[1]})')
+    print_data(1, False, lines,
+               f'Scale: {logical_monitor[2]}')
+    print_data(1, False, lines,
+               f'Transform: {transform_to_string(logical_monitor[3])}')
+    print_data(1, False, lines,
+               f'Primary: {logical_monitor[4]}')
+    monitors = logical_monitor[5]
+    print_data(1, False, lines,
+               f'Monitors: ({len(monitors)})')
+    for monitor in monitors:
+        is_last = monitor == monitors[-1]
+        print_data(2, is_last, lines,
+                   f'{monitor[0]} ({monitor[1]}, {monitor[2]}, {monitor[3]})')
+
+    properties = logical_monitor[6]
+    print_properties(1, lines, properties)
+
+    index += 1
+
+properties = variant[3]
+print()
+print_properties(-1, lines, properties)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]