1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 
3 /*
4  * Copyright (C) 2001 Havoc Pennington
5  * Copyright (C) 2003 Rob Adams
6  * Copyright (C) 2004-2006 Elijah Newren
7  * Copyright (C) 2013 Red Hat Inc.
8  * Copyright (C) 2020 NVIDIA CORPORATION
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of the
13  * License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifndef META_MONITOR_MANAGER_PRIVATE_H
25 #define META_MONITOR_MANAGER_PRIVATE_H
26 
27 #include <cogl/cogl.h>
28 #include <graphene.h>
29 #include <libgnome-desktop/gnome-pnp-ids.h>
30 
31 #include "backends/meta-backend-private.h"
32 #include "backends/meta-cursor.h"
33 #include "backends/meta-display-config-shared.h"
34 #include "backends/meta-monitor-transform.h"
35 #include "backends/meta-viewport-info.h"
36 #include "core/util-private.h"
37 #include "meta/display.h"
38 #include "meta/meta-monitor-manager.h"
39 
40 #define META_MONITOR_MANAGER_MIN_SCREEN_WIDTH 640
41 #define META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT 480
42 
43 typedef enum _MetaMonitorManagerCapability
44 {
45   META_MONITOR_MANAGER_CAPABILITY_NONE = 0,
46   META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 0),
47   META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 1)
48 } MetaMonitorManagerCapability;
49 
50 /* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */
51 typedef enum _MetaMonitorsConfigMethod
52 {
53   META_MONITORS_CONFIG_METHOD_VERIFY = 0,
54   META_MONITORS_CONFIG_METHOD_TEMPORARY = 1,
55   META_MONITORS_CONFIG_METHOD_PERSISTENT = 2
56 } MetaMonitorsConfigMethod;
57 
58 /* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */
59 typedef enum _MetaLogicalMonitorLayoutMode
60 {
61   META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL = 1,
62   META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2
63 } MetaLogicalMonitorLayoutMode;
64 
65 /*
66  * MetaCrtcAssignment:
67  *
68  * A representation of a CRTC configuration, generated by
69  * MetaMonitorConfigManager.
70  */
71 struct _MetaCrtcAssignment
72 {
73   MetaCrtc                 *crtc;
74   MetaCrtcMode             *mode;
75   graphene_rect_t           layout;
76   MetaMonitorTransform      transform;
77   GPtrArray                *outputs;
78 };
79 
80 /*
81  * MetaOutputAssignment:
82  *
83  * A representation of a connector configuration, generated by
84  * MetaMonitorConfigManager.
85  */
86 struct _MetaOutputAssignment
87 {
88   MetaOutput  *output;
89   gboolean     is_primary;
90   gboolean     is_presentation;
91   gboolean     is_underscanning;
92 };
93 
94 /*
95  * MetaOutputCtm:
96  *
97  * A 3x3 color transform matrix in the fixed-point S31.32 sign-magnitude format
98  * used by DRM.
99  */
100 typedef struct _MetaOutputCtm
101 {
102   uint64_t matrix[9];
103 } MetaOutputCtm;
104 
105 #define META_TYPE_MONITOR_MANAGER            (meta_monitor_manager_get_type ())
106 #define META_MONITOR_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER, MetaMonitorManager))
107 #define META_MONITOR_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_MANAGER, MetaMonitorManagerClass))
108 #define META_IS_MONITOR_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER))
109 #define META_IS_MONITOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_MONITOR_MANAGER))
110 #define META_MONITOR_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_MONITOR_MANAGER, MetaMonitorManagerClass))
111 
112 typedef struct _MetaDBusDisplayConfig MetaDBusDisplayConfig;
113 
114 G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaMonitorManager, g_object_unref)
115 
116 struct _MetaMonitorManager
117 {
118   GObject parent_instance;
119 
120   MetaDBusDisplayConfig *display_config;
121 
122   MetaBackend *backend;
123 
124   /* XXX: this structure is very badly
125      packed, but I like the logical organization
126      of fields */
127 
128   gboolean in_init;
129   unsigned int serial;
130 
131   MetaLogicalMonitorLayoutMode layout_mode;
132 
133   int screen_width;
134   int screen_height;
135 
136   GList *monitors;
137 
138   GList *logical_monitors;
139   MetaLogicalMonitor *primary_logical_monitor;
140 
141   int dbus_name_id;
142 
143   int persistent_timeout_id;
144 
145   guint panel_orientation_managed : 1;
146 
147   MetaMonitorConfigManager *config_manager;
148 
149   GnomePnpIds *pnp_ids;
150 
151   MetaMonitorSwitchConfigType current_switch_config;
152 };
153 
154 /**
155  * MetaMonitorManagerClass:
156  *
157  * @read_edid: Returns the raw Extended Display Identification Data (EDID)
158  *   for the given #MetaOutput object.
159  *
160  * @ensure_initial_config: Called on setup. Makes sure an initial config
161  *   is loaded.
162  *
163  * @apply_monitors_config: Tries to apply the given config using the given
164  *   method. Throws an error if something went wrong.
165  *
166  * @set_power_save_mode: Sets the #MetaPowerSave mode (for all displays).
167  *
168  * @change_backlight: Changes the backlight intensity to the given value (in
169  *   percent).
170  *
171  * @get_crtc_gamma: Queries and returns the gamma rampQueries and returns the
172  *   gamma ramp.
173  *
174  * @set_crtc_gamma: Sets custom display LUT (look up table) for each primary
175  *   color. Each table is indexed by a value that represents input intensity,
176  *   and yields a value that represents output intensity.
177  *
178  * @tiled_monitor_added: Should be called by a #MetaMonitor when it is created.
179  *
180  * @tiled_monitor_removed: Should be called by a #MetaMonitor when it is
181  *   destroyed.
182  *
183  * @is_transform_handled: vfunc for
184  *   meta_monitor_manager_is_transform_handled().
185  * @calculate_monitor_mode_scale: vfunc for
186  *   meta_monitor_manager_calculate_monitor_mode_scale().
187  * @calculate_supported_scales: vfunc for
188  *   meta_monitor_manager_calculate_supported_scales().
189  * @get_capabilities: vfunc for meta_monitor_manager_get_capabilities().
190  * @get_max_screen_size: vfunc for meta_monitor_manager_get_max_screen_size().
191  * @get_default_layout_mode: vfunc for meta_monitor_manager_get_default_layout_mode().
192  * @set_output_ctm: vfunc for meta_monitor_manager_output_set_ctm()
193  *
194  * The base class for a #MetaMonitorManager.
195  */
196 struct _MetaMonitorManagerClass
197 {
198   GObjectClass parent_class;
199 
200   GBytes * (* read_edid) (MetaMonitorManager *manager,
201                           MetaOutput         *output);
202 
203   void (* read_current_state) (MetaMonitorManager *manager);
204 
205   void (* ensure_initial_config) (MetaMonitorManager *manager);
206 
207   gboolean (* apply_monitors_config) (MetaMonitorManager        *manager,
208                                       MetaMonitorsConfig        *config,
209                                       MetaMonitorsConfigMethod   method,
210                                       GError                   **error);
211 
212   void (* set_power_save_mode) (MetaMonitorManager *manager,
213                                 MetaPowerSave       power_save);
214 
215   void (* change_backlight) (MetaMonitorManager *manager,
216                              MetaOutput         *output,
217                              int                 backlight);
218 
219   void (* get_crtc_gamma) (MetaMonitorManager  *manager,
220                            MetaCrtc            *crtc,
221                            size_t              *size,
222                            unsigned short     **red,
223                            unsigned short     **green,
224                            unsigned short     **blue);
225   void (* set_crtc_gamma) (MetaMonitorManager *manager,
226                            MetaCrtc           *crtc,
227                            size_t              size,
228                            unsigned short     *red,
229                            unsigned short     *green,
230                            unsigned short     *blue);
231 
232   void (* tiled_monitor_added) (MetaMonitorManager *manager,
233                                 MetaMonitor        *monitor);
234 
235   void (* tiled_monitor_removed) (MetaMonitorManager *manager,
236                                   MetaMonitor        *monitor);
237 
238   gboolean (* is_transform_handled) (MetaMonitorManager   *manager,
239                                      MetaCrtc             *crtc,
240                                      MetaMonitorTransform  transform);
241 
242   float (* calculate_monitor_mode_scale) (MetaMonitorManager           *manager,
243                                           MetaLogicalMonitorLayoutMode  layout_mode,
244                                           MetaMonitor                  *monitor,
245                                           MetaMonitorMode              *monitor_mode);
246 
247   float * (* calculate_supported_scales) (MetaMonitorManager           *manager,
248                                           MetaLogicalMonitorLayoutMode  layout_mode,
249                                           MetaMonitor                  *monitor,
250                                           MetaMonitorMode              *monitor_mode,
251                                           int                          *n_supported_scales);
252 
253   MetaMonitorManagerCapability (* get_capabilities) (MetaMonitorManager *manager);
254 
255   gboolean (* get_max_screen_size) (MetaMonitorManager *manager,
256                                     int                *width,
257                                     int                *height);
258 
259   MetaLogicalMonitorLayoutMode (* get_default_layout_mode) (MetaMonitorManager *manager);
260 
261   void (* set_output_ctm) (MetaOutput          *output,
262                            const MetaOutputCtm *ctm);
263 
264   MetaVirtualMonitor * (* create_virtual_monitor) (MetaMonitorManager            *manager,
265                                                    const MetaVirtualMonitorInfo  *info,
266                                                    GError                       **error);
267 };
268 
269 META_EXPORT_TEST
270 MetaBackend *       meta_monitor_manager_get_backend (MetaMonitorManager *manager);
271 
272 void                meta_monitor_manager_setup (MetaMonitorManager *manager);
273 
274 META_EXPORT_TEST
275 void                meta_monitor_manager_rebuild (MetaMonitorManager *manager,
276                                                   MetaMonitorsConfig *config);
277 
278 META_EXPORT_TEST
279 void                meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
280                                                           MetaMonitorsConfig *config);
281 
282 META_EXPORT_TEST
283 int                 meta_monitor_manager_get_num_logical_monitors (MetaMonitorManager *manager);
284 
285 META_EXPORT_TEST
286 GList *             meta_monitor_manager_get_logical_monitors (MetaMonitorManager *manager);
287 
288 MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_number (MetaMonitorManager *manager,
289                                                                           int                 number);
290 
291 MetaLogicalMonitor *meta_monitor_manager_get_primary_logical_monitor (MetaMonitorManager *manager);
292 
293 MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager,
294                                                                  float               x,
295                                                                  float               y);
296 
297 MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager,
298                                                                         MetaRectangle      *rect);
299 
300 MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager  *manager,
301                                                                        MetaLogicalMonitor  *logical_monitor,
302                                                                        MetaDisplayDirection direction);
303 
304 MetaMonitor *       meta_monitor_manager_get_primary_monitor (MetaMonitorManager *manager);
305 
306 META_EXPORT_TEST
307 MetaMonitor *       meta_monitor_manager_get_laptop_panel (MetaMonitorManager *manager);
308 
309 MetaMonitor *       meta_monitor_manager_get_monitor_from_spec (MetaMonitorManager *manager,
310                                                                 MetaMonitorSpec    *monitor_spec);
311 
312 MetaMonitor *       meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager,
313                                                                      const char         *connector);
314 
315 META_EXPORT_TEST
316 GList *             meta_monitor_manager_get_monitors      (MetaMonitorManager *manager);
317 
318 void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *manager,
319                                                             int                *width,
320                                                             int                *height);
321 
322 MetaPowerSave       meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager);
323 
324 void                meta_monitor_manager_power_save_mode_changed (MetaMonitorManager *manager,
325                                                                   MetaPowerSave       mode);
326 
327 void                meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
328                                                                 gboolean            ok);
329 
330 gboolean           meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
331 
332 void               meta_monitor_manager_read_current_state (MetaMonitorManager *manager);
333 
334 void               meta_monitor_manager_reconfigure (MetaMonitorManager *manager);
335 
336 META_EXPORT_TEST
337 void               meta_monitor_manager_reload (MetaMonitorManager *manager);
338 
339 gboolean           meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
340                                                             MetaMonitor        *monitor,
341                                                             MetaLogicalMonitor *logical_monitor,
342                                                             gfloat              matrix[6]);
343 
344 void               meta_monitor_manager_tiled_monitor_added (MetaMonitorManager *manager,
345                                                              MetaMonitor        *monitor);
346 void               meta_monitor_manager_tiled_monitor_removed (MetaMonitorManager *manager,
347                                                                MetaMonitor        *monitor);
348 
349 gboolean           meta_monitor_manager_is_transform_handled (MetaMonitorManager  *manager,
350                                                               MetaCrtc            *crtc,
351                                                               MetaMonitorTransform transform);
352 
353 META_EXPORT_TEST
354 MetaMonitorsConfig * meta_monitor_manager_ensure_configured (MetaMonitorManager *manager);
355 
356 META_EXPORT_TEST
357 void               meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
358                                                               MetaMonitorsConfig *config);
359 
360 META_EXPORT_TEST
361 void               meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
362                                                                       MetaMonitorsConfig *config);
363 
364 META_EXPORT_TEST
365 void               meta_monitor_manager_lid_is_closed_changed (MetaMonitorManager *manager);
366 
367 gboolean           meta_monitor_manager_is_headless (MetaMonitorManager *manager);
368 
369 float              meta_monitor_manager_calculate_monitor_mode_scale (MetaMonitorManager           *manager,
370                                                                       MetaLogicalMonitorLayoutMode  layout_mode,
371                                                                       MetaMonitor                  *monitor,
372                                                                       MetaMonitorMode              *monitor_mode);
373 
374 float *            meta_monitor_manager_calculate_supported_scales (MetaMonitorManager          *,
375                                                                     MetaLogicalMonitorLayoutMode ,
376                                                                     MetaMonitor                 *,
377                                                                     MetaMonitorMode             *,
378                                                                     int                         *);
379 
380 gboolean           meta_monitor_manager_is_scale_supported (MetaMonitorManager          *manager,
381                                                             MetaLogicalMonitorLayoutMode layout_mode,
382                                                             MetaMonitor                 *monitor,
383                                                             MetaMonitorMode             *monitor_mode,
384                                                             float                        scale);
385 
386 MetaMonitorManagerCapability
387                    meta_monitor_manager_get_capabilities (MetaMonitorManager *manager);
388 
389 gboolean           meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
390                                                              int                *max_width,
391                                                              int                *max_height);
392 
393 MetaLogicalMonitorLayoutMode
394                    meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager);
395 
396 META_EXPORT_TEST
397 MetaVirtualMonitor * meta_monitor_manager_create_virtual_monitor (MetaMonitorManager            *manager,
398                                                                   const MetaVirtualMonitorInfo  *info,
399                                                                   GError                       **error);
400 
401 META_EXPORT_TEST
402 MetaMonitorConfigManager *
403                    meta_monitor_manager_get_config_manager (MetaMonitorManager *manager);
404 
405 void meta_monitor_manager_rotate_monitor (MetaMonitorManager *manager);
406 
407 void meta_monitor_manager_clear_output (MetaOutput *output);
408 void meta_monitor_manager_clear_mode (MetaCrtcMode *mode);
409 void meta_monitor_manager_clear_crtc (MetaCrtc *crtc);
410 
411 gboolean meta_monitor_has_aspect_as_size (MetaMonitor *monitor);
412 
413 char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
414                                              const char         *vendor);
415 
416 static inline MetaOutputAssignment *
meta_find_output_assignment(MetaOutputAssignment ** outputs,unsigned int n_outputs,MetaOutput * output)417 meta_find_output_assignment (MetaOutputAssignment **outputs,
418                              unsigned int           n_outputs,
419                              MetaOutput            *output)
420 {
421   unsigned int i;
422 
423   for (i = 0; i < n_outputs; i++)
424     {
425       MetaOutputAssignment *output_assignment = outputs[i];
426 
427       if (output == output_assignment->output)
428         return output_assignment;
429     }
430 
431   return NULL;
432 }
433 
434 void meta_monitor_manager_post_init (MetaMonitorManager *manager);
435 
436 MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager);
437 
438 GList * meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager);
439 
440 #endif /* META_MONITOR_MANAGER_PRIVATE_H */
441