1 /*
2  * Copyright (C) 2017 Red Hat
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * 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., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 
20 #include "config.h"
21 
22 #include "backends/meta-crtc.h"
23 
24 #include "backends/meta-gpu.h"
25 
26 enum
27 {
28   PROP_0,
29 
30   PROP_ID,
31   PROP_GPU,
32   PROP_ALL_TRANSFORMS,
33 
34   N_PROPS
35 };
36 
37 static GParamSpec *obj_props[N_PROPS];
38 
39 typedef struct _MetaCrtcPrivate
40 {
41   uint64_t id;
42 
43   MetaGpu *gpu;
44 
45   MetaMonitorTransform all_transforms;
46 
47   GList *outputs;
48   MetaCrtcConfig *config;
49 } MetaCrtcPrivate;
50 
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(MetaCrtc,meta_crtc,G_TYPE_OBJECT)51 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
52 
53 uint64_t
54 meta_crtc_get_id (MetaCrtc *crtc)
55 {
56   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
57 
58   return priv->id;
59 }
60 
61 MetaGpu *
meta_crtc_get_gpu(MetaCrtc * crtc)62 meta_crtc_get_gpu (MetaCrtc *crtc)
63 {
64   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
65 
66   return priv->gpu;
67 }
68 
69 const GList *
meta_crtc_get_outputs(MetaCrtc * crtc)70 meta_crtc_get_outputs (MetaCrtc *crtc)
71 {
72   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
73 
74   return priv->outputs;
75 }
76 
77 void
meta_crtc_assign_output(MetaCrtc * crtc,MetaOutput * output)78 meta_crtc_assign_output (MetaCrtc   *crtc,
79                          MetaOutput *output)
80 {
81   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
82 
83   priv->outputs = g_list_append (priv->outputs, output);
84 }
85 
86 void
meta_crtc_unassign_output(MetaCrtc * crtc,MetaOutput * output)87 meta_crtc_unassign_output (MetaCrtc   *crtc,
88                            MetaOutput *output)
89 {
90   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
91 
92   g_return_if_fail (g_list_find (priv->outputs, output));
93 
94   priv->outputs = g_list_remove (priv->outputs, output);
95 }
96 
97 MetaMonitorTransform
meta_crtc_get_all_transforms(MetaCrtc * crtc)98 meta_crtc_get_all_transforms (MetaCrtc *crtc)
99 {
100   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
101 
102   return priv->all_transforms;
103 }
104 
105 void
meta_crtc_set_config(MetaCrtc * crtc,graphene_rect_t * layout,MetaCrtcMode * mode,MetaMonitorTransform transform)106 meta_crtc_set_config (MetaCrtc             *crtc,
107                       graphene_rect_t      *layout,
108                       MetaCrtcMode         *mode,
109                       MetaMonitorTransform  transform)
110 {
111   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
112   MetaCrtcConfig *config;
113 
114   meta_crtc_unset_config (crtc);
115 
116   config = g_new0 (MetaCrtcConfig, 1);
117   config->layout = *layout;
118   config->mode = mode;
119   config->transform = transform;
120 
121   priv->config = config;
122 }
123 
124 void
meta_crtc_unset_config(MetaCrtc * crtc)125 meta_crtc_unset_config (MetaCrtc *crtc)
126 {
127   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
128 
129   g_clear_pointer (&priv->config, g_free);
130 }
131 
132 const MetaCrtcConfig *
meta_crtc_get_config(MetaCrtc * crtc)133 meta_crtc_get_config (MetaCrtc *crtc)
134 {
135   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
136 
137   return priv->config;
138 }
139 
140 static void
meta_crtc_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)141 meta_crtc_set_property (GObject      *object,
142                         guint         prop_id,
143                         const GValue *value,
144                         GParamSpec   *pspec)
145 {
146   MetaCrtc *crtc = META_CRTC (object);
147   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
148 
149   switch (prop_id)
150     {
151     case PROP_ID:
152       priv->id = g_value_get_uint64 (value);
153       break;
154     case PROP_GPU:
155       priv->gpu = g_value_get_object (value);
156       break;
157     case PROP_ALL_TRANSFORMS:
158       priv->all_transforms = g_value_get_uint (value);
159       break;
160     default:
161       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
162     }
163 }
164 
165 static void
meta_crtc_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)166 meta_crtc_get_property (GObject    *object,
167                         guint       prop_id,
168                         GValue     *value,
169                         GParamSpec *pspec)
170 {
171   MetaCrtc *crtc = META_CRTC (object);
172   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
173 
174   switch (prop_id)
175     {
176     case PROP_ID:
177       g_value_set_uint64 (value, priv->id);
178       break;
179     case PROP_GPU:
180       g_value_set_object (value, priv->gpu);
181       break;
182     case PROP_ALL_TRANSFORMS:
183       g_value_set_uint (value, priv->all_transforms);
184       break;
185     default:
186       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187     }
188 }
189 
190 static void
meta_crtc_finalize(GObject * object)191 meta_crtc_finalize (GObject *object)
192 {
193   MetaCrtc *crtc = META_CRTC (object);
194   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
195 
196   g_clear_pointer (&priv->config, g_free);
197   g_clear_pointer (&priv->outputs, g_list_free);
198 
199   G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object);
200 }
201 
202 static void
meta_crtc_init(MetaCrtc * crtc)203 meta_crtc_init (MetaCrtc *crtc)
204 {
205   MetaCrtcPrivate *priv = meta_crtc_get_instance_private (crtc);
206 
207   priv->all_transforms = META_MONITOR_ALL_TRANSFORMS;
208 }
209 
210 static void
meta_crtc_class_init(MetaCrtcClass * klass)211 meta_crtc_class_init (MetaCrtcClass *klass)
212 {
213   GObjectClass *object_class = G_OBJECT_CLASS (klass);
214 
215   object_class->set_property = meta_crtc_set_property;
216   object_class->get_property = meta_crtc_get_property;
217   object_class->finalize = meta_crtc_finalize;
218 
219   obj_props[PROP_ID] =
220     g_param_spec_uint64 ("id",
221                          "id",
222                          "CRTC id",
223                          0, UINT64_MAX, 0,
224                          G_PARAM_READWRITE |
225                          G_PARAM_CONSTRUCT_ONLY |
226                          G_PARAM_STATIC_STRINGS);
227   obj_props[PROP_GPU] =
228     g_param_spec_object ("gpu",
229                          "gpu",
230                          "MetaGpu",
231                          META_TYPE_GPU,
232                          G_PARAM_READWRITE |
233                          G_PARAM_CONSTRUCT_ONLY |
234                          G_PARAM_STATIC_STRINGS);
235   obj_props[PROP_ALL_TRANSFORMS] =
236     g_param_spec_uint ("all-transforms",
237                        "all-transforms",
238                        "All transforms",
239                        0,
240                        META_MONITOR_ALL_TRANSFORMS,
241                        META_MONITOR_ALL_TRANSFORMS,
242                        G_PARAM_READWRITE |
243                        G_PARAM_CONSTRUCT_ONLY |
244                        G_PARAM_STATIC_STRINGS);
245   g_object_class_install_properties (object_class, N_PROPS, obj_props);
246 }
247