1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /*
4 * Copyright (C) 2017 Red Hat
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include "config.h"
23
24 #include "backends/meta-gpu.h"
25
26 #include "backends/meta-backend-private.h"
27 #include "backends/meta-output.h"
28
29 enum
30 {
31 PROP_0,
32
33 PROP_BACKEND,
34
35 PROP_LAST
36 };
37
38 static GParamSpec *obj_props[PROP_LAST];
39
40 typedef struct _MetaGpuPrivate
41 {
42 MetaBackend *backend;
43
44 GList *outputs;
45 GList *crtcs;
46 GList *modes;
47 } MetaGpuPrivate;
48
G_DEFINE_TYPE_WITH_PRIVATE(MetaGpu,meta_gpu,G_TYPE_OBJECT)49 G_DEFINE_TYPE_WITH_PRIVATE (MetaGpu, meta_gpu, G_TYPE_OBJECT)
50
51 gboolean
52 meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
53 {
54 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
55 GList *l;
56
57 for (l = priv->outputs; l; l = l->next)
58 {
59 MetaOutput *output = l->data;
60 const MetaOutputInfo *output_info = meta_output_get_info (output);
61
62 if (output_info->hotplug_mode_update)
63 return TRUE;
64 }
65
66 return FALSE;
67 }
68
69 gboolean
meta_gpu_read_current(MetaGpu * gpu,GError ** error)70 meta_gpu_read_current (MetaGpu *gpu,
71 GError **error)
72 {
73 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
74 gboolean ret;
75 GList *old_outputs;
76 GList *old_crtcs;
77 GList *old_modes;
78
79 /* TODO: Get rid of this when objects incref:s what they need instead */
80 old_outputs = priv->outputs;
81 old_crtcs = priv->crtcs;
82 old_modes = priv->modes;
83
84 ret = META_GPU_GET_CLASS (gpu)->read_current (gpu, error);
85
86 g_list_free_full (old_outputs, g_object_unref);
87 g_list_free_full (old_modes, g_object_unref);
88 g_list_free_full (old_crtcs, g_object_unref);
89
90 return ret;
91 }
92
93 MetaBackend *
meta_gpu_get_backend(MetaGpu * gpu)94 meta_gpu_get_backend (MetaGpu *gpu)
95 {
96 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
97
98 return priv->backend;
99 }
100
101 GList *
meta_gpu_get_outputs(MetaGpu * gpu)102 meta_gpu_get_outputs (MetaGpu *gpu)
103 {
104 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
105
106 return priv->outputs;
107 }
108
109 GList *
meta_gpu_get_crtcs(MetaGpu * gpu)110 meta_gpu_get_crtcs (MetaGpu *gpu)
111 {
112 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
113
114 return priv->crtcs;
115 }
116
117 GList *
meta_gpu_get_modes(MetaGpu * gpu)118 meta_gpu_get_modes (MetaGpu *gpu)
119 {
120 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
121
122 return priv->modes;
123 }
124
125 void
meta_gpu_take_outputs(MetaGpu * gpu,GList * outputs)126 meta_gpu_take_outputs (MetaGpu *gpu,
127 GList *outputs)
128 {
129 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
130
131 priv->outputs = outputs;
132 }
133
134 void
meta_gpu_take_crtcs(MetaGpu * gpu,GList * crtcs)135 meta_gpu_take_crtcs (MetaGpu *gpu,
136 GList *crtcs)
137 {
138 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
139
140 priv->crtcs = crtcs;
141 }
142
143 void
meta_gpu_take_modes(MetaGpu * gpu,GList * modes)144 meta_gpu_take_modes (MetaGpu *gpu,
145 GList *modes)
146 {
147 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
148
149 priv->modes = modes;
150 }
151
152 static void
meta_gpu_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)153 meta_gpu_set_property (GObject *object,
154 guint prop_id,
155 const GValue *value,
156 GParamSpec *pspec)
157 {
158 MetaGpu *gpu = META_GPU (object);
159 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
160
161 switch (prop_id)
162 {
163 case PROP_BACKEND:
164 priv->backend = g_value_get_object (value);
165 break;
166 default:
167 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
168 }
169 }
170
171 static void
meta_gpu_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)172 meta_gpu_get_property (GObject *object,
173 guint prop_id,
174 GValue *value,
175 GParamSpec *pspec)
176 {
177 MetaGpu *gpu = META_GPU (object);
178 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
179
180 switch (prop_id)
181 {
182 case PROP_BACKEND:
183 g_value_set_object (value, priv->backend);
184 break;
185 default:
186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187 }
188 }
189
190 static void
meta_gpu_finalize(GObject * object)191 meta_gpu_finalize (GObject *object)
192 {
193 MetaGpu *gpu = META_GPU (object);
194 MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
195
196 g_list_free_full (priv->outputs, g_object_unref);
197 g_list_free_full (priv->modes, g_object_unref);
198 g_list_free_full (priv->crtcs, g_object_unref);
199
200 G_OBJECT_CLASS (meta_gpu_parent_class)->finalize (object);
201 }
202
203 static void
meta_gpu_init(MetaGpu * gpu)204 meta_gpu_init (MetaGpu *gpu)
205 {
206 }
207
208 static void
meta_gpu_class_init(MetaGpuClass * klass)209 meta_gpu_class_init (MetaGpuClass *klass)
210 {
211 GObjectClass *object_class = G_OBJECT_CLASS (klass);
212
213 object_class->set_property = meta_gpu_set_property;
214 object_class->get_property = meta_gpu_get_property;
215 object_class->finalize = meta_gpu_finalize;
216
217 obj_props[PROP_BACKEND] =
218 g_param_spec_object ("backend",
219 "backend",
220 "MetaBackend",
221 META_TYPE_BACKEND,
222 G_PARAM_READWRITE |
223 G_PARAM_CONSTRUCT_ONLY |
224 G_PARAM_STATIC_STRINGS);
225 g_object_class_install_properties (object_class, PROP_LAST, obj_props);
226 }
227