tizen: kdbus: make i explicitly positive in make_single_header_vector
[platform/upstream/glib.git] / gio / gemblem.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2008 Clemens N. Buss <cebuzz@gmail.com>
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "gicon.h"
24 #include "gemblem.h"
25 #include "glibintl.h"
26 #include "gioenums.h"
27 #include "gioenumtypes.h"
28 #include "gioerror.h"
29 #include <stdlib.h>
30 #include <string.h>
31
32
33 /**
34  * GEmblem:
35  *
36  * `GEmblem` is an implementation of [iface@Gio.Icon] that supports
37  * having an emblem, which is an icon with additional properties.
38  * It can than be added to a [class@Gio.EmblemedIcon].
39  *
40  * Currently, only metainformation about the emblem's origin is
41  * supported. More may be added in the future.
42  */
43
44 static void g_emblem_iface_init (GIconIface *iface);
45
46 struct _GEmblem
47 {
48   GObject parent_instance;
49
50   GIcon *icon;
51   GEmblemOrigin origin;
52 };
53
54 struct _GEmblemClass
55 {
56   GObjectClass parent_class;
57 };
58
59 enum
60 {
61   PROP_0_GEMBLEM,
62   PROP_ICON,
63   PROP_ORIGIN
64 };
65
66 G_DEFINE_TYPE_WITH_CODE (GEmblem, g_emblem, G_TYPE_OBJECT,
67                          G_IMPLEMENT_INTERFACE (G_TYPE_ICON, g_emblem_iface_init))
68
69 static void
70 g_emblem_get_property (GObject    *object,
71                        guint       prop_id,
72                        GValue     *value,
73                        GParamSpec *pspec)
74 {
75   GEmblem *emblem = G_EMBLEM (object);
76
77   switch (prop_id)
78     {
79       case PROP_ICON:
80         g_value_set_object (value, emblem->icon);
81         break;
82
83       case PROP_ORIGIN:
84         g_value_set_enum (value, emblem->origin);
85         break;
86
87       default:
88         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
89         break;
90   }
91 }
92
93 static void
94 g_emblem_set_property (GObject      *object,
95                        guint         prop_id,
96                        const GValue *value,
97                        GParamSpec   *pspec)
98 {
99   GEmblem *emblem = G_EMBLEM (object);
100
101   switch (prop_id)
102     {
103       case PROP_ICON:
104         emblem->icon = g_value_dup_object (value);
105         break;
106
107       case PROP_ORIGIN:
108         emblem->origin = g_value_get_enum (value);
109         break;
110
111       default:
112         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
113         break;
114     }
115 }
116
117 static void
118 g_emblem_finalize (GObject *object)
119 {
120   GEmblem *emblem = G_EMBLEM (object);
121
122   if (emblem->icon)
123     g_object_unref (emblem->icon);
124
125   (*G_OBJECT_CLASS (g_emblem_parent_class)->finalize) (object);
126 }
127
128 static void
129 g_emblem_class_init (GEmblemClass *klass)
130 {
131   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
132
133   gobject_class->finalize = g_emblem_finalize;
134   gobject_class->set_property = g_emblem_set_property;
135   gobject_class->get_property = g_emblem_get_property;
136
137   /**
138    * GEmblem:origin:
139    *
140    * The origin the emblem is derived from.
141    *
142    * Since: 2.18
143    */
144   g_object_class_install_property (gobject_class,
145                                    PROP_ORIGIN,
146                                    g_param_spec_enum ("origin", NULL, NULL,
147                                                       G_TYPE_EMBLEM_ORIGIN,
148                                                       G_EMBLEM_ORIGIN_UNKNOWN,
149                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150
151   /**
152    * GEmblem:icon:
153    *
154    * The actual icon of the emblem.
155    *
156    * Since: 2.18
157    */
158   g_object_class_install_property (gobject_class,
159                                    PROP_ICON,
160                                    g_param_spec_object ("icon", NULL, NULL,
161                                                       G_TYPE_OBJECT,
162                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
163
164 }
165
166 static void
167 g_emblem_init (GEmblem *emblem)
168 {
169 }
170
171 /**
172  * g_emblem_new:
173  * @icon: a GIcon containing the icon.
174  *
175  * Creates a new emblem for @icon.
176  *
177  * Returns: a new #GEmblem.
178  *
179  * Since: 2.18
180  */
181 GEmblem *
182 g_emblem_new (GIcon *icon)
183 {
184   GEmblem* emblem;
185
186   g_return_val_if_fail (icon != NULL, NULL);
187   g_return_val_if_fail (G_IS_ICON (icon), NULL);
188   g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL);
189
190   emblem = g_object_new (G_TYPE_EMBLEM, NULL);
191   emblem->icon = g_object_ref (icon);
192   emblem->origin = G_EMBLEM_ORIGIN_UNKNOWN;
193
194   return emblem;
195 }
196
197 /**
198  * g_emblem_new_with_origin:
199  * @icon: a GIcon containing the icon.
200  * @origin: a GEmblemOrigin enum defining the emblem's origin
201  *
202  * Creates a new emblem for @icon.
203  *
204  * Returns: a new #GEmblem.
205  *
206  * Since: 2.18
207  */
208 GEmblem *
209 g_emblem_new_with_origin (GIcon         *icon,
210                           GEmblemOrigin  origin)
211 {
212   GEmblem* emblem;
213
214   g_return_val_if_fail (icon != NULL, NULL);
215   g_return_val_if_fail (G_IS_ICON (icon), NULL);
216   g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL);
217
218   emblem = g_object_new (G_TYPE_EMBLEM, NULL);
219   emblem->icon = g_object_ref (icon);
220   emblem->origin = origin;
221
222   return emblem;
223 }
224
225 /**
226  * g_emblem_get_icon:
227  * @emblem: a #GEmblem from which the icon should be extracted.
228  *
229  * Gives back the icon from @emblem.
230  *
231  * Returns: (transfer none): a #GIcon. The returned object belongs to
232  *          the emblem and should not be modified or freed.
233  *
234  * Since: 2.18
235  */
236 GIcon *
237 g_emblem_get_icon (GEmblem *emblem)
238 {
239   g_return_val_if_fail (G_IS_EMBLEM (emblem), NULL);
240
241   return emblem->icon;
242 }
243
244
245 /**
246  * g_emblem_get_origin:
247  * @emblem: a #GEmblem
248  *
249  * Gets the origin of the emblem.
250  *
251  * Returns: (transfer none): the origin of the emblem
252  *
253  * Since: 2.18
254  */
255 GEmblemOrigin
256 g_emblem_get_origin (GEmblem *emblem)
257 {
258   g_return_val_if_fail (G_IS_EMBLEM (emblem), G_EMBLEM_ORIGIN_UNKNOWN);
259
260   return emblem->origin;
261 }
262
263 static guint
264 g_emblem_hash (GIcon *icon)
265 {
266   GEmblem *emblem = G_EMBLEM (icon);
267   guint hash;
268
269   hash  = g_icon_hash (g_emblem_get_icon (emblem));
270   hash ^= emblem->origin;
271
272   return hash;
273 }
274
275 static gboolean
276 g_emblem_equal (GIcon *icon1,
277                 GIcon *icon2)
278 {
279   GEmblem *emblem1 = G_EMBLEM (icon1);
280   GEmblem *emblem2 = G_EMBLEM (icon2);
281
282   return emblem1->origin == emblem2->origin &&
283          g_icon_equal (emblem1->icon, emblem2->icon);
284 }
285
286 static gboolean
287 g_emblem_to_tokens (GIcon *icon,
288                     GPtrArray *tokens,
289                     gint  *out_version)
290 {
291   GEmblem *emblem = G_EMBLEM (icon);
292   char *s;
293
294   /* GEmblem are encoded as
295    *
296    * <origin> <icon>
297    */
298
299   g_return_val_if_fail (out_version != NULL, FALSE);
300
301   *out_version = 0;
302
303   s = g_icon_to_string (emblem->icon);
304   if (s == NULL)
305     return FALSE;
306
307   g_ptr_array_add (tokens, s);
308
309   s = g_strdup_printf ("%d", emblem->origin);
310   g_ptr_array_add (tokens, s);
311
312   return TRUE;
313 }
314
315 static GIcon *
316 g_emblem_from_tokens (gchar  **tokens,
317                       gint     num_tokens,
318                       gint     version,
319                       GError **error)
320 {
321   GEmblem *emblem;
322   GIcon *icon;
323   GEmblemOrigin origin;
324
325   emblem = NULL;
326
327   if (version != 0)
328     {
329       g_set_error (error,
330                    G_IO_ERROR,
331                    G_IO_ERROR_INVALID_ARGUMENT,
332                    _("Can’t handle version %d of GEmblem encoding"),
333                    version);
334       return NULL;
335     }
336
337   if (num_tokens != 2)
338     {
339       g_set_error (error,
340                    G_IO_ERROR,
341                    G_IO_ERROR_INVALID_ARGUMENT,
342                    _("Malformed number of tokens (%d) in GEmblem encoding"),
343                    num_tokens);
344       return NULL;
345     }
346
347   icon = g_icon_new_for_string (tokens[0], error);
348
349   if (icon == NULL)
350     return NULL;
351
352   origin = atoi (tokens[1]);
353
354   emblem = g_emblem_new_with_origin (icon, origin);
355   g_object_unref (icon);
356
357   return G_ICON (emblem);
358 }
359
360 static GVariant *
361 g_emblem_serialize (GIcon *icon)
362 {
363   GEmblem *emblem = G_EMBLEM (icon);
364   GVariant *icon_data;
365   GEnumValue *origin;
366   GVariant *result;
367
368   icon_data = g_icon_serialize (emblem->icon);
369   if (!icon_data)
370     return NULL;
371
372   origin = g_enum_get_value (g_type_class_peek (G_TYPE_EMBLEM_ORIGIN), emblem->origin);
373   result = g_variant_new_parsed ("('emblem', <(%v, {'origin': <%s>})>)",
374                                  icon_data, origin ? origin->value_nick : "unknown");
375   g_variant_unref (icon_data);
376
377   return result;
378 }
379
380 static void
381 g_emblem_iface_init (GIconIface *iface)
382 {
383   iface->hash  = g_emblem_hash;
384   iface->equal = g_emblem_equal;
385   iface->to_tokens = g_emblem_to_tokens;
386   iface->from_tokens = g_emblem_from_tokens;
387   iface->serialize = g_emblem_serialize;
388 }