1 /*
2 * Copyright (C) 2014 Michal Ratajsky <michal.ratajsky@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <string.h>
19 #include <glib.h>
20 #include <glib-object.h>
21
22 #include "matemixer-enums.h"
23 #include "matemixer-enum-types.h"
24 #include "matemixer-switch.h"
25 #include "matemixer-switch-private.h"
26 #include "matemixer-switch-option.h"
27
28 /**
29 * SECTION:matemixer-switch
30 * @include: libmatemixer/matemixer.h
31 */
32
33 struct _MateMixerSwitchPrivate
34 {
35 gchar *name;
36 gchar *label;
37 MateMixerSwitchOption *active;
38 };
39
40 enum {
41 PROP_0,
42 PROP_NAME,
43 PROP_LABEL,
44 PROP_ACTIVE_OPTION,
45 N_PROPERTIES
46 };
47
48 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
49
50 static void mate_mixer_switch_get_property (GObject *object,
51 guint param_id,
52 GValue *value,
53 GParamSpec *pspec);
54 static void mate_mixer_switch_set_property (GObject *object,
55 guint param_id,
56 const GValue *value,
57 GParamSpec *pspec);
58
59 static void mate_mixer_switch_dispose (GObject *object);
60 static void mate_mixer_switch_finalize (GObject *object);
61
62 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MateMixerSwitch, mate_mixer_switch, G_TYPE_OBJECT)
63
64 static MateMixerSwitchOption *mate_mixer_switch_real_get_option (MateMixerSwitch *swtch,
65 const gchar *name);
66
67 static void
mate_mixer_switch_class_init(MateMixerSwitchClass * klass)68 mate_mixer_switch_class_init (MateMixerSwitchClass *klass)
69 {
70 GObjectClass *object_class;
71
72 klass->get_option = mate_mixer_switch_real_get_option;
73
74 object_class = G_OBJECT_CLASS (klass);
75 object_class->dispose = mate_mixer_switch_dispose;
76 object_class->finalize = mate_mixer_switch_finalize;
77 object_class->get_property = mate_mixer_switch_get_property;
78 object_class->set_property = mate_mixer_switch_set_property;
79
80 properties[PROP_NAME] =
81 g_param_spec_string ("name",
82 "Name",
83 "Name of the switch",
84 NULL,
85 G_PARAM_READWRITE |
86 G_PARAM_CONSTRUCT_ONLY |
87 G_PARAM_STATIC_STRINGS);
88
89 properties[PROP_LABEL] =
90 g_param_spec_string ("label",
91 "Label",
92 "Label of the switch",
93 NULL,
94 G_PARAM_READWRITE |
95 G_PARAM_CONSTRUCT_ONLY |
96 G_PARAM_STATIC_STRINGS);
97
98 properties[PROP_ACTIVE_OPTION] =
99 g_param_spec_object ("active-option",
100 "Active option",
101 "Active option of the switch",
102 MATE_MIXER_TYPE_SWITCH_OPTION,
103 G_PARAM_READWRITE |
104 G_PARAM_CONSTRUCT_ONLY |
105 G_PARAM_STATIC_STRINGS);
106
107 g_object_class_install_properties (object_class, N_PROPERTIES, properties);
108 }
109
110 static void
mate_mixer_switch_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)111 mate_mixer_switch_get_property (GObject *object,
112 guint param_id,
113 GValue *value,
114 GParamSpec *pspec)
115 {
116 MateMixerSwitch *swtch;
117
118 swtch = MATE_MIXER_SWITCH (object);
119
120 switch (param_id) {
121 case PROP_NAME:
122 g_value_set_string (value, swtch->priv->name);
123 break;
124 case PROP_LABEL:
125 g_value_set_string (value, swtch->priv->label);
126 break;
127 case PROP_ACTIVE_OPTION:
128 g_value_set_object (value, swtch->priv->active);
129 break;
130
131 default:
132 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
133 break;
134 }
135 }
136
137 static void
mate_mixer_switch_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)138 mate_mixer_switch_set_property (GObject *object,
139 guint param_id,
140 const GValue *value,
141 GParamSpec *pspec)
142 {
143 MateMixerSwitch *swtch;
144
145 swtch = MATE_MIXER_SWITCH (object);
146
147 switch (param_id) {
148 case PROP_NAME:
149 /* Construct-only string */
150 swtch->priv->name = g_value_dup_string (value);
151 break;
152 case PROP_LABEL:
153 /* Construct-only string */
154 swtch->priv->label = g_value_dup_string (value);
155 break;
156 case PROP_ACTIVE_OPTION:
157 /* Construct-only object */
158 swtch->priv->active = g_value_dup_object (value);
159 break;
160
161 default:
162 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
163 break;
164 }
165 }
166
167 static void
mate_mixer_switch_init(MateMixerSwitch * swtch)168 mate_mixer_switch_init (MateMixerSwitch *swtch)
169 {
170 swtch->priv = mate_mixer_switch_get_instance_private (swtch);
171 }
172
173 static void
mate_mixer_switch_dispose(GObject * object)174 mate_mixer_switch_dispose (GObject *object)
175 {
176 MateMixerSwitch *swtch;
177
178 swtch = MATE_MIXER_SWITCH (object);
179
180 g_clear_object (&swtch->priv->active);
181
182 G_OBJECT_CLASS (mate_mixer_switch_parent_class)->dispose (object);
183 }
184
185 static void
mate_mixer_switch_finalize(GObject * object)186 mate_mixer_switch_finalize (GObject *object)
187 {
188 MateMixerSwitch *swtch;
189
190 swtch = MATE_MIXER_SWITCH (object);
191
192 g_free (swtch->priv->name);
193 g_free (swtch->priv->label);
194
195 G_OBJECT_CLASS (mate_mixer_switch_parent_class)->finalize (object);
196 }
197
198 /**
199 * mate_mixer_switch_get_name:
200 * @swtch: a #MateMixerSwitch
201 *
202 * Gets the name of the switch.
203 *
204 * The name serves as a unique identifier and in most cases it is not in a
205 * user-readable form.
206 *
207 * Returns: the name of the switch.
208 */
209 const gchar *
mate_mixer_switch_get_name(MateMixerSwitch * swtch)210 mate_mixer_switch_get_name (MateMixerSwitch *swtch)
211 {
212 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
213
214 return swtch->priv->name;
215 }
216
217 /**
218 * mate_mixer_switch_get_label:
219 * @swtch: a #MateMixerSwitch
220 *
221 * Gets the label of the switch.
222 *
223 * This is a potentially translated string that should be presented to users
224 * in the user interface.
225 *
226 * Returns: the label of the switch option.
227 */
228 const gchar *
mate_mixer_switch_get_label(MateMixerSwitch * swtch)229 mate_mixer_switch_get_label (MateMixerSwitch *swtch)
230 {
231 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
232
233 return swtch->priv->label;
234 }
235
236 /**
237 * mate_mixer_switch_get_option:
238 * @swtch: a #MateMixerSwitch
239 * @name: the name of an option
240 *
241 * Gets the #MateMixerSwitchOption with the given name.
242 *
243 * Returns: a #MateMixerSwitchOption or %NULL if there is no such switch option.
244 */
245 MateMixerSwitchOption *
mate_mixer_switch_get_option(MateMixerSwitch * swtch,const gchar * name)246 mate_mixer_switch_get_option (MateMixerSwitch *swtch, const gchar *name)
247 {
248 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
249 g_return_val_if_fail (name != NULL, NULL);
250
251 return MATE_MIXER_SWITCH_GET_CLASS (swtch)->get_option (swtch, name);
252 }
253
254 /**
255 * mate_mixer_switch_get_active_option:
256 * @swtch: a #MateMixerSwitch
257 *
258 * Gets the #MateMixerSwitchOption which is currently active.
259 *
260 * Returns: a #MateMixerSwitchOption.
261 */
262 MateMixerSwitchOption *
mate_mixer_switch_get_active_option(MateMixerSwitch * swtch)263 mate_mixer_switch_get_active_option (MateMixerSwitch *swtch)
264 {
265 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
266
267 return swtch->priv->active;
268 }
269
270 /**
271 * mate_mixer_switch_set_active_option:
272 * @swtch: a #MateMixerSwitch
273 * @option: the #MateMixerSwitchOption to set as the active option
274 *
275 * Changes the currently active switch option.
276 *
277 * Returns: %TRUE on success or %FALSE on failure.
278 */
279 gboolean
mate_mixer_switch_set_active_option(MateMixerSwitch * swtch,MateMixerSwitchOption * option)280 mate_mixer_switch_set_active_option (MateMixerSwitch *swtch,
281 MateMixerSwitchOption *option)
282 {
283 MateMixerSwitchClass *klass;
284
285 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), FALSE);
286 g_return_val_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option), FALSE);
287
288 klass = MATE_MIXER_SWITCH_GET_CLASS (swtch);
289 if (klass->set_active_option == NULL)
290 return FALSE;
291
292 if (swtch->priv->active != option) {
293 if (klass->set_active_option (swtch, option) == FALSE)
294 return FALSE;
295
296 _mate_mixer_switch_set_active_option (swtch, option);
297 }
298 return TRUE;
299 }
300
301 /**
302 * mate_mixer_switch_list_options:
303 * @swtch: a #MateMixerSwitch
304 *
305 * Gets the list of switch options that belong to the switch.
306 *
307 * The returned #GList is owned by the #MateMixerSwitch and may be invalidated
308 * at any time.
309 *
310 * Returns: a #GList of the switch options.
311 */
312 const GList *
mate_mixer_switch_list_options(MateMixerSwitch * swtch)313 mate_mixer_switch_list_options (MateMixerSwitch *swtch)
314 {
315 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
316
317 return MATE_MIXER_SWITCH_GET_CLASS (swtch)->list_options (swtch);
318 }
319
320 /* Protected functions */
321 void
_mate_mixer_switch_set_active_option(MateMixerSwitch * swtch,MateMixerSwitchOption * option)322 _mate_mixer_switch_set_active_option (MateMixerSwitch *swtch,
323 MateMixerSwitchOption *option)
324 {
325 g_return_if_fail (MATE_MIXER_IS_SWITCH (swtch));
326 g_return_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option));
327
328 if (swtch->priv->active == option)
329 return;
330
331 if (swtch->priv->active != NULL)
332 g_object_unref (swtch->priv->active);
333
334 swtch->priv->active = g_object_ref (option);
335
336 g_object_notify_by_pspec (G_OBJECT (swtch), properties[PROP_ACTIVE_OPTION]);
337 }
338
339 static MateMixerSwitchOption *
mate_mixer_switch_real_get_option(MateMixerSwitch * swtch,const gchar * name)340 mate_mixer_switch_real_get_option (MateMixerSwitch *swtch, const gchar *name)
341 {
342 const GList *list;
343
344 g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL);
345 g_return_val_if_fail (name != NULL, NULL);
346
347 list = mate_mixer_switch_list_options (swtch);
348 while (list != NULL) {
349 MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (list->data);
350
351 if (strcmp (name, mate_mixer_switch_option_get_name (option)) == 0)
352 return option;
353
354 list = list->next;
355 }
356 return NULL;
357 }
358