1 /*
2  * Copyright (C) 2016  Red Hat, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <gio/gio.h>
21 #include <math.h>
22 #include "cc-display-config.h"
23 
24 static const double known_diagonals[] = {
25   12.1,
26   13.3,
27   15.6
28 };
29 
30 static char *
diagonal_to_str(double d)31 diagonal_to_str (double d)
32 {
33   int i;
34 
35   for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++)
36     {
37       double delta;
38 
39       delta = fabs(known_diagonals[i] - d);
40       if (delta < 0.1)
41           return g_strdup_printf ("%0.1lf\"", known_diagonals[i]);
42     }
43 
44   return g_strdup_printf ("%d\"", (int) (d + 0.5));
45 }
46 
47 static char *
make_display_size_string(int width_mm,int height_mm)48 make_display_size_string (int width_mm,
49                           int height_mm)
50 {
51   char *inches = NULL;
52 
53   if (width_mm > 0 && height_mm > 0)
54     {
55       double d = sqrt (width_mm * width_mm + height_mm * height_mm);
56 
57       inches = diagonal_to_str (d / 25.4);
58     }
59 
60   return inches;
61 }
62 
63 static char *
make_output_ui_name(CcDisplayMonitor * output)64 make_output_ui_name (CcDisplayMonitor *output)
65 {
66   int width_mm, height_mm;
67   g_autofree char *size = NULL;
68 
69   cc_display_monitor_get_physical_size (output, &width_mm, &height_mm);
70   size = make_display_size_string (width_mm, height_mm);
71   if (size)
72     return g_strdup_printf ("%s (%s)", cc_display_monitor_get_display_name (output), size);
73   else
74     return g_strdup_printf ("%s", cc_display_monitor_get_display_name (output));
75 }
76 
77 
78 
G_DEFINE_TYPE(CcDisplayMode,cc_display_mode,G_TYPE_OBJECT)79 G_DEFINE_TYPE (CcDisplayMode,
80                cc_display_mode,
81                G_TYPE_OBJECT)
82 
83 static void
84 cc_display_mode_init (CcDisplayMode *self)
85 {
86 }
87 
88 static void
cc_display_mode_class_init(CcDisplayModeClass * klass)89 cc_display_mode_class_init (CcDisplayModeClass *klass)
90 {
91 }
92 
93 void
cc_display_mode_get_resolution(CcDisplayMode * self,int * w,int * h)94 cc_display_mode_get_resolution (CcDisplayMode *self, int *w, int *h)
95 {
96   return CC_DISPLAY_MODE_GET_CLASS (self)->get_resolution (self, w, h);
97 }
98 
99 GArray *
cc_display_mode_get_supported_scales(CcDisplayMode * self)100 cc_display_mode_get_supported_scales (CcDisplayMode *self)
101 {
102   return CC_DISPLAY_MODE_GET_CLASS (self)->get_supported_scales (self);
103 }
104 
105 double
cc_display_mode_get_preferred_scale(CcDisplayMode * self)106 cc_display_mode_get_preferred_scale (CcDisplayMode *self)
107 {
108   return CC_DISPLAY_MODE_GET_CLASS (self)->get_preferred_scale (self);
109 }
110 
111 gboolean
cc_display_mode_is_interlaced(CcDisplayMode * self)112 cc_display_mode_is_interlaced (CcDisplayMode *self)
113 {
114   return CC_DISPLAY_MODE_GET_CLASS (self)->is_interlaced (self);
115 }
116 
117 int
cc_display_mode_get_freq(CcDisplayMode * self)118 cc_display_mode_get_freq (CcDisplayMode *self)
119 {
120   return CC_DISPLAY_MODE_GET_CLASS (self)->get_freq (self);
121 }
122 
123 double
cc_display_mode_get_freq_f(CcDisplayMode * self)124 cc_display_mode_get_freq_f (CcDisplayMode *self)
125 {
126   return CC_DISPLAY_MODE_GET_CLASS (self)->get_freq_f (self);
127 }
128 
129 
130 struct _CcDisplayMonitorPrivate {
131   int ui_number;
132   gchar *ui_name;
133   gchar *ui_number_name;
134   gboolean is_usable;
135 };
136 typedef struct _CcDisplayMonitorPrivate CcDisplayMonitorPrivate;
137 
G_DEFINE_TYPE_WITH_PRIVATE(CcDisplayMonitor,cc_display_monitor,G_TYPE_OBJECT)138 G_DEFINE_TYPE_WITH_PRIVATE (CcDisplayMonitor,
139                             cc_display_monitor,
140                             G_TYPE_OBJECT)
141 
142 static void
143 cc_display_monitor_init (CcDisplayMonitor *self)
144 {
145   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
146 
147   priv->ui_number = 0;
148   priv->ui_name = NULL;
149   priv->ui_number_name = NULL;
150   priv->is_usable = TRUE;
151 }
152 
153 static void
cc_display_monitor_finalize(GObject * object)154 cc_display_monitor_finalize (GObject *object)
155 {
156   CcDisplayMonitor *self = CC_DISPLAY_MONITOR (object);
157   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
158 
159   g_clear_pointer (&priv->ui_name, g_free);
160   g_clear_pointer (&priv->ui_number_name, g_free);
161 
162   G_OBJECT_CLASS (cc_display_monitor_parent_class)->finalize (object);
163 }
164 
165 static void
cc_display_monitor_class_init(CcDisplayMonitorClass * klass)166 cc_display_monitor_class_init (CcDisplayMonitorClass *klass)
167 {
168   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
169 
170   gobject_class->finalize = cc_display_monitor_finalize;
171 
172   g_signal_new ("rotation",
173                 CC_TYPE_DISPLAY_MONITOR,
174                 G_SIGNAL_RUN_LAST,
175                 0, NULL, NULL, NULL,
176                 G_TYPE_NONE, 0);
177   g_signal_new ("mode",
178                 CC_TYPE_DISPLAY_MONITOR,
179                 G_SIGNAL_RUN_LAST,
180                 0, NULL, NULL, NULL,
181                 G_TYPE_NONE, 0);
182   g_signal_new ("primary",
183                 CC_TYPE_DISPLAY_MONITOR,
184                 G_SIGNAL_RUN_LAST,
185                 0, NULL, NULL, NULL,
186                 G_TYPE_NONE, 0);
187   g_signal_new ("active",
188                 CC_TYPE_DISPLAY_MONITOR,
189                 G_SIGNAL_RUN_LAST,
190                 0, NULL, NULL, NULL,
191                 G_TYPE_NONE, 0);
192   g_signal_new ("scale",
193                 CC_TYPE_DISPLAY_MONITOR,
194                 G_SIGNAL_RUN_LAST,
195                 0, NULL, NULL, NULL,
196                 G_TYPE_NONE, 0);
197   g_signal_new ("position-changed",
198                 CC_TYPE_DISPLAY_MONITOR,
199                 G_SIGNAL_RUN_LAST,
200                 0, NULL, NULL, NULL,
201                 G_TYPE_NONE, 0);
202   g_signal_new ("is-usable",
203                 CC_TYPE_DISPLAY_MONITOR,
204                 G_SIGNAL_RUN_LAST,
205                 0, NULL, NULL, NULL,
206                 G_TYPE_NONE, 0);
207 }
208 
209 const char *
cc_display_monitor_get_display_name(CcDisplayMonitor * self)210 cc_display_monitor_get_display_name (CcDisplayMonitor *self)
211 {
212   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_display_name (self);
213 }
214 
215 const char *
cc_display_monitor_get_connector_name(CcDisplayMonitor * self)216 cc_display_monitor_get_connector_name (CcDisplayMonitor *self)
217 {
218   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_connector_name (self);
219 }
220 
221 gboolean
cc_display_monitor_is_builtin(CcDisplayMonitor * self)222 cc_display_monitor_is_builtin (CcDisplayMonitor *self)
223 {
224   return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_builtin (self);
225 }
226 
227 gboolean
cc_display_monitor_is_primary(CcDisplayMonitor * self)228 cc_display_monitor_is_primary (CcDisplayMonitor *self)
229 {
230   return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_primary (self);
231 }
232 
233 void
cc_display_monitor_set_primary(CcDisplayMonitor * self,gboolean primary)234 cc_display_monitor_set_primary (CcDisplayMonitor *self, gboolean primary)
235 {
236   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_primary (self, primary);
237 }
238 
239 gboolean
cc_display_monitor_is_active(CcDisplayMonitor * self)240 cc_display_monitor_is_active (CcDisplayMonitor *self)
241 {
242   return CC_DISPLAY_MONITOR_GET_CLASS (self)->is_active (self);
243 }
244 
245 void
cc_display_monitor_set_active(CcDisplayMonitor * self,gboolean active)246 cc_display_monitor_set_active (CcDisplayMonitor *self, gboolean active)
247 {
248   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_active (self, active);
249 }
250 
251 CcDisplayRotation
cc_display_monitor_get_rotation(CcDisplayMonitor * self)252 cc_display_monitor_get_rotation (CcDisplayMonitor *self)
253 {
254   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_rotation (self);
255 }
256 
257 void
cc_display_monitor_set_rotation(CcDisplayMonitor * self,CcDisplayRotation rotation)258 cc_display_monitor_set_rotation (CcDisplayMonitor *self,
259                                  CcDisplayRotation rotation)
260 {
261   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_rotation (self, rotation);
262 }
263 
264 gboolean
cc_display_monitor_supports_rotation(CcDisplayMonitor * self,CcDisplayRotation r)265 cc_display_monitor_supports_rotation (CcDisplayMonitor *self, CcDisplayRotation r)
266 {
267   return CC_DISPLAY_MONITOR_GET_CLASS (self)->supports_rotation (self, r);
268 }
269 
270 void
cc_display_monitor_get_physical_size(CcDisplayMonitor * self,int * w,int * h)271 cc_display_monitor_get_physical_size (CcDisplayMonitor *self, int *w, int *h)
272 {
273   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_physical_size (self, w, h);
274 }
275 
276 void
cc_display_monitor_get_geometry(CcDisplayMonitor * self,int * x,int * y,int * w,int * h)277 cc_display_monitor_get_geometry (CcDisplayMonitor *self, int *x, int *y, int *w, int *h)
278 {
279   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_geometry (self, x, y, w, h);
280 }
281 
282 CcDisplayMode *
cc_display_monitor_get_mode(CcDisplayMonitor * self)283 cc_display_monitor_get_mode (CcDisplayMonitor *self)
284 {
285   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_mode (self);
286 }
287 
288 CcDisplayMode *
cc_display_monitor_get_preferred_mode(CcDisplayMonitor * self)289 cc_display_monitor_get_preferred_mode (CcDisplayMonitor *self)
290 {
291   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_preferred_mode (self);
292 }
293 
294 guint32
cc_display_monitor_get_id(CcDisplayMonitor * self)295 cc_display_monitor_get_id (CcDisplayMonitor *self)
296 {
297   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_id (self);
298 }
299 
300 GList *
cc_display_monitor_get_modes(CcDisplayMonitor * self)301 cc_display_monitor_get_modes (CcDisplayMonitor *self)
302 {
303   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_modes (self);
304 }
305 
306 gboolean
cc_display_monitor_supports_underscanning(CcDisplayMonitor * self)307 cc_display_monitor_supports_underscanning (CcDisplayMonitor *self)
308 {
309   return CC_DISPLAY_MONITOR_GET_CLASS (self)->supports_underscanning (self);
310 }
311 
312 gboolean
cc_display_monitor_get_underscanning(CcDisplayMonitor * self)313 cc_display_monitor_get_underscanning (CcDisplayMonitor *self)
314 {
315   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_underscanning (self);
316 }
317 
318 void
cc_display_monitor_set_underscanning(CcDisplayMonitor * self,gboolean underscanning)319 cc_display_monitor_set_underscanning (CcDisplayMonitor *self,
320                                       gboolean underscanning)
321 {
322   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_underscanning (self, underscanning);
323 }
324 
325 void
cc_display_monitor_set_mode(CcDisplayMonitor * self,CcDisplayMode * m)326 cc_display_monitor_set_mode (CcDisplayMonitor *self, CcDisplayMode *m)
327 {
328   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_mode (self, m);
329 }
330 
331 void
cc_display_monitor_set_position(CcDisplayMonitor * self,int x,int y)332 cc_display_monitor_set_position (CcDisplayMonitor *self, int x, int y)
333 {
334   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_position (self, x, y);
335 }
336 
337 double
cc_display_monitor_get_scale(CcDisplayMonitor * self)338 cc_display_monitor_get_scale (CcDisplayMonitor *self)
339 {
340   return CC_DISPLAY_MONITOR_GET_CLASS (self)->get_scale (self);
341 }
342 
343 void
cc_display_monitor_set_scale(CcDisplayMonitor * self,double s)344 cc_display_monitor_set_scale (CcDisplayMonitor *self, double s)
345 {
346   return CC_DISPLAY_MONITOR_GET_CLASS (self)->set_scale (self, s);
347 }
348 
349 gboolean
cc_display_monitor_is_useful(CcDisplayMonitor * self)350 cc_display_monitor_is_useful (CcDisplayMonitor *self)
351 {
352   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
353 
354   return priv->is_usable &&
355          cc_display_monitor_is_active (self);
356 }
357 
358 gboolean
cc_display_monitor_is_usable(CcDisplayMonitor * self)359 cc_display_monitor_is_usable (CcDisplayMonitor *self)
360 {
361   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
362 
363   return priv->is_usable;
364 }
365 
366 void
cc_display_monitor_set_usable(CcDisplayMonitor * self,gboolean is_usable)367 cc_display_monitor_set_usable (CcDisplayMonitor *self, gboolean is_usable)
368 {
369   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
370 
371   priv->is_usable = is_usable;
372 
373   g_signal_emit_by_name (self, "is-usable");
374 }
375 
376 gint
cc_display_monitor_get_ui_number(CcDisplayMonitor * self)377 cc_display_monitor_get_ui_number (CcDisplayMonitor *self)
378 {
379   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
380 
381   return priv->ui_number;
382 }
383 
384 const char *
cc_display_monitor_get_ui_name(CcDisplayMonitor * self)385 cc_display_monitor_get_ui_name (CcDisplayMonitor *self)
386 {
387   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
388 
389   return priv->ui_name;
390 }
391 
392 const char *
cc_display_monitor_get_ui_number_name(CcDisplayMonitor * self)393 cc_display_monitor_get_ui_number_name (CcDisplayMonitor *self)
394 {
395   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
396 
397   return priv->ui_number_name;
398 }
399 
400 char *
cc_display_monitor_dup_ui_number_name(CcDisplayMonitor * self)401 cc_display_monitor_dup_ui_number_name (CcDisplayMonitor *self)
402 {
403   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
404 
405   return g_strdup (priv->ui_number_name);
406 }
407 
408 static void
cc_display_monitor_set_ui_info(CcDisplayMonitor * self,gint ui_number,gchar * ui_name)409 cc_display_monitor_set_ui_info (CcDisplayMonitor *self, gint ui_number, gchar *ui_name)
410 {
411 
412   CcDisplayMonitorPrivate *priv = cc_display_monitor_get_instance_private (self);
413 
414   priv->ui_number = ui_number;
415   g_free (priv->ui_name);
416   priv->ui_name = ui_name;
417   priv->ui_number_name = g_strdup_printf ("%d\u2003%s", ui_number, ui_name);
418 }
419 
420 struct _CcDisplayConfigPrivate {
421   GList *ui_sorted_monitors;
422 };
423 typedef struct _CcDisplayConfigPrivate CcDisplayConfigPrivate;
424 
G_DEFINE_TYPE_WITH_PRIVATE(CcDisplayConfig,cc_display_config,G_TYPE_OBJECT)425 G_DEFINE_TYPE_WITH_PRIVATE (CcDisplayConfig,
426                             cc_display_config,
427                             G_TYPE_OBJECT)
428 
429 static void
430 cc_display_config_init (CcDisplayConfig *self)
431 {
432   CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self);
433 
434   priv->ui_sorted_monitors = NULL;
435 }
436 
437 static void
cc_display_config_constructed(GObject * object)438 cc_display_config_constructed (GObject *object)
439 {
440   CcDisplayConfig *self = CC_DISPLAY_CONFIG (object);
441   CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self);
442   GList *monitors = cc_display_config_get_monitors (self);
443   GList *item;
444   gint ui_number = 1;
445 
446   for (item = monitors; item != NULL; item = item->next)
447     {
448       CcDisplayMonitor *monitor = item->data;
449 
450       if (cc_display_monitor_is_builtin (monitor))
451         priv->ui_sorted_monitors = g_list_prepend (priv->ui_sorted_monitors, monitor);
452       else
453         priv->ui_sorted_monitors = g_list_append (priv->ui_sorted_monitors, monitor);
454     }
455 
456   for (item = priv->ui_sorted_monitors; item != NULL; item = item->next)
457     {
458       CcDisplayMonitor *monitor = item->data;
459       char *ui_name;
460       ui_name = make_output_ui_name (monitor);
461 
462       cc_display_monitor_set_ui_info (monitor, ui_number, ui_name);
463 
464       ui_number += 1;
465     }
466 }
467 
468 static void
cc_display_config_finalize(GObject * object)469 cc_display_config_finalize (GObject *object)
470 {
471   CcDisplayConfig *self = CC_DISPLAY_CONFIG (object);
472   CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self);
473 
474   g_list_free (priv->ui_sorted_monitors);
475 
476   G_OBJECT_CLASS (cc_display_config_parent_class)->finalize (object);
477 }
478 
479 static void
cc_display_config_class_init(CcDisplayConfigClass * klass)480 cc_display_config_class_init (CcDisplayConfigClass *klass)
481 {
482   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
483 
484   g_signal_new ("primary",
485                 CC_TYPE_DISPLAY_CONFIG,
486                 G_SIGNAL_RUN_LAST,
487                 0, NULL, NULL, NULL,
488                 G_TYPE_NONE, 0);
489   g_signal_new ("panel-orientation-managed",
490                 CC_TYPE_DISPLAY_CONFIG,
491                 G_SIGNAL_RUN_LAST,
492                 0, NULL, NULL, NULL,
493                 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
494 
495   gobject_class->constructed = cc_display_config_constructed;
496   gobject_class->finalize = cc_display_config_finalize;
497 }
498 
499 GList *
cc_display_config_get_monitors(CcDisplayConfig * self)500 cc_display_config_get_monitors (CcDisplayConfig *self)
501 {
502   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL);
503   return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_monitors (self);
504 }
505 
506 GList *
cc_display_config_get_ui_sorted_monitors(CcDisplayConfig * self)507 cc_display_config_get_ui_sorted_monitors (CcDisplayConfig *self)
508 {
509   CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self);
510 
511   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL);
512   return priv->ui_sorted_monitors;
513 }
514 
515 int
cc_display_config_count_useful_monitors(CcDisplayConfig * self)516 cc_display_config_count_useful_monitors (CcDisplayConfig *self)
517 {
518   CcDisplayConfigPrivate *priv = cc_display_config_get_instance_private (self);
519   GList *outputs, *l;
520   guint count = 0;
521 
522   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), 0);
523 
524   outputs = priv->ui_sorted_monitors;
525   for (l = outputs; l != NULL; l = l->next)
526     {
527       CcDisplayMonitor *output = l->data;
528       if (!cc_display_monitor_is_useful (output))
529         continue;
530       else
531         count++;
532     }
533   return count;
534 
535 }
536 
537 gboolean
cc_display_config_is_applicable(CcDisplayConfig * self)538 cc_display_config_is_applicable (CcDisplayConfig *self)
539 {
540   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE);
541   return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_applicable (self);
542 }
543 
544 void
cc_display_config_set_mode_on_all_outputs(CcDisplayConfig * config,CcDisplayMode * mode)545 cc_display_config_set_mode_on_all_outputs (CcDisplayConfig *config,
546                                            CcDisplayMode   *mode)
547 {
548   GList *outputs, *l;
549 
550   g_return_if_fail (CC_IS_DISPLAY_CONFIG (config));
551 
552   outputs = cc_display_config_get_monitors (config);
553   for (l = outputs; l; l = l->next)
554     {
555       CcDisplayMonitor *output = l->data;
556       cc_display_monitor_set_mode (output, mode);
557       cc_display_monitor_set_position (output, 0, 0);
558     }
559 }
560 
561 gboolean
cc_display_config_equal(CcDisplayConfig * self,CcDisplayConfig * other)562 cc_display_config_equal (CcDisplayConfig *self,
563                          CcDisplayConfig *other)
564 {
565   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE);
566   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (other), FALSE);
567 
568   return CC_DISPLAY_CONFIG_GET_CLASS (self)->equal (self, other);
569 }
570 
571 gboolean
cc_display_config_apply(CcDisplayConfig * self,GError ** error)572 cc_display_config_apply (CcDisplayConfig *self,
573                          GError **error)
574 {
575   if (!CC_IS_DISPLAY_CONFIG (self))
576     {
577       g_warning ("Cannot apply invalid configuration");
578       g_set_error (error,
579                    G_IO_ERROR,
580                    G_IO_ERROR_FAILED,
581                    "Cannot apply invalid configuration");
582       return FALSE;
583     }
584 
585   return CC_DISPLAY_CONFIG_GET_CLASS (self)->apply (self, error);
586 }
587 
588 gboolean
cc_display_config_is_cloning(CcDisplayConfig * self)589 cc_display_config_is_cloning (CcDisplayConfig *self)
590 {
591   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE);
592   return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_cloning (self);
593 }
594 
595 void
cc_display_config_set_cloning(CcDisplayConfig * self,gboolean clone)596 cc_display_config_set_cloning (CcDisplayConfig *self,
597                                gboolean clone)
598 {
599   g_return_if_fail (CC_IS_DISPLAY_CONFIG (self));
600   return CC_DISPLAY_CONFIG_GET_CLASS (self)->set_cloning (self, clone);
601 }
602 
603 GList *
cc_display_config_get_cloning_modes(CcDisplayConfig * self)604 cc_display_config_get_cloning_modes (CcDisplayConfig *self)
605 {
606   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), NULL);
607   return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_cloning_modes (self);
608 }
609 
610 gboolean
cc_display_config_is_layout_logical(CcDisplayConfig * self)611 cc_display_config_is_layout_logical (CcDisplayConfig *self)
612 {
613   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE);
614   return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_layout_logical (self);
615 }
616 
617 void
cc_display_config_set_minimum_size(CcDisplayConfig * self,int width,int height)618 cc_display_config_set_minimum_size (CcDisplayConfig *self,
619                                     int              width,
620                                     int              height)
621 {
622   g_return_if_fail (CC_IS_DISPLAY_CONFIG (self));
623   CC_DISPLAY_CONFIG_GET_CLASS (self)->set_minimum_size (self, width, height);
624 }
625 
626 gboolean
cc_display_config_is_scaled_mode_valid(CcDisplayConfig * self,CcDisplayMode * mode,double scale)627 cc_display_config_is_scaled_mode_valid (CcDisplayConfig *self,
628                                         CcDisplayMode   *mode,
629                                         double           scale)
630 {
631   g_return_val_if_fail (CC_IS_DISPLAY_CONFIG (self), FALSE);
632   g_return_val_if_fail (CC_IS_DISPLAY_MODE (mode), FALSE);
633   return CC_DISPLAY_CONFIG_GET_CLASS (self)->is_scaled_mode_valid (self, mode, scale);
634 }
635 
636 gboolean
cc_display_config_get_panel_orientation_managed(CcDisplayConfig * self)637 cc_display_config_get_panel_orientation_managed (CcDisplayConfig *self)
638 {
639   return CC_DISPLAY_CONFIG_GET_CLASS (self)->get_panel_orientation_managed (self);
640 }
641