[mutter] get-state: Use native Gio APIs to get the current config



commit 3553af257ee0ed2cd03ebf893137ec7564814021
Author: Marco Trevisan (Treviño) <mail 3v1n0 net>
Date:   Fri Jun 3 19:00:30 2022 +0200

    get-state: Use native Gio APIs to get the current config
    
    Also provide multiple readers into a class that can be expanded to also
    configure mutter.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2448>

 tools/get-state.py | 115 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 82 insertions(+), 33 deletions(-)
---
diff --git a/tools/get-state.py b/tools/get-state.py
index 0fd166239d..e4c47069ca 100755
--- a/tools/get-state.py
+++ b/tools/get-state.py
@@ -5,12 +5,12 @@ import enum
 import subprocess
 import sys
 
-from gi.repository import GLib
+from gi.repository import GLib, Gio
 
 
-class Source(enum.Enum):
-    DBUS = 1
-    FILE = 2
+NAME = 'org.gnome.Mutter.DisplayConfig'
+INTERFACE = 'org.gnome.Mutter.DisplayConfig'
+OBJECT_PATH = '/org/gnome/Mutter/DisplayConfig'
 
 TRANSFORM_STRINGS = {
     0: 'normal',
@@ -23,6 +23,69 @@ TRANSFORM_STRINGS = {
     7: 'flipped-270',
 }
 
+
+class Source(enum.Enum):
+    DBUS = 1
+    COMMAND_LINE = 2
+    FILE = 3
+
+
+class MonitorConfig:
+    CONFIG_VARIANT_TYPE = GLib.VariantType.new(
+        '(ua((ssss)a(siiddada{sv})a{sv})a(iiduba(ssss)a{sv})a{sv})')
+
+    def get_current_state(self) -> GLib.Variant:
+        raise NotImplementedError()
+
+
+class MonitorConfigDBus(MonitorConfig):
+    def __init__(self):
+        self._proxy = Gio.DBusProxy.new_for_bus_sync(
+            bus_type=Gio.BusType.SESSION,
+            flags=Gio.DBusProxyFlags.NONE,
+            info=None,
+            name=NAME,
+            object_path=OBJECT_PATH,
+            interface_name=INTERFACE,
+            cancellable=None,
+        )
+
+    def get_current_state(self) -> GLib.Variant:
+        variant = self._proxy.call_sync(
+            method_name='GetCurrentState',
+            parameters=None,
+            flags=Gio.DBusCallFlags.NO_AUTO_START,
+            timeout_msec=-1,
+            cancellable=None
+        )
+        assert variant.get_type().equal(self.CONFIG_VARIANT_TYPE)
+        return variant
+
+
+class MonitorConfigCommandLine(MonitorConfig):
+    def get_current_state(self) -> GLib.Variant:
+        command = ('gdbus call -e '
+                   f'-d {NAME} '
+                   f'-o {OBJECT_PATH} '
+                   f'-m {INTERFACE}.GetCurrentState')
+
+        result = subprocess.run(command, shell=True,
+                                check=True, capture_output=True, text=True)
+        return GLib.variant_parse(self.CONFIG_VARIANT_TYPE, result.stdout)
+
+
+class MonitorConfigFile(MonitorConfig):
+    def __init__(self, file_path):
+        if file_path == '-':
+            self._data = sys.stdin.read()
+        else:
+            with open(file_path) as file:
+                self._data = file.read()
+
+    def get_current_state(self) -> GLib.Variant:
+        return GLib.variant_parse(self.CONFIG_VARIANT_TYPE, self._data)
+
+
 def print_data(level, is_last, lines, data):
     if is_last:
         link = '└'
@@ -61,34 +124,9 @@ def print_properties(level, lines, properties):
         print_data(level + 1, is_last, lines,
                 f'{property} ⇒ {properties[property]}')
 
-def print_current_state(args):
-    if args.file:
-        source = Source.FILE
-        path = args.file
-    else:
-        source = Source.DBUS
-
-    short = args.short
-
-    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 print_current_state(monitor_config, short):
+    variant = monitor_config.get_current_state()
 
     print('Serial: {}'.format(variant[0]))
     print()
@@ -162,10 +200,21 @@ def print_current_state(args):
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Get display state')
-    parser.add_argument('file', metavar='FILE', type=str, nargs='?',
+    parser.add_argument('--file', metavar='FILE', type=str, nargs='?',
                         help='Read the output from gdbus call instead of calling D-Bus')
+    parser.add_argument('--gdbus', action='store_true')
     parser.add_argument('--short', action='store_true')
 
     args = parser.parse_args()
 
-    print_current_state(args)
+    if args.file and args.gdbus:
+        raise argparse.ArgumentTypeError('Incompatible arguments')
+
+    if args.file:
+        monitor_config = MonitorConfigFile(args.file)
+    elif args.gdbus:
+        monitor_config = MonitorConfigCommandLine()
+    else:
+        monitor_config = MonitorConfigDBus()
+
+    print_current_state(monitor_config, short=args.short)


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