[mutter] monitor: Add support to privacy screen



commit f2316720848df069d649b3b6d904d361b1f3e171
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon Mar 22 01:02:19 2021 +0100

    monitor: Add support to privacy screen
    
    Some monitors support hardware features to enable the privacy screen
    mode that allows users to toggle (via software or hardware button) a
    state in which the display may be harder to see to people not sitting
    in front of it.
    
    Expose then this capability to the monitor level so that we can get its
    state and set it.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1952>

 src/backends/meta-monitor.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/backends/meta-monitor.h |  6 ++++++
 src/backends/meta-output.c  | 44 ++++++++++++++++++++++++++++++++++++++++++++
 src/backends/meta-output.h  | 19 +++++++++++++++++++
 4 files changed, 112 insertions(+)
---
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 54a228e835..46cb05a666 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -2021,3 +2021,46 @@ meta_monitor_set_logical_monitor (MetaMonitor        *monitor,
 
   priv->logical_monitor = logical_monitor;
 }
+
+static MetaOutput *
+maybe_get_privacy_screen_output (MetaMonitor *monitor)
+{
+  MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+  if (priv->outputs && priv->outputs->next)
+      return NULL;
+
+  return meta_monitor_get_main_output (monitor);
+}
+
+MetaPrivacyScreenState
+meta_monitor_get_privacy_screen_state (MetaMonitor *monitor)
+{
+  MetaOutput *output;
+
+  output = maybe_get_privacy_screen_output (monitor);
+
+  if (!output)
+    return META_PRIVACY_SCREEN_UNAVAILABLE;
+
+  return meta_output_get_privacy_screen_state (output);
+}
+
+gboolean
+meta_monitor_set_privacy_screen_enabled (MetaMonitor  *monitor,
+                                         gboolean      enabled,
+                                         GError      **error)
+{
+  MetaOutput *output;
+
+  output = maybe_get_privacy_screen_output (monitor);
+
+  if (!output)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           "The privacy screen is not supported by this output");
+      return FALSE;
+    }
+
+  return meta_output_set_privacy_screen_enabled (output, enabled, error);
+}
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 4b3a527e30..066caa7f46 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -280,4 +280,10 @@ const char * meta_monitor_get_display_name (MetaMonitor *monitor);
 void meta_monitor_set_logical_monitor (MetaMonitor        *monitor,
                                        MetaLogicalMonitor *logical_monitor);
 
+MetaPrivacyScreenState meta_monitor_get_privacy_screen_state (MetaMonitor *monitor);
+
+gboolean meta_monitor_set_privacy_screen_enabled (MetaMonitor  *monitor,
+                                                  gboolean      enabled,
+                                                  GError      **error);
+
 #endif /* META_MONITOR_H */
diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c
index 36d8cc2273..f198752f7a 100644
--- a/src/backends/meta-output.c
+++ b/src/backends/meta-output.c
@@ -419,6 +419,50 @@ meta_output_finalize (GObject *object)
   G_OBJECT_CLASS (meta_output_parent_class)->finalize (object);
 }
 
+MetaPrivacyScreenState
+meta_output_get_privacy_screen_state (MetaOutput *output)
+{
+  MetaOutputClass *output_class = META_OUTPUT_GET_CLASS (output);
+
+  if (!output_class->get_privacy_screen_state)
+    return META_PRIVACY_SCREEN_UNAVAILABLE;
+
+  return output_class->get_privacy_screen_state (output);
+}
+
+gboolean
+meta_output_set_privacy_screen_enabled (MetaOutput  *output,
+                                        gboolean     enabled,
+                                        GError     **error)
+{
+  MetaOutputClass *output_class = META_OUTPUT_GET_CLASS (output);
+  MetaPrivacyScreenState state;
+
+  state = meta_output_get_privacy_screen_state (output);
+
+  if (state == META_PRIVACY_SCREEN_UNAVAILABLE)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           "The privacy screen is not supported by this output");
+      return FALSE;
+    }
+
+  g_assert (output_class->set_privacy_screen_enabled != NULL);
+
+  if (state & META_PRIVACY_SCREEN_LOCKED)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                           "The privacy screen is locked at hardware level, "
+                           "impossible to set it");
+      return FALSE;
+    }
+
+  if (!!(state & META_PRIVACY_SCREEN_ENABLED) == enabled)
+    return TRUE;
+
+  return output_class->set_privacy_screen_enabled (output, enabled, error);
+}
+
 static void
 meta_output_init (MetaOutput *output)
 {
diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h
index cc055881c3..10ed947b9c 100644
--- a/src/backends/meta-output.h
+++ b/src/backends/meta-output.h
@@ -64,6 +64,14 @@ typedef enum
   META_CONNECTOR_TYPE_META = 1000,
 } MetaConnectorType;
 
+typedef enum
+{
+  META_PRIVACY_SCREEN_UNAVAILABLE = 0,
+  META_PRIVACY_SCREEN_ENABLED = 1 << 0,
+  META_PRIVACY_SCREEN_DISABLED = 1 << 1,
+  META_PRIVACY_SCREEN_LOCKED = 1 << 2,
+} MetaPrivacyScreenState;
+
 typedef struct _MetaOutputInfo
 {
   grefcount ref_count;
@@ -138,6 +146,11 @@ G_DECLARE_DERIVABLE_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
 struct _MetaOutputClass
 {
   GObjectClass parent_class;
+
+  MetaPrivacyScreenState (* get_privacy_screen_state) (MetaOutput *output);
+  gboolean (* set_privacy_screen_enabled) (MetaOutput  *output,
+                                           gboolean     enabled,
+                                           GError     **error);
 };
 
 META_EXPORT_TEST
@@ -170,6 +183,12 @@ void meta_output_set_backlight (MetaOutput *output,
 
 int meta_output_get_backlight (MetaOutput *output);
 
+MetaPrivacyScreenState meta_output_get_privacy_screen_state (MetaOutput *output);
+
+gboolean meta_output_set_privacy_screen_enabled (MetaOutput  *output,
+                                                 gboolean     enabled,
+                                                 GError     **error);
+
 void meta_output_add_possible_clone (MetaOutput *output,
                                      MetaOutput *possible_clone);
 


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